[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval. [BLOCKING] Before each step or sub-skill call, update task tracking: set
in_progresswhen step starts, setcompletedwhen step ends. [BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason. [BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.
Quick Summary
Goal: Detect impacted docs from code changes and orchestrate updates across all doc types so every code/spec/test change leaves documentation in sync — impacted project-reference docs, project-config.json sections, Feature Specs, §8 TCs, test-code links, and derived indexes all reflect the shipped behavior, with zero drift left silent.
Summary:
- This skill is a ROUTER, not an author — start with Phase 0 triage (git diff → categorize → dedup modules → check existing docs) and delegate each doc type to its owner (
/spec,/spec [mode=tests],/spec [mode=sync],/spec-index,/tech-specfor derived technical views); NEVER write §8,docs/specs/, or derived technical spec content directly. — why: dual authorship diverges spec from index/view. - Main steps (each impact-gated; skipped phase → mark
completedwith reason): Phase 0 triage (git diff → categorize → dedup modules → record existing-doc state) → Phase 1 project context sync (impact-map → PARALLEL verify of the impacteddocs/project-reference/**docs +docs/project-config.jsonsections +README.md) → Phase 2/spec(§1–§7 Feature Spec; doc-first BLOCK when feature behavior changed but no Spec exists) → Phase 2.5/spec-index(derived bucket INDEX/ERD refresh, optional) → Phase 2.6/tech-spec(derived technical view refresh/audit, optional when technical tree is affected) → Phase 3/spec [mode=tests](§8 TCs) → Phase 4/spec [mode=sync](§8 ↔ test code) → Phase 5 summary report → final review (#8 runs the Step 2.4 code↔spec sync-verify). - Create ALL 8 tasks via
TaskCreatebefore touching any file; run the fixed phase order0 → 1 → 2 → 2.5/2.6 → 3 → 4 → 5 → final review— fast-exit is a decision, never a silent omission. - The final pass (Step 2.4) is the workflow's last gate: per touched module verify shipped code against §3 ACs, §4 BRs, §8 TCs — a removed/weakened [HARD] BR is a code-vs-spec contradiction that BLOCKS completion.
- Output is tech-agnostic prose (no framework/product names outside evidence fields) and traceability-first (update
FR-/BR-/OP-/TC-logical IDs before prose); ALWAYS write the Phase 5 summary report as the audit trail.
Orchestration Model:
git diff → Triage → Phase 1: Project Context Sync (PARALLEL, impact-scoped)
│ ├─ impacted docs/project-reference/** — verify → patch → (escalate to /scan --target=X)
│ ├─ impacted docs/project-config.json sections — verify → merge → validate
│ └─ README.md / project docs (docs-manager)
→ Phase 2: /spec (business feature docs)
→ Phase 2.5: /spec-index (derived index/ERD refresh) [optional]
→ Phase 2.6: /tech-spec (derived technical view refresh/audit) [optional]
→ Phase 3: /spec [mode=tests] (§8 test specifications)
→ Phase 4: /spec [mode=sync] (§8 ↔ test code sync)
→ Phase 5: Summary Report
Key Rules:
- Router only — NEVER duplicate sub-skill logic or write Section 8 /
docs/specs/content - [BLOCKING] Freshness is impact-scoped, never assumed. Phase 1 verifies only the
docs/project-reference/**docs anddocs/project-config.jsonsections the diff can actually rot (routed bynode .claude/scripts/doc-impact-map.cjs), and reports a per-doc verdictFRESH | PATCHED | RESCAN REQUIRED | UNVERIFIED. A doc nobody checked is UNVERIFIED — NEVER FRESH. — why: these docs are injected into every downstream AI context, so a silent stale line teaches every later agent a codebase that no longer exists. - [BLOCKING] An impact-scoped verify NEVER writes
<!-- Last scanned: -->. Only a full/scan --target=Xmay move that stamp; the narrow pass writes<!-- Last verified: ... -->instead — and only in a doc that already carries aLast scannedstamp (Step 1.6). — why:Last scanneddrives the 60-day full-rescan gate (.claude/hooks/lib/session-init-helpers.cjs:769); resetting it from a partial check would buy speed by disabling the very net that catches whole-doc rot. - **[BLOCKING] A
PATCHEDdocs/project-reference/**doc MUST run/prompt-enhance <doc>before its verdict is final** (Step 1.3) — keeps the doc as concise as possible while staying valuable enough for AI; skip only for a stamp/count-only edit. - Phase 1/docs-manager MUST NOT own any
docs/specs/**, test-spec, spec-index/ERD, or derived technical-view path. - Every excluded artifact is explicitly reserved to its child skill (
/spec,/spec-index, or/tech-spec) so one canonical writer owns it. - Exclude
docs/specs/**and generated technical views from every docs-manager brief and write set. - Each phase checks whether needed before invoking — skip phases with no impact
- Step-to-skill order is fixed — run phases sequentially, never out of order
- ALWAYS report what was checked, even if nothing needed updating
- Pass triage context (changed files, detected modules, impacted sections) to each sub-skill via
$ARGUMENTS - MUST ATTENTION dedup module list — backend + frontend changes for same module = ONE entry
- MUST ATTENTION track step state live:
in_progress-> execute ->completed(orcompletedwith skip reason) - For
.claudeskills/hooks/workflows/sync tooling changes, flag generated mirror sync status (npm run codex:synccompleted or explicit N/A).docs-updateroutes and reports this check; it does not edit generated mirrors directly. - [BLOCKING] Tech-agnostic output: when updating spec/specs/README/INDEX, do NOT introduce framework/product/language/design-pattern names into prose or headings — preserve the evidence-field exception (
**Evidence**,CoveredBy, legacyIntegrationTest,[Source:], frontmatter, Mermaid). Authority:docs/project-reference/spec-principles.md§3. - [BLOCKING] M3 Traceability Update: See
.claude/skills/shared/sdd-artifact-contract.md→ "AI-SDD Mandates (M1-M7)" for BLOCKING criteria. When syncing docs after code changes, update the logical-ID mappings (FR-/BR-/OP-/TC-) FIRST, then the prose. The[Source: namespace/service/id]abstract-anchor evidence is re-resolved ONLY if the logical artifact was renamed/split — a file move or stack change does NOT change the anchor (physical coords live only in the provenance sidecar) — and the logical-ID spine stays stable across the change — never drop or renumber a logical ID just because the code moved. Keep all synced prose M1/M2-clean.
Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence >80%.
Mandatory Task Creation (ZERO TOLERANCE)
[BLOCKING] Create ALL 8 tasks via
TaskCreateBEFORE touching any file. NEVER consolidate, rename, omit. Conditional tasks skipped: markcompletedimmediately with reason — NEVER silently omit.
| # | Task Subject | Conditional? |
|---|---|---|
| 1 | [docs-update] Phase 0 — Triage: collect git diff, categorize files, detect modules, check existing docs |
No — always first |
| 2 | [docs-update] Phase 1 — Project context sync: impact-map → PARALLEL verify of impacted docs/project-reference/** + docs/project-config.json sections + README/project docs |
No — always, unless Step 0.3 declared a TRUE fast exit (empty impact map). Runs even when Phases 2-4 are all skipped |
| 3 | [docs-update] Phase 2 — Invoke /spec: update business feature docs |
Yes — service/frontend files changed AND module has existing feature docs |
| 4 | [docs-update] Phase 2.5/2.6 — Refresh derived views via /spec-index and/or /tech-spec |
Yes — Feature Spec changed and bucket maintains INDEX/ERD, OR technical tree is affected |
| 5 | [docs-update] Phase 3 — Invoke /spec [mode=tests]: update/add §8 business test specifications |
Yes — business-visible functionality added OR existing business-visible behavior changed |
| 6 | [docs-update] Phase 4 — Invoke /spec [mode=sync]: sync §8 ↔ test code |
Yes — Phase 3 changed §8 TCs |
| 7 | [docs-update] Phase 5 — Write summary report to plans/reports/docs-update-{YYMMDD}-{HHMM}.md |
No — always |
| 8 | [docs-update] Final review — verify all impacted docs updated, no phases skipped without justification, AND run the Step 2.4 code↔spec sync-verify (AC/BR/TC drift) for every touched module |
No — always |
Execution rules:
- Mark each task
in_progresswhen starting,completedwhen done — one active at a time - Multiple modules → add one subtask per module for Phase 2/3 invocations
- Multiple impacted reference docs → add one subtask per doc (or per source-of-truth cluster) under Task 2, so each doc's verdict is tracked individually
- NEVER batch-complete — each sub-skill invocation tracked individually
- Phase 0 TRUE fast-exit (impact map empty) → mark tasks 2-8
completedwith reason "Skipped — impact map empty" - Phase 0 PARTIAL exit (docs/config impacted but no business behavior — e.g. harness, CI, or manifest-only changes) → run Task 2, mark tasks 3-6
completedwith reason "Skipped — no business behavior changed", still run tasks 7-8 - NEVER execute a phase step until matching task status is
in_progress - After each phase/skill call, write one-line evidence in task update (
what ran,what changed,why skipped) - If
TaskCreate/task updates unavailable, maintain equivalent 8-task plan tracker with same status transitions
Step-Skill Call Order (Do Not Reorder)
| Order | Task ID | Step / Phase | Skill Call | Tracking Rule |
| ----- | ------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| 1 | 1 | Phase 0: Triage | Inline triage logic in this skill | Set Task 1 in_progress before diff scan; set completed after module + impact map recorded |
| 2 | 2 | Phase 1: Project Context Sync | doc-impact-map.cjs + PARALLEL docs-manager sub-agents (one per impacted doc/cluster) + /scan --target=X or /project-config only on escalation | Set Task 2 in_progress before the impact map; completed only after EVERY routed doc and config section carries a verdict + evidence |
| 3 | 3 | Phase 2: Business Feature Docs | /spec | Set Task 3 in_progress before invocation; completed after output review |
| 4 | 4 | Phase 2.5/2.6: Derived View Refresh | /spec-index [mode=index] and/or /tech-spec [mode=generate | audit] | Set Task 4 in_progress before invocation; completed after derived outputs are refreshed or skipped with reason |
| 5 | 5 | Phase 3: §8 Test Specs | /spec [mode=tests] | Set Task 5 in_progress before invocation; completed after TC review |
| 6 | 6 | Phase 4: §8 ↔ Test Code Sync | /spec [mode=sync] | Set Task 6 in_progress before invocation; completed after sync validation |
| 7 | 7 | Phase 5: Summary Report | Inline report write | Set Task 7 in_progress before report write; completed after file path confirmed |
| 8 | 8 | Final Review | Inline verification gate | Set Task 8 in_progress before final audit; completed after all phases justified |
Enforcement: If a required step cannot run, STOP and ask user before adapting order. Never continue with untracked steps.
Phase 0: Triage — Detect Impacted Documentation
Step 0.1: Collect Changed Files
- Run
git diff --name-only HEAD(staged + unstaged changes) - No uncommitted changes →
git diff --name-only HEAD~1(last commit) - Still empty →
git diff --name-only origin/develop...HEAD(branch changes)
Step 0.2: Categorize Changes
| Changed File Pattern | Impact Category | Phases to Run |
|---|---|---|
{backend-source-paths}/** from docs/project-config.json |
spec + spec [mode=tests] + project-docs | 1 + 2 + 3 + 4 |
{frontend-apps-dir}/**, {frontend-libs-dir}/{domain-lib}/** |
spec + spec [mode=tests] + project-docs | 1 + 2 + 3 + 4 |
{legacy-frontend-dir}/**Client/** |
spec + spec [mode=tests] + project-docs | 1 + 2 + 3 + 4 |
{configured-framework-source-paths}/** |
project-docs only | 1 only |
docs/** (outside specRoots) |
project-docs only | 1 only |
.claude/**, .agents/**, .codex/**, CLAUDE.md, AGENTS.md |
harness inventory — skill/hook/agent/workflow counts, catalogs, module registry | 1 only |
Dependency manifests (package.json, *.csproj, pyproject.toml, lockfiles, …) |
project-docs — tech stack, versions, run commands | 1 only |
Infra/CI/env (docker-compose*, Dockerfile, .github/workflows/**, *.tf, appsettings*, .env*) |
project-docs — ports, deployment, env keys | 1 only |
{frontend-libs-dir}/{framework-core-lib}/**, {frontend-libs-dir}/{common-lib}/** |
project-docs only | 1 only |
This table classifies BUSINESS-doc impact (which of Phases 2-4 run). It is deliberately coarse. The precise
docs/project-reference/**+docs/project-config.jsonrouting is produced by the impact map in Step 1.1 — read it there, never guess it here.
Step 0.3: Fast Exit Check — decided by the impact map, never by path intuition
Run the impact map NOW (same command as Step 1.1) and read fastExit from its output:
node .claude/scripts/doc-impact-map.cjs --text
| Map result | Route |
|---|---|
fastExit: true — no impacted reference doc, no impacted config section, no unrouted file |
Report "No documentation impacted by current changes." → mark tasks 2-8 completed with reason "Skipped — impact map empty" → exit early |
| Impacted docs/config but NO business behavior changed (harness, CI, manifests, docs tree) | PARTIAL exit — run Phase 1 in full, mark Phases 2-4 completed with reason "Skipped — no business behavior changed", continue to Phase 5 |
| Any business/service/frontend code changed | Full sequence |
unrouted non-empty |
NOT a fast exit — classify each unrouted file by hand first (add it to the wave, or record why it carries no doc impact) |
[BLOCKING] A
.claude/**-only (or tooling-only) diff is NOT a full fast exit. Harness edits change the skill/hook/agent/workflow inventories thatCLAUDE.md,docs-index-reference.md, andproject-structure-reference.mdderive by globbing.claude/: the counts and catalogs go stale with zero feature impact, and NO other gate in this skill catches them — Phases 2-4 only look atdocs/specs/\*\*. — why: the cheapest way to ship stale docs is to classify the change as "tooling" and skip the only phase that would have noticed.
Step 0.4: Auto-Detect Affected Modules
Extract unique module names from changed paths. MUST ATTENTION dedup: unique() before passing to any sub-skill — backend + frontend same module = ONE entry. Prevents duplicate /spec invocations.
| Changed File Path Pattern | Detected Module |
|---|---|
{backend-module-path}/{Module}/** |
{Module} |
{frontend-apps-dir}/{app-name}/** |
{Module} (map app to module) |
{frontend-libs-dir}/{domain-lib}/{configured-feature-path}/** |
{Module} (map feature to module) |
{legacy-frontend-dir}/{Module}Client/** |
{Module} |
Build project-specific mapping from docs/project-config.json and project reference docs, not from hard-coded skill paths:
node -e "const cfg=require('./docs/project-config.json'); console.log(JSON.stringify({sourcePaths: cfg.codebaseHealth?.sourcePaths, contextGroups: cfg.contextGroups?.map(g => ({name:g.name,pathRegexes:g.pathRegexes})), specRoot: 'docs/specs/'}, null, 2))"
node -e "process.stdout.write('docs/specs/')"
Step 0.5: Check Existing Docs for Each Module
For each detected module:
- Check the matching bucket directory exists under
docs/specs/ - Check that the bucket contains
README.*.mdFeature Specs, or use the project reference doc's feature-doc layout - Check the matching bucket directory under
docs/specs/exists using project reference docs - Record:
hasFeatureSpec(§1–§7 present),hasTestSpecs(§8 present),hasDerivedIndex(bucket INDEX.md present)
Step 0.6: Declare the Doc-Update Wave
Detection is SEQ and comes FIRST — every assignment below is derived from the impacted-doc set, so nothing dispatches until Steps 0.1–0.5 have produced it. Once that set exists, updating N unrelated docs is embarrassingly parallel: one docs-manager sub-agent per doc or per doc cluster, all spawned in ONE message.
- Declare before dispatch —
Parallel plan: wave 1 = [docs-manager: {doc A}, docs-manager: {cluster B}, …] · SEQ = [Phase 0 triage, the Phase 2 → 2.5/2.6 → 3 → 4 spec chain, Phase 5 report] (reason). - STRICT one-writer-per-file. Every impacted doc path appears in EXACTLY ONE agent's brief, stated as that agent's owned file set. A doc owned by nobody is a silent miss; a doc owned by two agents is a lost-update race where the later write wins and the earlier finding vanishes.
- [HAZARD] Two docs that embed the same canonical or derived data MUST go to the SAME agent — never split across the wave. Counts, catalogs, module maps, INDEX rows, ERD entities, and any table copied out of a source of truth have to be regenerated by ONE writer from ONE reading of that source. Split across two agents they diverge inside a single commit — and the divergence survives review because each doc is internally consistent and only the pair is wrong. Cluster by SOURCE OF TRUTH, not by directory.
- Barrier before the spec chain. Phase 2 → 2.5/2.6 → 3 → 4 stays a FIXED SEQ chain:
/specoutput feeds the derived index, and §8 TCs feed[mode=sync]. Parallelism lives INSIDE a phase across independent modules — never across these phases. - Per-module fan-out is PAR only when the modules are disjoint. Two detected modules that map to ONE Feature Spec share a write target and stay a single task — the same reason Step 0.4 dedups the module list.
- Every member returns a summary +
Full report:path; YOU merge them into the Phase 5 report only after ALL members return, a skipped member counting as returned.
Phase 1: Project Context Sync — Reference Docs + project-config.json (PARALLEL, impact-scoped)
Why this phase exists.
docs/project-reference/**anddocs/project-config.jsonare injected into EVERY downstream AI context and route every skill in the framework. When code moves and they do not, the harness keeps teaching a codebase that no longer exists — and nothing else in this skill catches it, because Phases 2-4 only look atdocs/specs/**./scan-all+/project-configdo repair them, but they re-derive every doc from zero, which is why they run every 60 days instead of every change. This phase does the same job at diff scope: same no-stale guarantee, small enough to afford after every change.
When to run: ALWAYS, unless Step 0.3 declared a TRUE fast exit. Run it even when every one of Phases 2-4 is skipped.
Scope discipline: verify ONLY what the impact map routes; escalate to a full /scan --target=X when a surgical patch cannot make the doc true again. NEVER regenerate all docs, and NEVER hand-author a full reference doc here — scan owns authoring, this phase owns verification and surgical repair.
Step 1.1: Build the Doc-Impact Map (SEQ — everything below derives from it)
node .claude/scripts/doc-impact-map.cjs --json # machine-readable (drives the wave)
node .claude/scripts/doc-impact-map.cjs --text # human-readable (goes in the report)
node .claude/scripts/doc-impact-map.cjs --base=origin/main # branch-scope instead of working tree
The map routes each changed file to the docs and config sections it can rot, and returns per doc: doc, exists, lastScanned/ageDays, scanTarget (the full-rescan escalation), checks (which verifications apply), changedFiles/addedFiles/deletedFiles, and heuristicOnly. Routing is derived from docs/project-config.json (contextGroups, modules, testing, e2eTesting, styling, designSystem, specRoots) plus change-class rules — never from hardcoded project paths.
Handling the map's output — [BLOCKING] rules:
unroutedfiles are not proof of no impact — they are proof the router had no rule. Classify each by hand: add it to the wave, or record in the report why it carries no doc impact. NEVER let an unrouted file silently pass as fresh.- A
heuristicOnlydoc is a GUESS, not evidence. Verify it like any other, and downgrade to "not impacted" only with a stated reason. - Any doc whose
exists: falseis a MISSING doc, not a fresh one → route to/scan --target=<scanTarget>(or/docs-initwhen the whole set is absent). - If the script is unavailable (older checkout, non-Node host), derive the same map by hand from
docs/project-config.json— match changed paths againstcontextGroups[].pathRegexes→guideDoc/patternsDoc/stylingDoc/designSystemDoc,modules[].pathRegex→ project-structure +modules, test/e2e/styling paths → their docs, manifests → tech stack, infra/CI → ports & deployment,.claude/**→ inventory counts. Record that the map was manual.
Step 1.2: Declare the Verify Wave (PAR — one message, all members)
Parallel plan: wave 1 = [docs-manager: {doc A}, docs-manager: {cluster B}, docs-manager: project-config.json, …] · SEQ = [Step 1.1 impact map, the Phase 2 → 2.5/2.6 → 3 → 4 spec chain, Phase 5 report] (reason)
Wave-construction rules — the Step 0.6 hazards apply verbatim, plus:
- STRICT one-writer-per-file.
docs/project-config.jsonhas exactly ONE owning agent in the wave, always. Two agents merging JSON into the same file is a guaranteed lost update. - Cluster by SOURCE OF TRUTH, not by directory.
README.md+project-structure-reference.mdboth restate the module/directory map, andCLAUDE.md+docs-index-reference.md+project-structure-reference.mdall embed.claude/-derived counts — each such set goes to ONE agent so the numbers cannot diverge inside a single commit. - Every routed doc appears in exactly one brief. A doc owned by nobody is a silent miss.
- Every member returns its verdict table +
Full report:path; merge only after ALL members return.
Step 1.3: Per-Doc Verify Contract (what each wave member actually does)
Verify FIRST, patch NARROW. Run only the checks the map listed for that doc:
| Check | Question it answers | How to answer it | On failure |
|---|---|---|---|
claims |
Do the doc's cited paths/examples still exist? | node .claude/scripts/doc-impact-map.cjs claims <doc> (missing = dead, ambiguous = short-form that resolves by suffix), then grep each cited symbol at its cited file |
Repoint or delete a dead citation, repo-root an ambiguous one (a citation is evidence — never leave a dead one). The reference-doc-freshness test suite fails the build on any dead citation |
coverage |
Does every ADDED artifact of this doc's kind appear in it? | Diff the map's addedFiles against the doc's inventory/examples |
Add the missing row/example with file:line |
counts |
Do numeric claims match ground truth? | Re-derive by glob/grep (skills, hooks, agents, workflows, services, docs, tests) | Update the number — and the marker region if the count is generated |
conventions |
Did the diff introduce a pattern the doc does not describe, or violate one it does? | Read the diff against the doc's rules | New pattern → document it. Violation → report it, do NOT document it as a convention |
commands |
Do documented run/test commands still work? | Compare against manifests/scripts (package.json, test config, integrationTestVerify) |
Patch the command |
versions |
Do stated tech/framework versions match the manifests? | Read the manifest — never infer | Patch the version |
ports |
Do documented ports/endpoints match infra config? | Read compose/k8s/appsettings — never infer | Patch the port |
links / catalog |
Do cross-links and catalog rows resolve? | Existence-check each target | Fix or remove the row |
Verdict per doc (exactly one, evidence required):
| Verdict | Meaning | Required evidence |
|---|---|---|
FRESH |
Every applicable check ran and passed; no edit needed | Which checks ran + what was compared |
PATCHED |
Surgical edit applied, then /prompt-enhance <doc> run to keep it concise |
Sections touched + file:line evidence for each new claim + prompt-enhance run confirmation (or stated reason skipped) |
RESCAN REQUIRED |
Beyond surgical repair — a new subsystem/pattern family appeared, most of the impacted section's examples are dead, or the doc's structure no longer fits the code | The scanTarget to run (/scan --target=X), and whether it ran in this session or is queued |
UNVERIFIED |
Could not be checked (missing tooling, blocked read, budget) | Why, and what must run next |
[BLOCKING] Never fabricate freshness. "Looks fine", "probably unchanged", and "the diff was small" are not check results. A doc that was not verified is
UNVERIFIED, neverFRESH— a false FRESH is worse than no check, because it retires the suspicion that would have caught the drift later.
[BLOCKING] Every
PATCHEDdocs/project-reference/**doc MUST run/prompt-enhance <doc>(default--op=enhance) before the verdict is recorded. These docs are injected into every downstream AI context — a surgical edit that adds correct prose without re-compressing still leaves the doc bloated./prompt-enhancekeeps content as concise as possible while staying valuable enough for AI (caveman compression + attention anchoring), closing the same gap on the narrow patch path that/scan --target=X's own mandatory final step (scan/SKILL.mdFinal Step) already closes on a full rescan — so aRESCAN REQUIREDdoc that escalates to/scangets it for free and needs no separate call here. Skip ONLY for a single stamp/date/count-only edit, and record the skip reason.
Step 1.4: project-config.json Drift Check (single writer, schema-validated)
Verify ONLY the sections the map flagged. For each:
- Re-derive from evidence — read the changed files, not the old config value.
- Surgical merge — add/update entries; NEVER rename, remove, or restructure a top-level section (the
/project-configSchema Protection Rules apply here unchanged). - Prove every touched
pathRegex/path still matches something real — a regex that matches zero files is stale config that silently disables every downstream router that depends on it, and no schema check catches it:
node -e "const c=require('./docs/project-config.json');const {execSync}=require('child_process');const files=execSync('git ls-files',{encoding:'utf8'}).split('\n').filter(Boolean).map(f=>'/'+f);for(const m of c.modules||[]){const re=new RegExp(m.pathRegex,'i');const n=files.filter(f=>re.test(f)).length;console.log((n?'OK ':'DEAD')+' modules.'+m.name+' -> '+n+' file(s)')}"
- Validate the schema after the merge:
node -e "const {validateConfig}=require('./.claude/hooks/lib/project-config-schema.cjs');console.log(JSON.stringify(validateConfig(require('./docs/project-config.json')),null,2))"
- Escalate, don't improvise — a NEW top-level section, a new module class, a new tech stack, or a failed validation means the change is a re-scan, not a patch → run
/project-config(and report that it is required if it cannot run in this session).
Step 1.5: README & Project Docs (docs-manager)
Pass the Phase 0 diff context to a docs-manager sub-agent (subagent_type="docs-manager") for the prose project docs in the same wave:
README.md— update if project scope or setup changed (keep under 300 lines)docs/project-reference/project-structure-reference.md— update if service architecture or cross-service patterns changed (same agent as README: shared source of truth)
Standalone invocation (not a workflow step) may first spawn 2-4 scout-external (preferred) or scout agents to locate affected areas; as a workflow step, skip scouting and use the Phase 0 diff context.
Exclusions unchanged: this agent NEVER owns docs/specs/**, test specs, spec-index/ERD, or derived technical views.
Step 1.6: Stamp Discipline (BLOCKING)
| What ran | Stamp to write |
|---|---|
Full /scan --target=X |
<!-- Last scanned: YYYY-MM-DD --> (owned by scan, top of doc) |
…(truncated)