aboutsummaryrefslogtreecommitdiff
path: root/hooks/destructive-bash-confirm.py
Commit message (Collapse)AuthorAgeFilesLines
* feat(hooks): scan file-backed messages and harden rm parsingCraig Jennings2026-05-221-9/+77
| | | | | | | | | | Two audit gaps in the confirmation hooks, plus the test harness they were missing. The git-commit and gh-pr-create hooks scanned for AI attribution but only saw inline messages. A commit made with -F/--file or a PR made with --body-file slipped through, since the hook stored a placeholder instead of the file's text, and the publish flow uses -F constantly. A new read_referenced_file helper in _common.py reads the referenced local file (missing, oversized, or non-UTF-8 returns None, which means "couldn't inspect" and never "clean"), so attribution scanning now sees the real committed and posted text. An unreadable file falls through to the existing ask-anyway path. destructive-bash-confirm.py parsed rm flags by splitting on whitespace, which mangled quoted paths and missed flag variants. detect_rm_rf now tokenizes with shlex, so quoted or spaced paths and combined, separate, or reordered flags all parse. It fails toward asking (a sentinel that still fires the modal) on unbalanced quotes, or when a forced recursive rm sits alongside a pipeline, compound command, substitution, or redirect, since target attribution isn't trustworthy there. The supported and unsupported shell constructs are documented in the docstrings. These hooks had no tests and weren't in make test. Added a pytest harness under hooks/tests (an importlib-by-path loader, since the hook filenames are hyphenated) with 54 tests across the three hooks and the shared helper, and wired hooks/tests into make test. Full suite green.
* feat(hooks+skills): destructive-bash confirm + architecture suite + ↵Craig Jennings2026-04-191-0/+174
problem-solving routing Three improvements bundled together: 1. New hook — `destructive-bash-confirm.py` (PreToolUse/Bash): Gates `git push --force`, `git reset --hard`, `git clean -f`, `git branch -D`, and `rm -rf` behind a confirmation modal with the command, local context (branch, uncommitted counts, targeted paths), and a severity banner. Elevates severity when force-pushing protected branches (main/master/develop/release/prod) or when rm -rf targets root, home, or wildcard paths. Reuses _common.py. 2. Architecture suite rename — the "Part of the arch-* suite" footer in arch-design, arch-decide, arch-document, arch-evaluate descriptions now reads "Part of the architecture suite (arch-design / arch-decide / arch-document / arch-evaluate + c4-analyze / c4-diagram for notation-specific diagramming)." Matching footers added to c4-analyze and c4-diagram. c4-* keep their framework-specific prefix (C4 is a notation, arch-* is framework-agnostic workflow) but are now discoverable as suite members. 3. Problem-solving cluster routing — added YAML frontmatter with descriptions (including "Do NOT use for X (use Y)" clauses) to debug/SKILL.md and fix-issue/SKILL.md. Previously both had no frontmatter at all, which broke skill-router discovery. The four cluster members (debug, fix-issue, root-cause-trace, five-whys) now route unambiguously by description alone.