Make the visible plan DOM the single source of truth: derive the spec on demand with a shared scripts/extract-plan-spec.mjs extractor, and retire the embedded #plan-digest block plus its refresh and closing-script escaping machinery — while keeping the same self-contained HTML deliverable and the ~15× token savings for downstream consumers.
Read and implement all steps in the plan at docs/plans/replace-plan-digest-with-extractor.md — Replace the stored plan digest with a compute-on-read extractor. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/replace-plan-digest-with-extractor.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
More ways to run this plan — goal & workflow prompts, file path
Achieve this goal: Replace the stored plan digest with a compute-on-read extractor. The plan at docs/plans/replace-plan-digest-with-extractor.md describes one approach — use it as reference, but optimize for the outcome. Fan out across parallel subagents where that serves the outcome. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/replace-plan-digest-with-extractor.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
Run a workflow to implement the plan at docs/plans/replace-plan-digest-with-extractor.md — Replace the stored plan digest with a compute-on-read extractor. Brief subagents with the plan file at docs/plans/replace-plan-digest-with-extractor.md. Reserve a final verification phase for the lead agent, not a subagent. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/replace-plan-digest-with-extractor.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
replace-plan-digest-with-extractor.html
docs/plans/replace-plan-digest-with-extractor.html
docs/plans/replace-plan-digest-with-extractor.md
Context
The story behind this plan — what prompted the work and why it matters now.
Since plan-agent 2.3.0, every generated plan embeds a spec-only markdown digest — a <script type="text/markdown" id="plan-digest"> block — as the first element child of <body> . The digest is a denormalized cache of the plan spec, which already lives in the visible DOM ( .objective-card , .step-card with .step-action / .step-why / .verify-body , #criteria-list , #verification ).
Like any cache, that duplication creates an invalidation problem — and the codebase already pays for it: implementation-plan SKILL.md must "refresh the digest" on every content edit (Steps 2/6/8), review-plan adds a dedicated "Pass 1b — Refresh the digest", and a closing-script escaping contract guards the block. All of that machinery exists only because the spec is stored twice.
Compute-on-read removes the duplication: derive the spec from the DOM on demand. Crucially, scripts/backfill-plan-digests.mjs already exports hasDigest , decodeEntities , extractSections , and buildDigest — the exact HTML→markdown logic, already unit-tested — so this is mostly rewiring proven code, not writing a parser. New plans stop embedding the digest; the extractor reads an embedded digest first (old plans, verbatim) and derives from the DOM otherwise (new plans), so existing plans are never touched.
Files that change
Every file this plan touches, and what happens to each one.
scripts/lib/plan-spec.mjsnew shared parse fns (extractSections/buildDigest/guard+unguard)- scripts/
extract-plan-spec.mjsnew read-time spec extractor; imports scripts/lib/plan-spec.mjsbackfill-plan-digests.mjsmodified import shared fns from scripts/lib/plan-spec.mjs (behavior unchanged)
.claude-plugin/marketplace.jsonmodified bump plan-agent 2.7.0 → 2.8.0skills/implementation-plan/reference/SKELETON.htmlmodified remove digest block + placeholder; repoint buildImplementPrompt()skills/implementation-plan/SKILL.mdmodified drop digest section + refresh rules; prompts call extractorskills/review-plan/SKILL.mdmodified reviewers run extractor; remove refresh passskills/review-plan/references/role-prompts.mdmodified 7 reviewer briefs read via extractoragents/plan-reviewer-*.mdmodified 7 reviewer defs read via extractorREADME.mdmodified document the extractorCHANGELOG.mdmodified 2.8.0 entry- tests/plugins/
test-extract-plan-spec.mjsnew objective + unit coveragetest-extractor-wiring.shmodified renamed from test-plan-digest.sh; asserts no digest + wiringtest-goal-prompt.shmodified update any assertion on the old awk one-liner
Steps
The step-by-step work, in order — each step says what to do, why it matters, and how to check it worked.
Tests
The tests that prove the change does what it promises.
Definition of done
The plan counts as done when every statement below is true — check each one off as you verify it.
Final check
One last pass to confirm the whole change works end to end.
Generate a fresh plan with the modified skill and confirm it has no embedded digest, its implement prompt and the Copy-button output reference the extractor, and node scripts/extract-plan-spec.mjs on it emits correct DOM-derived spec. Run the extractor on an older plan (e.g. docs/plans/embed-markdown-digest-in-html-plans.html ) and confirm the output is the unguarded spec markdown (the embedded digest with <\/script reversed to </script ) — not byte-identical to awk, by design. Run node tests/plugins/test-extract-plan-spec.mjs , bash tests/plugins/test-extractor-wiring.sh , and node tests/plugins/test-backfill-digest.mjs — all must pass (the last with its corpus assertion scoped to legacy plans). Finally, grep -rn "plan-digest" across the plan-agent tree and confirm only intentional references remain: the retained backfill injector, the shared scripts/lib/plan-spec.mjs , the tests, and historical CHANGELOG entries.
Wrapping up
Three gates that must all pass before this plan is marked completed.
Completion Report
No items to report — all requirements met.