Section 02: CLAUDE.md §Plan Routing Stanza + impl-hygiene.md PLAN_ROUTING_DRIFT Category
Status: Complete Goal: Land the canonical rule text and reviewer finding category that every later section relies on. §03’s helper references the routing rule; §04’s reviewer wiring references the finding category; §05’s migration must not proceed until the rule is published (new migrations would be flagged CRITICAL otherwise, which is correct, but §05 is the migration itself).
Success Criteria:
-
grep -c "Plan Routing — Mechanical" CLAUDE.mdreturns 1 (connects to mission criterion: “CLAUDE.md carries a new §Plan Routing — Mechanical stanza”) - The new stanza is ≤60 lines, prose-lint clean (no dated narrative, no rationale tails, no “previously X, now Y”)
-
grep -c "PLAN_ROUTING_DRIFT" .claude/rules/impl-hygiene.mdreturns at least 1 (category bullet) -
grep -c "PLAN_ROUTING_DRIFT.*Critical" .claude/rules/impl-hygiene.mdreturns at least 1 -
python3 scripts/prose-lint.py CLAUDE.md .claude/rules/impl-hygiene.mdexits 0
Context: The 2026-04-24 bug-tracker redesign added §Bug Handling and §Plan-Blocker Bugs stanzas to CLAUDE.md. This section adds the parallel §Plan Routing stanza so plans inherit the same mechanical discipline. The finding category lives in impl-hygiene.md because that is the SSOT for reviewer severity classification — adding it there propagates to every reviewer skill without per-skill edits.
Reference implementations:
- CLAUDE.md §Plan-Blocker Bugs Belong IN the Plan (lines 46–53): six-bullet structure covering default routing, carve-outs, banned anti-patterns, cure, reviewer flag. The new stanza mirrors this shape.
- impl-hygiene.md §Finding Categories (8 existing entries): INVERTED-TDD (Critical), LEAK (Critical), DRIFT (Major), GAP (Major), WASTE/EXPOSURE/BLOAT (Minor), [NOTE] (informational). PLAN_ROUTING_DRIFT slots in as Critical, matching INVERTED-TDD’s severity because routing errors silently fragment the DAG.
Depends on: Section 01 — cannot write accurate rule text without knowing what Fallback-R looks like in practice (from the manifest).
Intelligence Reconnaissance
Queries run 2026-04-24:
scripts/intel-query.sh --human search "PLAN_ROUTING_DRIFT" --limit 5— prior art scan for routing-drift finding categories across reference repos; results inform severity weight selection.scripts/intel-query.sh --human symbols "classify_bug_exclusion" --repo ori --limit 5— locates the factoring precedent inscripts/plan_corpus/bug_markers.pythat motivates the single-bullet finding-category extension pattern.grep -n "Plan-Blocker Bugs" CLAUDE.md— locates the structural parallel at line ~46.grep -nE "^### " .claude/rules/impl-hygiene.md | head -20— enumerates finding-category section headers.grep -c "Critical\|Major\|Minor" .claude/rules/impl-hygiene.md— confirms severity-level vocabulary is established.
Results summary (≤500 chars) [ori]: CLAUDE.md §Plan-Blocker Bugs Belong IN the Plan provides the canonical stanza shape (default/carve-outs/banned/cure/reviewer-flag). impl-hygiene.md §Finding Categories has 8 entries with Critical/Major/Minor severities; adding PLAN_ROUTING_DRIFT as Critical matches INVERTED-TDD’s severity weight. Prose-lint (scripts/prose-lint.py) enforces no-prose rule on authored .md — stanza must be bullets + tables, ≤2-sentence paragraphs.
See .claude/skills/query-intel/compose-intel-summary.md for the full query protocol.
02.1 Author CLAUDE.md §Plan Routing — Mechanical stanza
File(s): CLAUDE.md (wrapper root)
Add a new stanza between existing §Plan-Blocker Bugs Belong IN the Plan (CLAUDE.md:46–53) and §Tests That Expose Bugs (CLAUDE.md:55). Preserve the surrounding flow.
-
Draft the stanza body (target ≤60 lines, bullet-heavy, no prose):
### Plan Routing — Mechanical - **Default routing**: every new plan's scope maps mechanically to an owning roadmap section via `owns_crates:` frontmatter inversion, identical to `/add-bug` Step 0. Routing is computed at plan-creation time (`/create-plan` Step 0.6); author declares scope (crates touched), helper decides artifact kind. - **Multi-crate rule — primary-by-count**: count how many of the plan's scoped crates each roadmap section owns. Section with strictly-max count wins → subsection of that section. Ties → Fallback-R. - **Artifact kinds**: - **Subsection** (default) — scope maps to one dominant roadmap section; plan becomes `plans/roadmap/section-NN-*.md` subsection. - **Fallback-R peer plan** — scope ties across sections OR scope crates have no owning section; plan lives at `plans/<name>/` with `reroute: true` + `routing_justification: "..."` frontmatter. - **Tracker-index entry** — scope is orthogonal to compiler code (doc-only, skill-only, tooling-only); entry in `bug-tracker/section-NN-*.md`. - **Helper SSOT**: `scripts/plan_routing.py` owns the inversion + primary-by-count algorithm; consumed by `/add-bug` Step 0 and `/create-plan` Step 0.6. Duplicating the algorithm elsewhere is a `LEAK:algorithmic-duplication` violation. - **Banned anti-patterns**: - `target_section:` frontmatter chosen by plan author — re-introduces the judgment the mechanical rule eliminates. - Sibling `plans/<name>/` peer plans without `routing_justification:` — same hazard as the banned `fix-BUG-*.md` sibling files. - `target_crate:` / "primary crate" selection — deterministic count replaces author judgment. - **Cure (if banned anti-pattern surfaces)**: back out the siblings, re-run `scripts/plan_routing.py` on their scope, migrate to subsection or Fallback-R with `routing_justification`. - Reviewers (`/tpr-review`, `/review-plan`) MUST flag NEW `plans/<name>/` directories without `routing_justification` as `PLAN_ROUTING_DRIFT` (Critical per `impl-hygiene.md §Finding Categories`). `scripts/plan_corpus/schemas.py` validator rejects `reroute: true` without `routing_justification:` at `plan_corpus check --strict-recon` time. -
Edit
CLAUDE.mdinserting the stanza at the correct position (after §Plan-Blocker Bugs Belong IN the Plan, before §Tests That Expose Bugs) -
Verify stanza is grep-findable:
grep -c "Plan Routing — Mechanical" CLAUDE.mdreturns 1 -
Run prose-lint:
python3 scripts/prose-lint.py CLAUDE.mdexits 0 -
Subsection close-out (02.1) — MANDATORY before starting 02.2:
- Stanza text committed; grep verification + prose-lint both green
- Update this subsection’s
statustocomplete - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check
02.2 Extend impl-hygiene.md §Finding Categories with PLAN_ROUTING_DRIFT
File(s): .claude/rules/impl-hygiene.md
Add one bullet to the existing §Finding Categories list. The category shape matches existing entries (category name, default severity, one-sentence definition).
-
Locate the §Finding Categories section (
grep -n "## .*Finding Categories" .claude/rules/impl-hygiene.md) -
Draft the new entry:
- **PLAN_ROUTING_DRIFT** — Default: **Critical**. A plan artifact exists at a location inconsistent with the mechanical `owns_crates` routing rule (CLAUDE.md §Plan Routing — Mechanical). Surface forms: new `plans/<name>/` directory without `routing_justification:` frontmatter; plan scope maps to a single roadmap section's `owns_crates` but was created as a peer plan instead of a subsection; `routing_justification:` present on a subsection-routable plan (should be absent); duplicated routing algorithm outside `scripts/plan_routing.py`. Severity matches INVERTED-TDD (Critical) because routing errors silently fragment the plan DAG, making work invisible to scanners (`/continue-roadmap`, `/fix-next-bug`), and downstream bug routing via `owns_crates` produces incorrect Fallback-R assignments. -
Insert after DRIFT entry (immediately before GAP), preserving the Critical→Major→Minor→informational severity ordering established in the file
-
Run prose-lint:
python3 scripts/prose-lint.py .claude/rules/impl-hygiene.mdexits 0 -
Verify both category name and severity are grep-findable:
grep -c "PLAN_ROUTING_DRIFT" .claude/rules/impl-hygiene.mdreturns at least 1;grep -c "PLAN_ROUTING_DRIFT.*Critical" .claude/rules/impl-hygiene.mdreturns at least 1 -
Subsection close-out (02.2) — MANDATORY before starting 02.N:
- Category entry committed; grep + prose-lint green
- Update this subsection’s
statustocomplete - Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check
02.N Completion Checklist
- All implementation subsections (02.1–02.2) are
[x]and statuscomplete - All section success criteria have corresponding
[x]checkboxes -
grep -c "Plan Routing — Mechanical" CLAUDE.mdreturns 1 -
grep -c "PLAN_ROUTING_DRIFT" .claude/rules/impl-hygiene.mdreturns ≥1 -
python3 scripts/prose-lint.py CLAUDE.md .claude/rules/impl-hygiene.mdexits 0 -
./test-all.shgreen — regression canary (compiler_repo clean; canary vacuous) -
python -m scripts.plan_corpus checkexits 0 for CLAUDE.md + impl-hygiene.md scope (if applicable) - Plan sync:
- This section’s frontmatter
status→complete, subsection statuses →complete -
00-overview.mdQuick Reference: Section 02 status →Complete -
00-overview.mdmission success criteria: check off “CLAUDE.md carries §Plan Routing stanza” + “impl-hygiene.md includes PLAN_ROUTING_DRIFT Critical” -
index.mdSection 02 status →Complete
- This section’s frontmatter
- Repo hygiene check —
compiler_repo/diagnostics/repo-hygiene.sh --check(verified clean 2026-04-24).
Exit Criteria: Stanza + category both landed and grep-verified; prose-lint green on both edited files; ./test-all.sh green.