style(no-slop): remove every em-dash + banned words across all modules + capstone
Apply the no-ai-slop standard (now binding in AGENTS.md): the em-dash character is banned outright (restructured, not blind-replaced), plus the banned word/phrase list (delve, leverage, robust, seamless, truly, unlock, etc.). 0 em-dashes remain in modules + capstone; the only "robust" left is the planted M10 ai-change.patch trap. Module H1 titles use a colon separator. All deliberate teaching devices preserved; labs compile/parse (py/sh/yaml/json); no junk. AGENTS.md updated with the hard no-slop rules. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ci-security.yml — the security gate as a CI step (Module 15).
|
||||
# ci-security.yml: the security gate as a CI step (Module 15).
|
||||
#
|
||||
# This is a PROVIDER-NEUTRAL snippet, not a drop-in file. The YAML below uses the widely-shared
|
||||
# "workflow / job / steps" shape that most hosted and self-hosted CI systems understand (the exact
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v7
|
||||
# Secret scanning cares about history. If your tool scans commits (not just the working
|
||||
# tree), fetch full history here — e.g. set `with: { fetch-depth: 0 }`.
|
||||
# tree), fetch full history here; e.g. set `with: { fetch-depth: 0 }`.
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Cloud-sync config for tasks-app — a realistic snapshot of what an AI hands you.
|
||||
"""Cloud-sync config for tasks-app: a realistic snapshot of what an AI hands you.
|
||||
|
||||
Asked to "sync tasks to a cloud service," a model will produce something like this: it works, it
|
||||
reads naturally, it passes lint and tests... and it carries two planted flaws: a live credential
|
||||
@@ -24,15 +24,15 @@ def sync_headers() -> dict:
|
||||
|
||||
# --- The problem the SAST scanner should flag (Gate 3) -----------------------------------------
|
||||
# AI-classic: "sign" the request body with a quick hash. MD5 is broken for anything
|
||||
# security-relevant — a textbook weak-crypto idiom. A secret scanner won't catch this (it's not a
|
||||
# security-relevant; a textbook weak-crypto idiom. A secret scanner won't catch this (it's not a
|
||||
# secret); a SAST tool like bandit will (it's insecure code you wrote). DO NOT imitate.
|
||||
def sign_payload(body: str) -> str:
|
||||
return hashlib.md5(body.encode()).hexdigest()
|
||||
|
||||
|
||||
# --- The fix (Part C) --------------------------------------------------------------------------
|
||||
# Read the secret from the environment instead of committing it. Proper secret management — env
|
||||
# files, secret stores, per-environment config — is Module 17. This is just enough to make the
|
||||
# Read the secret from the environment instead of committing it. Proper secret management (env
|
||||
# files, secret stores, per-environment config) is Module 17. This is just enough to make the
|
||||
# scanner go quiet honestly.
|
||||
#
|
||||
# import os
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Dependencies an AI "suggested" for the tasks-app cloud-sync feature.
|
||||
#
|
||||
# This file is deliberately booby-trapped with the three things AI gets wrong about dependencies.
|
||||
# Read it before you run anything — every line looks plausible, which is the whole problem.
|
||||
# Read it before you run anything; every line looks plausible, which is the whole problem.
|
||||
#
|
||||
# Work through it in Part B of the lab:
|
||||
# 1) `pip-audit -r requirements.txt` will FAIL TO RESOLVE because of the bad names below.
|
||||
@@ -14,11 +14,11 @@
|
||||
requests==2.19.1
|
||||
|
||||
# (2) TYPOSQUAT of a real package ("requests"). One transposed letter. Does not exist on the
|
||||
# public index today — the resolver will reject it. The danger isn't the 404; it's "fixing"
|
||||
# public index today; the resolver will reject it. The danger isn't the 404; it's "fixing"
|
||||
# it by guessing instead of verifying what was actually meant.
|
||||
reqeusts==2.31.0
|
||||
|
||||
# (3) HALLUCINATION — a plausible-but-invented name the model produced from thin air. This is the
|
||||
# (3) HALLUCINATION: a plausible-but-invented name the model produced from thin air. This is the
|
||||
# slopsquatting target: register this name with malware and the next person to `pip install`
|
||||
# gets owned. Confirm it does not resolve; never add it without verifying the real project.
|
||||
task-cloud-sync-client==1.4.2
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# security-scan.sh — the security gate for tasks-app (Module 15).
|
||||
# security-scan.sh: the security gate for tasks-app (Module 15).
|
||||
#
|
||||
# Runs two scanners and exits non-zero if EITHER finds something. That non-zero exit is what turns
|
||||
# a CI run red (Module 14). One script, two homes: run it by hand for fast local feedback, and call
|
||||
# it from the pipeline so the same definition of "a finding" enforces the merge.
|
||||
#
|
||||
# These two tools (pip-audit, detect-secrets) are concrete examples of their categories — SCA and
|
||||
# These two tools (pip-audit, detect-secrets) are concrete examples of their categories, SCA and
|
||||
# secret scanning. Swap in any equivalent; keep the contract the same: scan, print, fail on findings.
|
||||
#
|
||||
# Usage: ./security-scan.sh
|
||||
@@ -30,7 +30,7 @@ if [ -f requirements.txt ]; then
|
||||
status=1
|
||||
fi
|
||||
else
|
||||
echo "(no requirements.txt found — skipping SCA)"
|
||||
echo "(no requirements.txt found; skipping SCA)"
|
||||
fi
|
||||
|
||||
echo
|
||||
@@ -38,7 +38,7 @@ echo "=== Gate 2: secret scan (detect-secrets) ==="
|
||||
# detect-secrets prints a JSON report of any secrets it finds. NOTE: with no path it scans the files
|
||||
# git TRACKS, so stage the starter files (`git add`) before running this, or an untracked file is
|
||||
# invisible to the gate. We parse the JSON with `python3` (no jq dependency) and fail CLOSED: the
|
||||
# parser returns 0=secrets found, 1=clean, anything else=couldn't tell — and "couldn't tell" must
|
||||
# parser returns 0=secrets found, 1=clean, anything else=couldn't tell; "couldn't tell" must
|
||||
# count as a failure, never a silent pass.
|
||||
report="$(detect-secrets scan)"
|
||||
printf '%s' "$report" | python3 -c 'import sys, json
|
||||
|
||||
Reference in New Issue
Block a user