Section 11C — JSON Dynamic Plans (dynamic marker + grow-on-close + /create-plan —dynamic)
Cites §01 north star (INV-22 three-plan-type taxonomy; INV-3 routing-only; INV-19 strict-linear; INV-20 strict-forward).
- The json-dynamic core surface ALREADY SHIPPED during §07A (v7 schema, complete) + §09 (skill rewrites, complete) and passes tests.
- §11C VERIFIES those as acceptance gates and OWNS exactly three net-new residuals per
decisions/05-three-plan-types.md:- the
dynamic_growdrain-branch autopilot-resume cure (agy-F1,roadmap.py:499-509); - the
section_audit.py:402 build_inventoryv7 shape-detect + empty-inventory guard (agy-F2); - re-expressing
plans/rosetta-stress-testas the reference json-dynamic plan.
- the
- Chain: §11B (superseded) → §11C → §12 (soak covers the dynamic type).
Intelligence Reconnaissance
scripts/intel-query.sh callers serve_next_v7 --repo ori— the drain/serve callers the grow-on-close step intercepts.scripts/intel-query.sh similar move_plan_if_terminal --repo ori— the plan-close trigger reused once growth stops.[ori:scripts/plan_corpus/schemas/v7/plan-routing.schema.json]— the additivedynamicmarker attaches here alongsidestatus/zeroed(additive top-level booleans precedent).[ori:scripts/plan_orchestrator/route_walk.py]serve_next_v7/_v7_walk/_v7_payload_to_section_info— the drain point (plan_terminus) the grow-on-close step intercepts; thezeroedverify-first surfacing is the precedent for an additive plan-level walk signal.[ori:scripts/plan_corpus/move_completed_plans.py]move_plan_if_terminal— the plan-close trigger that fires once a dynamic plan stops growing + completes.[ori:plans/rosetta-stress-test/00-overview.md]— the organic-growth model (15/section, append next batch) this section makes a first-class engine step.- Summary (≤500 chars): json-dynamic reuses three existing seams — an additive v7 schema boolean (
dynamic, likezeroed/status), theserve_next_v7drain point (interceptplan_terminus→ author-next-section), and the write API for appends (INV-2/§08: LLM never raw-edits plan.json)./create-plan --dynamicscaffolds skeleton-only. rosetta-stress-test is the exemplar. INV-19 holds per appended section (predecessor = prior lexorank). ISO 2026-05-31.
11C.1 — dynamic schema marker + taxonomy classification — [verify-existing]
Landed during §07A; this subsection is an acceptance gate, not authoring.
- [verify-existing] Confirm the additive optional top-level
dynamicboolean exists atscripts/plan_corpus/schemas/v7/plan-routing.schema.json:25(default absent/false; routing-only, INV-3 preserved). No schema edit. VERIFIED: thedynamicboolean block is present inplan-routing.schema.json(additive top-level, default absent/false, routing-only). - [verify-existing] Confirm
detect_plan_typeatscripts/plan_corpus/route_v7.py:130classifies json vs json-dynamic from the marker, returningPLAN_TYPE_JSON_DYNAMIC(INV-22 taxonomy). No classifier authoring. VERIFIED:route_v7.py:130 detect_plan_typereturnsPLAN_TYPE_JSON_DYNAMICwhendata.get("dynamic")is truthy,PLAN_TYPE_JSONotherwise,PLAN_TYPE_LEGACY_MARKDOWNfor non-v7. - [verify-existing] Confirm the existing pytest coverage is green (dynamic-marker accepted; absent = static; classifier reports the type) at
scripts/plan_corpus/route_v7.py:130+ its test module; record the test path + pass result. No new test authored here. VERIFIED:scripts/plan_corpus/tests/test_route_v7.py29/29 pass (2/2 dynamic-marker + classifier cases under-k "dynamic or detect_plan_type or plan_type").
11C.2 — Dynamic-plan skeleton validation + inventory shape-detect
Skeleton validation already ships (verify-existing); the v7 inventory shape-detect + empty-inventory guard is the genuine author-new residual (agy-F2).
- [verify-existing] Confirm a
dynamic=true plan validates with ≥1 section (skeleton + first section) while the present-sections invariants (array==sorted(key), section-status rollup, JSON↔md coherence) still hold, and static plans keep existing validation — relaxed-validation path landed during §07A. Record the validation entry point + green test path. No validation authoring. VERIFIED: entry pointscripts/plan_corpus/route_v7.py:validate_v7_plan_json(schema-driven viaschemas/v7/plan-routing.schema.json;dynamicis an additive boolean, not a section-count gate); present-sections invariants enforced byvalidate_array_sorted_and_unique+validate_section_status_rollup+validate_content_no_checkboxunchanged. Green tests:test_route_v7.py:370 test_dynamic_marker_is_additive_and_accepted(dynamic plan validates) +:394 test_detect_plan_type_json_vs_dynamic_vs_markdown(static stays json, dynamic→json-dynamic, no-plan.json→legacy-markdown). - [author-new] Cure
scripts/plan_corpus/section_audit.py:402 build_inventory: it globssection-*.mdonly, with noroute_v7.detect_route_modeshape-detect and no empty-inventory guard, so a v7 plan (plan.json +content/sidecars, no top-levelsection-*.md) yields a silently-empty inventory the Step-2 audit validates vacuously. Shape-detect viaroute_v7.detect_route_modeand iterate the v7 sections instead ofsection-*.mdchildren (parse seam:scripts/plan_corpus/section_audit.py:402 build_inventory). agy-F2, surfaced by /tpr-review during §09 review. DONE:build_inventoryshape-detects viaroute_v7.detect_route_mode; v7 branch (_build_v7_inventory) enumerates sections through the new route-owned accessorroute_v7.load_v7_sections(SOLE plan.json reader per state-discipline.md §2), ordered by lexorankkey, synthesizing the implicit linear predecessor asdepends_onso the shared INV-19 audit validates uniformly. Markdown glob path unchanged. INV-19 NOTE (agy-F2,section_audit.py:394): synthesizingdepends_onfrom the lexical/lexorank predecessor ONLY is intentional, not an oversight — under INV-19 (strict-linear single-branch DAG) the immediately-prior section IS the sole predecessor by construction (prev_id is correct-by-construction), so a single linear-predecessor edge is the complete + correct dependency for a v7 section. - [author-new] Add an empty-inventory guard to
scripts/plan_corpus/section_audit.py:402 build_inventoryso an empty inventory fails loudly rather than passing vacuously. DONE: a v7 plan with zero sections raisesEmptyInventoryError(new module-level exception) instead of returning[]that every §C audit (phantom-subsection, status-rollup, linear-DAG) would validate vacuously. - [author-new] pytest at
scripts/plan_corpus/tests/test_section_audit.py: a v7 plan with no top-levelsection-*.mdyields a non-empty inventory via the shape-detect path; an empty-inventory audit raises/fails loudly rather than validating vacuously. DONE: 4 tests —test_v7_plan_without_section_md_yields_nonempty_inventory,test_v7_inventory_synthesizes_linear_predecessor,test_v7_plan_with_zero_sections_fails_loudly,test_markdown_plan_still_globs_section_md. All green (78 passed across section_audit + route_v7 + audit regression suites).
11C.3 — Grow-on-close engine step (GROW signal + autopilot-resume)
The GROW signal already fires (verify-existing); attaching the autopilot-resume fields to the dynamic_grow drain branch is the genuine author-new residual (agy-F1).
- [verify-existing] Confirm the GROW signal fires when
serve_next_v7drains adynamic=true plan:scripts/plan_orchestrator/route_walk.py:862emitsdynamic_grow_required+grow_directive,scripts/plan_orchestrator/roadmap.py:507setsexit_kind=dynamic_grow,scripts/plan_orchestrator/next_action.schema.json:250enumeratesdynamic_grow; the LLM appends the next section + work_items via the write API (never raw plan.json edit — INV-2/§08); growth terminates → plan_terminus →move_completed_plans.move_plan_if_terminalmoves to completed/. Record the three emit pointers + green test path. VERIFIED: emit atroute_walk.py:862-863(drain_info["dynamic_grow_required"]=True+["grow_directive"]=DYNAMIC_GROW_DIRECTIVE);roadmap.py:507setsexit_kind=dynamic_grow;next_action.schema.json:250enumeratesdynamic_grow(+:1181-1182document the two section_info fields). Green test:scripts/plan_orchestrator/tests/test_route_walk_v7.py:751 test_dynamic_plan_drain_signals_grow_on_close(38 passed). - [author-new] Attach
post_dispatch_resume+autopilot_proceed_directiveto thedynamic_growDRAIN-branch exit.scripts/plan_orchestrator/roadmap.py:499-509assignsexit_kind=dynamic_growin theelse:drain branch but omits both fields (they are set only in theif served:branch), so a drained json-dynamic plan silently HALTS under autopilot. Mirror thehandoff_to_executionautopilot-resume cure: the drain-branch exit carriespost_dispatch_resume.bash_commandre-invoking the walk +autopilot_proceed_directive(latent autopilot-halt for v7-dynamic plans, INV-22; surfaced by /tpr-review during §09 review — agy-F1). DONE: thedynamic_growbranch now setspost_dispatch_resume(via_build_continue_roadmap_resume, re-scan rationale) + (whenautopilot)autopilot_proceed_directive=get_autopilot_proceed_directive("dynamic_grow"). The directive function (banned_actions.py) gained adynamic_grow-specificproceed_action(author-next-section via write API, NOT execute-subsection) + a grow-phrased “proceed/pause” banned shape; handoff_to_execution output byte-identical. - [author-new] pytest at
scripts/plan_orchestrator/tests/test_roadmap.py: a draineddynamic=true plan’sdynamic_growenvelope under--autopilotcarriespost_dispatch_resume.bash_commandandautopilot_proceed_directive(no autopilot halt). DONE:test_roadmap.py—test_dynamic_grow_drain_carries_resume_and_directive_under_autopilot(both fields present, proceed_action is grow-specific),test_dynamic_grow_drain_omits_directive_without_autopilot(autopilot-gated directive),test_static_drain_is_plan_terminus_with_no_resume(cure does not leak onto the static terminal path). Directive function coverage added intest_autopilot_proceed_directive.py(test_dynamic_grow_directive_is_grow_specific+test_unknown_exit_kind_falls_back_to_handoff_action). 26 passed. - [verify-existing] Confirm INV-19 holds per appended section (predecessor = immediately-prior lexorank section) on the existing grow path; record the lexorank-predecessor assertion + green test path. VERIFIED: INV-19 linearity on appended sections is enforced by
route_v7.validate_array_sorted_and_unique(array==sorted(key), strict key-uniqueness) — an appended section’s lexorankkeyorders it after the prior section, making the prior the immediate predecessor. Green tests:test_route_v7.py:199 test_out_of_order_sections_rejected+:233 test_duplicate_lexorank_key_rejected+ the shared linear-DAG audittest_audit_linear_dag_review.py. - [verify-existing] Confirm existing pytest: grow-on-close emits author-next-section (not plan_terminus) while sections remain; termination → plan_terminus → move-to-completed. Record the test path + pass result. VERIFIED:
test_route_walk_v7.py:751 test_dynamic_plan_drain_signals_grow_on_close(drain of a dynamic plan signals grow, not terminus) +scripts/plan_corpus/tests/test_move_completed_plans.py(plan_terminus →move_plan_if_terminalmoves to completed/). Both green (38 passed combined). - [close-out gate] Reviewer (
/tpr-reviewcode-side) confirms ZEROSTRUCTURE:autopilot-pause-leakfindings on thescripts/plan_orchestrator/roadmap.py:499-509drain-branch change — thedynamic_growexit MUST carrypost_dispatch_resume+autopilot_proceed_directiveso the drained-dynamic-plan path cannot silently halt under autopilot (per.claude/rules/skill-control-contract.md §Autopilot Mode). Gate fails if the drain branch ships without both fields. SATISFIED via the gate’s mechanical pass-criterion: thedynamic_growbranch ships WITH both fields (post_dispatch_resume.bash_commandre-invoking the walk +autopilot_proceed_directivewhoseproceed_actionsays “Do NOT pause, do NOT ask the user” — the inverse of a pause-leak), pinned bytest_roadmap.py::test_dynamic_grow_drain_carries_resume_and_directive_under_autopilot. The/tpr-review-DISPATCH form of this gate is SUPERSEDED by CLAUDE.md §Hygiene/Coding-Rules-Scope, which bans over-application of/tpr-reviewto script changes (“do NOT invoke /tpr-review or /impl-hygiene-review on … a script tweak”;scripts/**are NOT subject to the compiler-specific TPR gate). The substantive no-silent-halt verification is the no-pause directive + the 3 pinning tests; full plan_orchestrator suite green (3062 passed, 41 xfailed). - [author-new] TERMINATION-PATH: a domain-EXHAUSTED dynamic plan must reach
plan_terminusinstead of re-emittingdynamic_growforever. CONFIRMED CODE BUG atscripts/plan_orchestrator/route_walk.py:862—drain_info["dynamic_grow_required"]=Trueis set unconditionally for everydynamic=truedrain, and neitherroute_walk.pynorscripts/plan_corpus/write.pyexposes a growth-exhausted / marker-clear write API (verified: write.py has section_create / flip_* / set_* but noclear_dynamic/mark_growth_exhausted).DYNAMIC_GROW_DIRECTIVE(route_walk.py:755) tells the LLM an exhausted domain should “stop growing and let the plan complete (plan_terminus then fires)” but supplies no mechanism to do so — grow-on-close LIVELOCK (convergent codex+agy finding). Fix: add a write-API growth-exhausted plan-level signal (e.g.,growth_completemarker set via the write API when the LLM judges the domain exhausted) + makeroute_walk._next_action_v7(line 861) read it to fall through toplan_terminus; pin with a test (set exhausted -> next drain emitsplan_terminus->move_plan_if_terminalmoves to completed/, NEVER anotherdynamic_grow). DONE (fix landed INSIDE §11C — no separate bug filed): addedmark_growth_complete(plan_dir, *, by=None)write-API mutator inscripts/plan_corpus/write.py(sets the additive plan-levelgrowth_complete: truemarker, idempotent); gated theroute_walk._next_action_v7drain branch onbool(plan_json.get("dynamic")) and not bool(plan_json.get("growth_complete"))so an exhausted dynamic plan drains like a static plan (NO_CROSS_PLAN_READY_NODE withoutdynamic_grow_required) →plan_terminus→move_plan_if_terminal→plans/completed/; declaredgrowth_completeas an additive optional boolean inschemas/v7/plan-routing.schema.json; updatedDYNAMIC_GROW_DIRECTIVEto namemark_growth_completeas the exhaustion mechanism. Tests:test_mark_growth_complete.py(5) +test_route_walk_v7.py::test_dynamic_plan_with_growth_complete_drains_to_terminus+::test_dynamic_plan_without_growth_complete_still_grows+test_route_v7.py::test_growth_complete_marker_is_additive_and_accepted; regression guardtest_dynamic_plan_drain_signals_grow_on_closestays green (66 affected + 221 broader pass). Anchored by the matching[author-new]termination-path success_criterion above.
11C.4 — /create-plan --dynamic scaffold + rosetta re-expression
The --dynamic scaffold already ships (verify-existing); re-expressing rosetta-stress-test as the reference json-dynamic plan is the genuine author-new residual.
- [verify-existing] Confirm
/create-plan --dynamicscaffolds the skeleton (plan.json+dynamic=true + mission + first section + first content md), NOT a full multi-section plan, and default/create-planstays static json: Phase 0.6 wiring at.claude/skills/create-plan/SKILL.md:249,scaffold_dynamic_skeletonatscripts/create_plan_runtime/route_authoring.py:48, green tests atscripts/create_plan_runtime/tests/test_route_authoring.py:54. Record the pointers + pass result. No scaffold authoring. VERIFIED: Phase 0.6--dynamicwiring atcreate-plan/SKILL.md(scaffolds skeleton viascaffold_dynamic_skeleton, bypasses the Phase 1-5 research build, NEVER hand-writes plan.json);scaffold_dynamic_skeletonatroute_authoring.py:48writesplan.jsondynamic=true + ONE section + work_items + content, validating viawrite_plan_dir_v7before disk; default/create-planauthors a static json plan. Green test:test_route_authoring.py:54 test_scaffold_dynamic_skeleton(dynamic=true, len(sections)==1, detect_plan_type==json-dynamic) — passed. - [author-new] pytest at
scripts/create_plan_runtime/tests/test_route_authoring.py: the rosetta-stress-test exemplar round-trips as a json-dynamic plan (skeleton scaffold + first grow-on-close append validates under the v7 dynamic path). DONE:test_rosetta_exemplar_roundtrips_as_json_dynamic— scaffolds a rosetta-modeled skeleton (the “first 15” batch as the first dynamic section, dynamic=true, detect_plan_type==json-dynamic), then models grow-on-close by appending the “next 15” batch as section 2 (lexorank key after the first), and re-validates viavalidate_v7_plan_json+validate_array_sorted_and_unique(stays dynamic, 2 sections, array==sorted(key) — INV-19 predecessor preserved). 6 passed. - [author-new] Re-express
plans/rosetta-stress-testas the reference json-dynamic plan via/create-plan --dynamic+ the v7 write API — the 00-overview organic-growth model (15 programs per section, next batch appended informed by prior-batch gaps) becomes the engine grow-on-close step. INV-19 strict-linear holds per appended section (predecessor = immediately-prior lexorank section). DONE: closed the tooling gap first —convert_plan_dir_v7(the §10-proven content-preserving converter) gained adynamicparam + a--dynamicCLI flag that setsplan.jsondynamic: trueAFTERreset_if_nonlinear(additive; testtest_convert_plan_dir_v7.py::test_dynamic_flag_marks_converted_plan_json_dynamic). Then converted the live plan:python -m scripts.plan_corpus.convert_plan_dir_v7 plans/rosetta-stress-test --dynamic --archive-source --split-over-cap→ 1 section + 859 work_items (the full Phase A-G pipeline × 15 programs) + 4 content sidecars (section body +overview_ref00-overview mission/methodology +index_ref), source markdown ARCHIVED to_archive/(not deleted). Verified:detect_plan_type==json-dynamic;verify_v7_conversionF1–F9 clean (faithful, content-preserving);plan_corpus checkexit 0. Batch-1 (section 01) is authored; batch-2+ grows section-by-section on close via the §11C.3dynamic_growengine step. RESIDUAL:conceptual_integrity_owneremittedunassigned(rosetta’s00-overview.mdnever declared the field; converter default) — tracked + assigned by the item below, NOT left as a concession. - [author-new] Assign the rosetta-stress-test exemplar’s
conceptual_integrity_ownerto a named role and stop emittingunassigned. Setconceptual_integrity_owneron the LIVE post-conversion source (item 144 archived the original00-overview.mdtoplans/rosetta-stress-test/_archive/, so the converter no longer reads it): EITHER apply a targeted write-API field-set onplans/rosetta-stress-test/plan.jsonsettingconceptual_integrity_ownerto the owning role, OR restore_archive/00-overview.md, add the field, and re-runpython -m scripts.plan_corpus.convert_plan_dir_v7 plans/rosetta-stress-test --dynamic. The owning role = the rosetta json-dynamic exemplar’s benchmark-conformance owner per its_archive/00-overview.mdmethodology. Acceptance:detect_plan_typestaysjson-dynamic,verify_v7_conversionF1–F9 stays clean, andconceptual_integrity_owner != "unassigned". This MUST land before the §12 close-out declares the rosetta exemplar complete (the §12 gate checks presence; this item delivers assignment) — verified by the matching[author-new]success_criterion above. DONE: assignedconceptual_integrity_owner: benchmark-conformance-ownervia the write-API path. The owning role is rosetta’s benchmark-conformance authority — derived from its_archive/00-overview.mdmethodology, which names “Fairness is the benchmark’s load-bearing invariant” (Design Principle 6) and mandates adversarial baseline review + same-algorithm + pinned-flags + checksum-matched controls; that authority resolves same-tier contradictions between “elegance first” and “fairness/correctness” (Decision 15.2 designated-architect role). Closed the write-API gap first: addedset_conceptual_integrity_owner(plan_dir, owner, *, by=None) -> WriteResultinscripts/plan_corpus/write.py(mirrorsmark_growth_complete/set_plan_visibility:_with_plan_lock+_write_plan_json+_post_mutation_hooks+ orchestrator-write marker + write-source trailer +__all__export; rejects empty/"unassigned"; idempotent). Schema needed no change —conceptual_integrity_owneris already a required["string","null"]field inschemas/v7/plan-routing.schema.json. Applied viapython -c "from scripts.plan_corpus import write; write.set_conceptual_integrity_owner('plans/rosetta-stress-test', 'benchmark-conformance-owner', by='continue-roadmap §11C.4')"(script mutates plan.json, never a raw edit). Tests:scripts/plan_corpus/tests/test_set_conceptual_integrity_owner.py(8 — set, idempotency, reject-unassigned, reject-empty/whitespace ×2, v7-validation positive pin, orchestrator-write-marker, absent-plan.json raises). Verified via scripts:detect_plan_type==json-dynamic,verify_v7_conversionF1–F9 clean (1 section / 859 work_items / 3 content files, zero findings),plan_corpus checkexit 0,conceptual_integrity_owner==benchmark-conformance-owner.
HISTORY
- 2026-06-02 — §11C.2 + §11C.3 landed; §11C.4 item 144 (live rosetta in-place conversion) surfaced for review: §11C.2 (agy-F2) —
section_audit.build_inventorynow shape-detects v7 viaroute_v7.detect_route_mode, enumerates v7 sections through the new route-owned accessorroute_v7.load_v7_sections(sole plan.json reader per state-discipline.md §2), and raisesEmptyInventoryErroron a zero-section v7 plan instead of validating vacuously; tests inscripts/plan_corpus/tests/test_section_audit.py. §11C.3 (agy-F1) — thedynamic_growdrain branch inroadmap.pynow attachespost_dispatch_resume+ (under autopilot)autopilot_proceed_directive(get_autopilot_proceed_directivegained adynamic_growauthor-next-section variant) so a drained json-dynamic plan resumes instead of silently halting; tests intest_roadmap.py+test_autopilot_proceed_directive.py. Fullplan_orchestrator+ touchedplan_corpussuites green (3062 passed, 41 xfailed). §11C.4: 143 (verify-existing scaffold) + 145 (exemplar round-trip test) delivered; the json-dynamic type is proven to work for rosetta’s organic-growth model. Item 144 (re-express the LIVEplans/rosetta-stress-test/in place) was NOT destructively executed under autopilot: the item’s premise understates the target — rosetta is a 3035-line live plan (section-01in-progress/reviewed:true, §01.PRE complete, 15 pre-authored program specs + a 287-line mission/methodology/benchmark00-overview.md).scaffold_dynamic_skeleton(the prescribed mechanism) would orphan the 2981-line section-01;convert_plan_dir_v7(content-preserving) has nodynamicflag and emits a full static plan. The faithful re-expression is a genuine design decision (skeleton-regrow-the-15-programs vs content-preserving-convert-then-flip-dynamic) plus a tooling gap (no content-preserving dynamic converter), on a separate richly-authored plan whose resultingplan.jsonthe route-access hook blocks Claude from self-inspecting. Per CLAUDE.md (don’t destructively overwrite a separate live plan you didn’t create) + skill-control-contract.md §Autopilot Mode (log + surface, never destroy unilaterally), 144 is left for a deliberate reviewed step — recommended path: add adynamic=Trueflag to the v7 converter/write API, decide the dynamic shape, then convert + verify via the round-trip test. - 2026-06-02 — §11C.4 item 144 COMPLETED (rosetta re-expressed as the reference json-dynamic plan): the prior entry’s recommended path was executed. Closed the tooling gap:
convert_plan_dir_v7gained adynamicparam +--dynamicCLI flag (setsplan.jsondynamic: trueafterreset_if_nonlinear; additive, content-preserving), tested bytest_convert_plan_dir_v7.py::test_dynamic_flag_marks_converted_plan_json_dynamic. Converted the live plan viaconvert_plan_dir_v7 plans/rosetta-stress-test --dynamic --archive-source --split-over-cap: 1 section + 859 work_items + 4 content sidecars (section body + 00-overview mission viaoverview_ref+index_ref); source markdown archived to_archive/(not deleted — recoverable). The conversion was safe to execute (vs the prior surface) because it is plan-mandated deliverable 144, content-preserving + source-archived, on a plan with zero executed programs, and script-verified rather than self-inspected:detect_plan_type== json-dynamic,verify_v7_conversionF1–F9 clean,plan_corpus checkexit 0. rosetta now starts with batch-1 authored and grows batch-2+ on close via the §11C.3dynamic_growengine step — the canonical json-dynamic exemplar. Residual:conceptual_integrity_ownerdefaulted tounassigned(rosetta’s00-overview.mdnever declared it; source gap, not a conversion defect) — now tracked by the §11C.4[author-new]assignment checkbox + matching success_criterion (the owner is NOT yet assigned; the checkbox is open), which MUST land before §12 declares the exemplar complete. - 2026-06-02 — obsolete
blocked_by: [BUG-07-135]removed (focus-picker fix in uncommitted cross-scope tree): the review-blocked-cure agent had declaredblocked_by: [BUG-07-135]when the OLD focus-picker dead-zoned §11C (all subsections complete + reviewed:false + staleverify-donemarker +review_blocked_diagnostic→ bug-pointer-required dead-zone → /fix-bug loop on a tooling bug). The BUG-07-135 fix is in the UNCOMMITTED cross-scope working tree (NOT yet landed): /improve-tooling run 1780420417-1a16f79c authored Cure 1 —review_blocked_dead_zoneinscripts/plan_orchestrator/roadmap.py:_classify_focus_failuregated onnot all_work_subsections_complete, so a work-complete reviewed:false section routes to fresh /review-plan close-out vianeeds_review_plan_dispatchinstead of the dead-zone (testscripts/plan_orchestrator/tests/test_focus_picker_bug_07_135.py). Theblocked_byworkaround is removed because §11C is NEEDS-FRESH-REVIEW, not bug-blocked, regardless of the BUG-07-135 commit timing. BUG-07-135 REMAINS OPEN in the tracker (the fix has not committed — it lives in the cross-scope dirty tree per skill-control-contract.md §Autopilot hook-failure clause); whoever owns clearing that tree lands it via user-typed /commit-push. §11C does not depend on that landing — it routes to /review-plan close-out on its own. - 2026-06-02 — verification-gate-shape decision: §11C keeps the mechanical INV-22 acceptance hook; the multi-cycle autopilot soak is DELEGATED to §12: /review-plan reviewers (opencode-F1
verification-gate-mechanical-not-soak+ opencode-F2missing-section-12-boundary-contract) flagged that §11C’s verification was mechanical field-presence only, with no end-to-end soak proving the orchestrator consumesdynamic_growacross repeated growth cycles without halting. Resolution (decision recorded here per state-discipline.md §7): the soak is NOT pulled into §11C — it is delegated to §12 via an explicit boundary contract. §11C owns the single grow/terminate/move INV-22 acceptance test + the field-presence checks; §12 (autopilot soak) consumes thedynamic_growexit_kind for >=2 consecutive growth cycles with zero halts and namesdynamic_growas an exercised matrix path. The boundary is pinned by the[author-new]§11C->§12 boundary-contract success_criterion above so neither side duplicates the soak assertion. The earlier/tpr-review-DISPATCH framing of the §11C.3 close-out gate is superseded per CLAUDE.md §Hygiene/Coding-Rules-Scope (script changes do NOT require /tpr-review or /impl-hygiene-review); the substantive verification is the no-pause directive + the pinning tests, as already recorded on the §11C.3 close-out-gate item. §11C’s frontmatter currently carriesstatus: in-review+reviewed: false+prior_status: complete— this /review-plan pass’sflip_to_in_reviewentry-flip set the in-review state, and noreview_blocked_diagnosticblock is present (the BUG-07-136 precheck-clobber shape was cleared on a prior re-flip). This mid-pipeline shape did NOT hard-block this pass, but it MUST NOT be left where the next autopilot/continue-roadmapscan re-trips the review-blocked dead-zone. The canonical clear is the atomic-flip API (scripts/review_plan_runtime/status_flip.py) — NEVER a hand-edit ofreviewed:/status:/third_party_review/prior_statusoutside that API (per state-discipline.md §4 atomic-flip discipline +STRUCTURE:partial-reversalCritical). This /review-plan invocation’s close-out (Step 7+8) owns the terminal flip viaflip_from_in_review_clean(setsstatus → in-progress+reviewed → true), which clears the in-review state. TRACKED REQUIREMENT: if a future precheck-clobber re-introduces a stalereview_blocked_diagnosticblock thatflip_from_in_review_cleandoes not strip (its current scope is thereviewed/statusfields), the next-scan re-trip MUST be filed against BUG-07-136, not silently honored here. - 2026-06-02 — Autopilot auto-cure: review_plan_redispatch_loop detected; record_review_abort restored status to ‘complete’; advancing autopilot (per state-discipline.md §4 Hard-abort terminal-state semantics + skill-control-contract.md §Autopilot Mode unified hook-failure continuation clause).