From ebce2474c815ec3a6f3a8cda8f6a259ae75bb062 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 13 Nov 2026 10:46:52 +0000 Subject: [PATCH] feat(hooks): block Stop and push on unreviewed prose scripts/prose-check.sh hashes the docs and code comments the branch adds against origin/main. The Stop hook and pre-push exit 2 until doc-review has run and `--mark` records that hash. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019XphpcWhwJWodgw4PpUSKK --- .claude/settings.json | 4 +++ .claude/skills/doc-review/SKILL.md | 2 +- AGENTS.md | 1 + lefthook.yml | 2 ++ scripts/prose-check.sh | 44 ++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100755 scripts/prose-check.sh diff --git a/.claude/settings.json b/.claude/settings.json index e3620ebc..566b31db 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -6,6 +6,10 @@ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.agents/hooks/lint-and-test.sh" + }, + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/scripts/prose-check.sh" } ] } diff --git a/.claude/skills/doc-review/SKILL.md b/.claude/skills/doc-review/SKILL.md index 41904f3c..5fbead82 100644 --- a/.claude/skills/doc-review/SKILL.md +++ b/.claude/skills/doc-review/SKILL.md @@ -45,4 +45,4 @@ Code comments and messages: List findings as `file:line, check number, proposed rewrite`, then apply them. Run `bun run lint` and, if `plugin/` changed, `bun run test:hook`. Finish by checking the "Definition of done" table in `AGENTS.md` for files -the change affects but does not touch. +the change affects but does not touch, then run `scripts/prose-check.sh --mark`. diff --git a/AGENTS.md b/AGENTS.md index 3b208573..a2146c4c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -108,3 +108,4 @@ For most development only the main unit tests need re-running regularly. ## Hooks Address issues related to change you made if a Stop hook reports them. +The Stop hook and pre-push block while the branch adds docs or code comments that `doc-review` has not seen (`scripts/prose-check.sh`). diff --git a/lefthook.yml b/lefthook.yml index 0d1caee9..1d971e00 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -29,3 +29,5 @@ pre-push: run: bash scripts/sync-plugin-version.sh --check pushed-tree: run: bash scripts/git-hooks/check-pushed-tree.sh + prose-check: + run: bash scripts/prose-check.sh diff --git a/scripts/prose-check.sh b/scripts/prose-check.sh new file mode 100755 index 00000000..d13b109b --- /dev/null +++ b/scripts/prose-check.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Exits 2 while the branch adds docs or code comments that no doc-review has seen. +# --mark records the current additions as reviewed. +set -uo pipefail + +root="$(git rev-parse --show-toplevel)" || exit 0 +cd "$root" || exit 0 +base="$(git merge-base origin/main HEAD 2>/dev/null)" || exit 0 +stamp="$(git rev-parse --git-path prose-reviewed)" + +code='*.ts *.tsx *.js *.mjs *.cjs *.sh *.yml *.yaml' +generated=':!plugin/hooks/projection.js :!plugin/types/index.d.ts :!schemas/generated' + +# Prints "filekindline" for each added prose line, untracked files included. +added() { + { + git diff -U0 --no-color "$base" -- '*.md' $code $generated + git ls-files -z --others --exclude-standard -- '*.md' $code $generated | + xargs -0 -r -n1 git diff -U0 --no-color --no-index /dev/null + } | awk ' + /^\+\+\+ b\// { file = substr($0, 7); doc = file ~ /\.md$/; next } + /^\+/ { + line = substr($0, 2) + if (doc) { if (line ~ /[^[:space:]]/) print file "\tdoc\t" line } + else if (line ~ /^[[:space:]]*(\/\/|\/\*|\*|#)/ && line !~ /^#!/) print file "\tcomment\t" line + }' +} + +lines="$(added)" +[ -z "$lines" ] && exit 0 +hash="$(printf '%s' "$lines" | git hash-object --stdin)" + +if [ "${1:-}" = "--mark" ]; then + echo "$hash" >"$stamp" + exit 0 +fi +[ "$(cat "$stamp" 2>/dev/null)" = "$hash" ] && exit 0 + +{ + echo "Prose added since the last doc-review:" + printf '%s\n' "$lines" | awk -F'\t' '{ n[$1 " (" $2 ")"]++ } END { for (f in n) printf " %4d %s\n", n[f], f }' | sort -rn + echo "Run the doc-review skill on this diff, apply its cuts, then run scripts/prose-check.sh --mark." +} >&2 +exit 2