Skip to content

ci: the docs current-state guard runs on every PR from one shared script - #391

Merged
yw0nam merged 6 commits into
mainfrom
ci/docs-guard
Oct 21, 2026
Merged

yw0nam merged 6 commits into
mainfrom
ci/docs-guard

Conversation

@yw0nam

@yw0nam yw0nam commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Summary

The docs current-state rule is enforced in CI, not only in the Claude Code edit hook. Edits made through a shell command, and every edit by an external agent (other CLIs do not run Claude Code hooks), now meet the same check on the PR.

scripts/ci/docs-guard.sh          one home of the skip line and the vocabulary
  ├─ text mode   (stdin)          ← .claude/hooks/posttool-edit-guard.sh (blocks on exit 1, fails open otherwise)
  └─ diff mode   (<base-ref>)     ← CI job "docs-guard (docs are current-state)", pull_request only
        git -c core.quotePath=false diff -U0 -M <merge-base> HEAD -- '*.md'  (node_modules, .github, .claude, CHANGELOG.md excluded at any depth)
        awk: per-file header/hunk state, added lines only, matched on the line text
        → "<path>: <line>" × first 5, exit 1 │ "docs-guard OK.", exit 0 │ exit 2 on a bad ref

The hook's block JSON and reason are unchanged. Owner decision: a hit fails the PR.

Review notes (GPT spec review ×2, two-axis review, two fix rounds, a final two-axis check):

  • Fixed in review: the parser now resets per file (a deleted first file had hidden every later hit), paths print without git's b/ and without the trailing TAB git adds to a path with a space, matching uses the line text only (a flagged word in a path no longer flags clean lines), all added lines go through one awk pass (5,000 lines: 17 s before, about 16 ms now), rename detection stays on so a pure git mv of a doc passes.
  • Not changed: the exclusion list lives in the hook's case and in the script's pathspecs (two syntaxes); output stops at five hits; a correct current-state sentence that uses a flagged word is flagged when its line is touched, and the writer rephrases it (as with the hook).

Related issues

None.

Runtime evidence (required for ingest / retrieval / serving behavior)

Under both gawk and mawk (Ubuntu's default awk), in throwaway repos:

scenario result
pure git mv of a doc containing "no longer" exit 0, docs-guard OK.
rename plus one new flagged line exit 1, docs/c.md: It no longer waits.
deleted first file, then a new file with a flagged line exit 1, docs/z.md: Cache no longer expires.
clean line in docs/no longer/x.md exit 0
flagged line in docs/a b.md exit 1, docs/a b.md: It no longer retries. (no TAB)
Korean vocabulary in docs/한글.md exit 1, path unquoted; the skip line is skipped
unknown base ref exit 2

The hook's block output is byte-identical to main's hook for a hit and for clean content. bash scripts/ci/docs-guard.sh origin/main on this branch: docs-guard OK. This PR's own docs-guard job is the first CI run.

Verification

  • uv run pytest passes — tests/test_docs_guard.py + tests/test_git_guard.py: 30 passed
  • uv run ruff format --check . and uv run ruff check . pass
  • docker compose build mcp passes (Dockerfile / dependency changes) — N/A
  • Runtime evidence attached above, or N/A justified

Checklist (core principles)

  • Selective storage — notes stay distilled; verbatim text lives only in doc_rows and the turns lane
  • Source-specific logic stays out of the source-agnostic core (ingest pipeline, retrieval, serving)
  • No hardcoded endpoints/models — configuration lives in .env
  • New/changed behavior ships a test in this PR (or skip-tests label justified)

@yw0nam
yw0nam merged commit da426c7 into main Oct 21, 2026
5 checks passed
@yw0nam
yw0nam deleted the ci/docs-guard branch October 21, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant