Doc guardrails
Linters · hooks · rules · CI
This page is the runtime inventory of the doc-guardrail layer — the automation that prevents the three recurring documentation bug-classes a full CodeCanyon-playbook audit surfaced (2026-06-12). For how to author, see Site Authoring Capabilities.
The three bug-classes → the guard
Section titled “The three bug-classes → the guard”| Bug-class (real examples) | Guard |
|---|---|
Fragile shell in prose — commented-line greps, ** globstar off, missing --no-ansi, non-idempotent >>/crontab, indented heredoc EOF inside ssh "…", ssh -T exit-gating, inline -pPASS | lint-mdx-shell.mjs |
Doc ↔ reality drift — hardcoded git SHAs / php8.x copied as a fixed truth / VERSION="x.y.z" replaced with a real vendor number, security-header count 5-vs-6, grade A vs A+ | check-doc-drift.mjs |
| ”Done” claimed without building | verify-before-done hook + CI gate |
Scripts (app/scripts/)
Section titled “Scripts (app/scripts/)”| Script | What it flags | npm |
|---|---|---|
lint-mdx-shell.mjs | Extracts fenced bash/sh blocks; flags the footguns above (errors = inline secrets / placeholder secrets; warnings = the rest). Runs actionlint on yaml GitHub-Actions blocks. --shellcheck adds a syntax pass (noisy on doc placeholders — opt-in). | npm run lint:mdx |
check-doc-drift.mjs | Hardcoded SHAs/versions + cross-page contradictions (header count, grade word). | npm run lint:drift |
| both | — | npm run doc:lint |
Both default to exit-1 on error (CI) and take --warn to stay advisory (hooks). They take file args or default to the whole src/content/docs corpus.
Agent hooks (.agents/scripts/, mirrored to .claude / .cursor / .codex)
Section titled “Agent hooks (.agents/scripts/, mirrored to .claude / .cursor / .codex)”| Hook | Event | Behavior |
|---|---|---|
guard-git-revert.sh | PreToolUse (Bash) | Blocks git checkout -- / restore / reset --hard / stash / clean — these discard work git never stored, and a parallel agent or Malek may have authored it. Override per-command: ZAJ_ALLOW_REVERT=1. |
lint-mdx-on-edit.sh | PostToolUse (Write/Edit) | Advisory — runs the linters on the edited .mdx, prints findings, never blocks. |
verify-before-done.sh | Stop / SubagentStop | Nudges npm run build + npm run doc:lint when uncommitted .mdx has no fresh build (marker: app/.zaj/verify/last-build, written by postbuild). Advisory; ZAJ_VERIFY_STRICT=1 hard-blocks. |
Rules (.claude/rules/)
Section titled “Rules (.claude/rules/)”05-mdx-shell-blocks · 06-no-hardcoded-reality · 07-single-source-of-truth · 08-docs-secrets-and-destructive · 09-verify-before-done (and 04-no-clobber-parallel-edits — never revert another session’s work).
CI (.github/workflows/)
Section titled “CI (.github/workflows/)”doc-checks.yml(PR gate) —npm run build+lint:mdx+lint:driftrequired; step-contract advisory. Make it blocking via branch-protection required checks.link-check.yml(weekly + manual) —lycheefor external link rot (internal links already covered at build).
For authors / agents
Section titled “For authors / agents”Run /doc-lint [scope] or npm run doc:lint before declaring a doc done. The doc-build-verifier agent runs the build and the lint pass. Fix errors (CI-blocking); warnings are advisory.