§01 — Dual-mode plan.json-preferred + .md-fallback Astro loader
Goal
Make website_repo’s Astro plan-rendering pipeline consume plan.json natively (per Decision 14: plan.json is the SOLE canonical plan artifact), preferring it when present and falling back to the correct + functional section-*.md reader otherwise, so the live site never breaks during the mixed-corpus transition window (some plans .md, some plan.json). This deliverable shipped + verified in website_repo commit 3e3ef60 “feat(loaders): plan.json-native dual-mode plan-section loader” (2026-05-24 17:25).
§01.1 — plan.json-preferred branch + section-*.md fallback
-
plan-section-loader.tsprefers<base>/plan.json:JSON.parseofjoin(baseDir, 'plan.json'), iteratesubsections[]into per-section store entries, dereference eachbody_refsidecar (join(baseDir, sub.body_ref)→readFileSync→renderMarkdown) into the rendered body —plan-section-loader.ts:30-90(shipped in 3e3ef60). - Fall back to the existing
section-*.mdreaddirSync+parseYamlFrontmatter+renderMarkdownreader when noplan.jsonis present, so.md-only plans render unchanged —plan-section-loader.ts:93-94(shipped). -
lib/plan-data.tsreroutes/parallelPlansregistries continue readingindex.mdfrontmatter — 27 lines changed in 3e3ef60 (shipped). - Build-verify:
astro syncexits 0 with zero schema errors across all 24 rendered plans — verified per the 3e3ef60 commit body.
§01.2 — Resolve-before-validate sidecar dereference (no Zod change)
- Confirm the loader resolves
body_refsidecars into the renderedbody/renderedstore fields BEFORE Zod validation, passing only the already-resolved data object (plan/section/title/status/goal/tier/spec/inspired_by/depends_on/sections) toparseData—plan-section-loader.ts:67-83(shipped). - Verify
content.config.ts:67-83planSectionsschema needed NO 6-field sidecar-ref extension: the existing schema already validates the resolved object;body_ref/mission_refare never surfaced to Zod. The original schema-extension step is superseded by resolve-before-validate.
Out of scope — owned downstream
- The full
plan.json-only cutover (removing the.mdfallback once every rendered plan is JSON-native, and convertingindex.mdto JSON-native) is NOT part of this plan’s deliverable. It is owned by the live v7scripts-first-workflow-architecturenodecontent/website-repo-migration--s-6ccb6456.md§10, gated on §35.9. Declared via the00-overview.mdreferences:pointer, not adepends_on:edge (this plan has no executable section the DAG would gate on §35.9).
Review record
- Deliverable shipped + build-verified in
website_repocommit3e3ef60(astro syncexit 0 across all 24 plans per the commit body); website_repo edits were user-approval-gated (full approval granted 2026-05-24 for the website cutover). No open findings.