Section 03 — Minimal JSON-Authoring Substrate
Bootstrap substrate; lands before §04 so converted plans are per-plan executable without the §05 cross-plan engine.
Goal
See frontmatter. Three pieces: routing-only schema + write API (03.1), the net-new id-keyed scanner (03.2), per-plan serve_next (03.3). All per-plan; no cross-plan dependency.
Intelligence Reconnaissance
- 2026-05-28 — graph queries grounding the §03 substrate scope:
scripts/intel-query.sh symbol-plans serve_next --repo ori— confirms[ori:scripts/plan_corpus/graph.py:188]plan-agnostic implementation;serve_nextconsumes aGraphkeyed bynodes; cross-plan hints currently filter viah in self.nodes(line 188-189) and silently drop non-local references.scripts/intel-query.sh file-symbols scripts/plan_corpus/graph.py --repo ori— confirmsGraph.from_plan_json,serve_next,relocate_past_blocker,escalate,merge_nodesare the API surface the §03.3 per-plan substrate reuses unchanged on the in-plan node set; the cross-plan hint wrapper layers on top.scripts/intel-query.sh symbol-plans check_item --repo ori— confirmscheck_itemconsumes JSON line-numbers (NOT id-in-markdown scanning); grounds §03.2 net-newcheckbox_scan.pyintroduction as a non-duplicating layer atop existing JSON-line discipline.
- Summary (≤500 chars): §03 is a bootstrap substrate consuming the §02-emitted routing-only
plan.json(INV-3) + delivering schema (§03.1), id-keyed scanner (§03.2), per-planserve_nextreuse + cross-plan hint wrapper (§03.3), todo-yah render view (§03.4); all per-plan; NO §05 cross-plan engine dependency. Schema is the SSOT for the INV-17 + INV-19 + INV-20 impossible-state invariants. The cross-plan hint wrapper closes the silent-drop gap surfaced byserve_nextgraph-filtering.
03.1 — plan.json routing-only schema + atomic write API
- Author
scripts/plan_corpus/schemas/v6/plan-routing.schema.json— formal version landed 2026-05-28 (bootstrap-stub title retired; migration_stamp field removed per §02.R DD-01 RESET-only policy). - INV-19 schema rejects branch-encoding fields on
nodes[]—additionalProperties: falseat RoutingNode covers all listed fields;test_k_validate_raises_on_every_invariant_pathnegative pins cover the matrix. - Author the atomic
plan.jsonwrite API — landed atscripts/plan_corpus/plan_json_write.py:78 mutate_routing_state(fcntl.flock-serialized read-modify-write, tempfile + os.replace, schema-validation BEFORE disk write,expected_read_base_hashCAS per state-discipline.md §4). 8/8 tests pass (scripts/plan_corpus/tests/test_plan_json_write.py). - INV-17 cross-field invariant — Completion subschema authored at
schemas/v6/plan-routing.schema.json:63with required{verifier, verified_at, body_hash, gates_verified};allOf if/thenat lines 56-61 makesstatus: doneUNREPRESENTABLE without Completion. - INV-20 strict-forward —
Completion.gates_verifiedatschemas/v6/plan-routing.schema.json:74hasminItems: 1;test_j_inv20_gates_verified_positive_negative_pinscovers the {empty, missing, non-empty, in-progress+gates} matrix. - Subsection close (03.1) — all
[x];status: complete.
03.2 — id-keyed checkbox scanner (NET-NEW; fenced-block skip)
- Author
scripts/plan_corpus/checkbox_scan.py— fence-state machine tracks```and~~~opener families separately; suppresses matching inside fences. - Match
^\s*- \[(x| )\] \[([^\]]+)\]on non-fenced lines →CheckboxEntry{id, checked, line}(1-indexed).derive_node_status(entries)returnsdone(all checked) /in-progress(mixed) /not-started(empty or all unchecked). - This is the SOLE status-derivation mechanism (single update point, INV-10); item status lives ONLY in the content markdown checkbox.
- INV-18 content-size lint —
scripts/plan_corpus/content_size_lint.pyauthored;DEFAULT_CAP = 300per routing.md §5;check_content_file()+scan_content_dir()flag over-cap content ids; cap is a content lint NEVER aplan.jsonfield (INV-3 preserved); wholecontent/<id>--<slug>.mdis the read contract (no fragment /section_infoslice). 18 tests pass (scripts/plan_corpus/tests/test_checkbox_scan.py). - Subsection close (03.2) — all
[x];status: complete.
03.3 — per-plan serve_next (reuse graph.py)
- Build a per-plan
Graph—scripts/plan_corpus/per_plan_route.py:build_graph_from_plan_jsonconverts v6 routing-only plan.json nodes tograph.Nodeinstances;graph.serve_next/relocate/escalate/merge_nodesreused unchanged on the in-plan node set. - Authored cross-plan hint-resolution wrapper —
serve_next_with_cross_plan(graph, corpus_lookup)atscripts/plan_corpus/per_plan_route.py:78. For each candidate node’shint_needsNOT ingraph.nodes, queriescorpus_lookup(node_id) -> str|None; defers the candidate when any cross-plan hint is non-done (status-lookup, NOT relocation trigger). - Cross-plan
hint_needssemantics: satisfied (done) → ignore; unknown (Nonefrom corpus_lookup) → ignore; unsatisfied (non-done) → defer this node. Relocation never moves nodes across plans (refinement 4 preserved by construction). - Tests: positive pin (cross-plan hint satisfied → served); negative pin (cross-plan hint unsatisfied → deferred to next in-plan candidate); pin (all candidates blocked → None); pin (in-plan relocation still works through
graph.serve_next); pin (corpus_lookup never called for in-plan hints). 13 tests pass (scripts/plan_corpus/tests/test_per_plan_route.py). - Subsection close (03.3) — all
[x];status: complete.
03.4 — render.py —view todo-yah (linear-walk visibility view per §00.4)
- Author
scripts/plan_corpus/render_todo_yah.py:render_todo_yah(plan_json, *, content_dir, active_node_id, drift_node_ids)— emits ASCII linear walk in lexorank order from a v6 routing-only plan.json; per-row format<marker> <plan_id>:<node_id> <slug>[ <-- YOU ARE HERE]. - Marker semantics:
[x]=status: done+completionpresent (INV-17 attestation gate);[>]=status: in-progressORstatus: in-review;[ ]=status: not-started;[!]= drift (done-without-attestation OR explicit drift_node_ids member OR unknown status). - YAH annotation —
active_node_idparameter accepts the currently-active node id; matching row gets<-- YOU ARE HEREappended (ASCII only; no Unicode arrows). - Deterministic — pure-function render; lexorank
keysort is total-order withidtiebreak; notime.time()/ random / session state.test_render_is_deterministic_across_repeated_callspins byte-identity. - Tests: lexorank ordering pin; per-status marker pins (
not-started,in-progress,in-review,donewith completion,donewithout completion = drift); explicit drift_node_ids pin; unknown-status drift pin; YAH annotation pin (present + absent); empty plan pin; ASCII-only pin; plan_id-in-row pin. 14 tests pass (scripts/plan_corpus/tests/test_render_todo_yah.py). - Subsection close (03.4) — all
[x];status: complete.
03.R — Third Party Review Findings
- [TPR-03-001-agy+claude-ds][Major] STRUCTURE:atomic-flip-violation (filed 2026-05-28 /tpr-review cap-exit): §02 frontmatter
status: complete + reviewed: falseviolates state-discipline.md §4 atomic-flip discipline —reviewed: trueis the §00.3 close-out gate that must flip before/withstatus: complete. Not inline-curable by /tpr-review (state-discipline.md §4:reviewed:field owned exclusively byflip_from_in_review_clean()at /review-plan close-out). Cure: when /review-plan §02 next runs Step 7+8 §02.3 close-out, the atomic flip will resolve. Surfaced here for §03 close-out completeness; §03 reviewed:true flip blocked on this until §02 is fully closed.
References
- Pass 1B:
graph.pyserve_next/relocate/escalate/merge (:176/:209/:216/:230/:243) plan-agnostic;lexorank.pyAPI. - Pass 1C: scanner net-new;
write.py:check_itemuses JSONlinenot id-scan; fenced-skip not implemented today. - §01 invariants 4 (linear walk/relocate), 5 (cyclic-impossible), 9 (single update point), 10.
- §03A — Substrate verification gates (migrated §03.N close-out per deadlock-cure 2026-05-28 Option 1).
HISTORY
- 2026-05-28 — Deadlock cure (Option 1: migrate cycle-causing subsection): §03.N Completion Checklist migrated to new sibling
section-03A-substrate-verification.md. §03 deliverables §03.1-§03.4 are allstatus: complete; the prior §03.N close-out gates (pytest substrate suite, negative-import test, plan_corpus check, /tpr-review final) gated §03 close on downstream verification work, holding 9 dependent sections (§04-§12) waiting on §03. Per recommended_unblock Option 1, the gates moved to §03A so §03 flipsstatus: completeon its own deliverables. §03A carriesdepends_on: ["03"]and owns the verification gates. §03.R TPR-03-001 (reviewed:true blocked on §02 fully closing) remains in §03 — that finding is about §03’sreviewed:flip ownership, not itsstatus:flip. - 2026-05-29 — §07A v7 route schema supersedes the v6 substrate contract: the route schema v7 two-level
plan.json(sections[]+ flatwork_items[], per §07A +decisions/04-sections-work-items-split.md) supersedes the v6 flat-nodenodes[]model; §03’s v6 substrate stayscompletebut the id-keyed checkbox scanner is deprecated and the v7work_itemstatus write API + both v7 validators (array==sorted+unique, JSON<->md coherence) are added per §07A.3.