Implementation Plan

Embed a machine-readable markdown digest in every HTML plan

completed
2026-06-10 agentics feature

Ship a machine-readable markdown digest inside every HTML plan — a non-rendering <script type="text/markdown" id="plan-digest"> block as the first element child of <body> — so the implementer, the workflow author, and the 5–7 review-team agents read ~3.7k tokens of spec instead of re-reading ~21k tokens of styled HTML, with zero second source-of-truth file.

Implement Read and implement all steps in the plan at docs/plans/embed-markdown-digest-in-html-plans.html — Embed a markdown digest in every HTML plan for cheap reads
Run as workflow — launch parallel subagents
Run a workflow to implement the plan at docs/plans/embed-markdown-digest-in-html-plans.html — Embed a markdown digest in every HTML plan for cheap downstream reads
File embed-markdown-digest-in-html-plans.html
Path docs/plans/embed-markdown-digest-in-html-plans.html
Acceptance criteria 0 / 10 done

Context

A generated HTML plan is a single self-contained file of ~86–97 KB (~21.5k tokens), but only about 17% of that is plan content — the other ~83% is the fixed skeleton CSS and JS, byte-for-byte identical in every plan. The Read tool cannot skip <style> or <script> blocks, so every consumer that opens a plan pays for the whole file.

That cost is paid repeatedly. The implementer reads it; a Run a workflow… author reads it; and a single review-plan cycle has the lead plus up to 7 reviewer agents each instructed to read the plan — roughly ~170k tokens per review, of which ~140k is the same CSS read eight times. review-plan already says "exclude <style> and <script>" but the Read tool can't honor that — it's aspiration, not mechanism.

This plan embeds a spec-only markdown digest inside the plan rather than writing a sibling .md file. A sibling file is a second source of truth that drifts the moment implementation flips checkboxes or review-plan edits content, and it collides with the plan-interview .md tooling. An embedded <script type="text/markdown"> block keeps the single-file guarantee, never renders, and is extractable in any session — no plugin install required — via a flag-and-exit awk: awk '/<script[^>]*id="plan-digest"/{f=1;next} f&&/<\/script>/{exit} f' <file> (a simple awk range would re-trigger on later mentions of the id, as this very plan demonstrates).

Resolved decisions (from clarification): the block is the first element child of <body> (extracted with awk); the digest is spec-only so status flips and checkbox ticks never invalidate it; this plan backfills the ~50 existing plans via an idempotent script; and the 7 reviewers read the digest only while the lead keeps full HTML for its selector-based edits.

Files to Modify

agentics/
  • .claude-plugin/
    • marketplace.json modified bump plan-agent 2.1.0 → 2.2.0
  • kit/plugins/plan-agent/
    • CHANGELOG.md modified add 2.2.0 entry
    • README.md modified document the digest + extraction
    • agents/
      • plan-reviewer-*.md modified 7 defs read the digest, not full HTML
    • skills/implementation-plan/
      • SKILL.md modified contract, generation, refresh, prompts; includes buildImplementPrompt() instruction update
      • reference/SKELETON.html modified add #plan-digest block (first element child of body)
    • skills/review-plan/
      • SKILL.md modified digest-only reviewers, Step 7 refresh
      • references/role-prompts.md modified 7 briefs read the digest
  • scripts/
    • backfill-plan-digests.mjs new idempotent injector over existing plans
  • tests/plugins/
    • test-plan-digest.sh new objective smoke test
    • test-backfill-digest.mjs new backfill unit + integration

Diagram

Digest lifecycle
Generate
plan-agent drafts the spec
objective, steps, tests, criteria
Embed
fill #plan-digest
first element child of <body>, never renders
Extract
awk on the consumer side
~3.7k tokens of spec, any session
Refresh
on any spec edit
Step 8 edit loop · review-plan Step 7
Tokens to read one plan

Steps

1
todo Add the #plan-digest block to SKELETON.html as the first element child of <body>
Every generated plan inherits structure from the skeleton, so the block must live there once. Place it immediately after <body> (before the icon sprite) as <script type="text/markdown" id="plan-digest">{plan-digest}</script> — a non-executable script type the browser never renders or fetches, preserving the no-CDN, single-file guarantee. Add a guiding HTML comment above it documenting the spec-only rule and the flag-and-exit awk extraction — the comment is a comment node, not an element, so the script remains the first element child of <body> (the property the smoke test asserts, mirroring DOM firstElementChild semantics).
Verify
grep -n 'id="plan-digest"' SKELETON.html shows the block within the first lines after <body>; open the skeleton in a browser and confirm the block produces no visible output and no console error. Also confirm the placeholder token used (e.g. {plan-digest}) is documented in a comment or in implementation-plan/SKILL.md Step 2 so the generator knows exactly what string to replace when filling the block.
2
todo Define the digest content + escaping contract in implementation-plan/SKILL.md
A precise, stable contract is what lets the generator, every consumer, and the backfill script agree on shape. Specify the digest as the authored spec only — title, objective, context, file list, steps (action/why/verify), tests, acceptance-criteria text, verification — and explicitly exclude live state (status, checkbox states, completion report, copy buttons, CSS/JS). Insert markdown raw (not HTML-escaped); the only guard is to replace any literal closing-script sequence with a backslashed form (<\/script) so it cannot terminate the block early. Define the canonical extractor as the flag-and-exit awk '/<script[^>]*id="plan-digest"/{f=1;next} f&&/<\/script>/{exit} f' — a simple awk range re-triggers on any later line that mentions the id, so it must not be the documented form.
Verify
Re-read SKILL.md; the new subsection enumerates the included fields, the excluded live-state fields, the "raw markdown, not HTML-escaped" rule, and the <\/script guard.
3
todo Wire digest generation + content-edit refresh into the generation workflow
In SKILL.md Step 2, after the sections are drafted, build {plan-digest} from the final content and fill the skeleton placeholder. Add a rule to HTML Output Requirements: any later Edit that changes spec content (Step 5b interview findings, the Step 8 "Edit the plan" loop) must regenerate the block in the same pass; status flips (Step 6) and acceptance-criteria checks must not touch it. This keeps the digest authoritative without coupling it to progress churn. The digest carries no checksum or timestamp — staleness is prevented by this refresh rule plus the CI guard in Next Steps, not by an integrity field.
Verify
SKILL.md Step 2 and HTML Output Requirements name the digest fill and the refresh-on-content-edit rule; Step 6 and the acceptance-criteria gate explicitly state they do not regenerate the digest. Generate a throwaway plan and confirm the digest matches the visible spec.
4
todo Add the digest-extraction clause to the implement & workflow prompts
The implementer and the workflow author are the primary beneficiaries — they start in a fresh session with no context. Update the {implement-prompt}/{workflow-prompt} templates and the buildImplementPrompt() instruction list to direct the consumer to start from the digest, e.g. append: "Start from the markdown spec in the #plan-digest block (extract: awk '/<script[^>]*id="plan-digest"/{f=1;next} f&&/<\/script>/{exit} f' <file>) before opening the full HTML."
Verify
Generate a sample plan; both the implement <code> row and the workflow prompt carry the extraction one-liner, and the copied prompt from buildImplementPrompt() includes the "start from the digest" instruction.
5
todo Switch the 7 review-plan reviewers to digest-only reads
This is the largest token win (~120k per review cycle) and reviewers only emit prose findings, so they never need the DOM. In references/role-prompts.md, change every "Read the implementation plan at <ABSOLUTE_PATH>" to extract and read the #plan-digest block; mirror the change in all 7 individual agents/plan-reviewer-*.md defs (plan-reviewer-architecture.md, plan-reviewer-completeness.md, plan-reviewer-testability.md, plan-reviewer-risk.md, plan-reviewer-conventions.md, plan-reviewer-ux.md, plan-reviewer-accessibility.md) that say "Read the plan's full content." In review-plan/SKILL.md Step 4, state the split: reviewers get the digest, the lead reads full HTML for Step 7 selector edits. When a plan has no digest yet (e.g. an old plan not backfilled), reviewers fall back to reading the full HTML for that run so reviews never break.
Verify
grep -L plan-digest kit/plugins/plan-agent/agents/plan-reviewer-*.md returns nothing (all 7 defs updated); role-prompts.md references the digest for all 7 roles plus the no-digest full-HTML fallback; SKILL.md Step 4 documents the lead-vs-reviewer read split.
6
todo Add a digest-refresh pass to review-plan Step 7
Step 7 mutates spec content by CSS selector (Pass 1 inline edits), which makes the embedded digest stale for the next consumer. Add a "Pass 3 — refresh the digest": after the inline edits and the review-append, regenerate the #plan-digest block from the now-updated plan content. Skip it when output mode is "review only" (no content was changed).
Verify
review-plan/SKILL.md Step 7 lists Pass 3; a dry walk-through confirms it runs only after Pass 1 applied edits in "update plan in place" mode and is skipped in "review only".
7
todo Create the backfill injector scripts/backfill-plan-digests.mjs
The chosen scope backfills the ~50 existing plans. Write an idempotent Node script (matching the repo's existing scripts/*.mjs convention) that scans docs/plans/*.html (skipping index.html and any file already containing #plan-digest), parses title/objective/files/steps/tests/criteria/verification from the stable skeleton structure (IDs/classes: #objective, .step-card, #tests, #criteria-list, #verification, .file-tree), builds the digest (with the <\/script guard), and inserts it as the first element child of <body>. It must never touch status, checkboxes, or progress state, must only inject when all expected sections parse — skipping and reporting any plan it cannot fully parse rather than writing a partial digest — and must support --dry-run, printing injected / skipped / failed counts.
Verify
node scripts/backfill-plan-digests.mjs --dry-run reports counts with zero failures; a real run injects digests; a second real run injects 0 (all skipped). Plans that cannot be fully parsed are listed as skipped, not partially injected; git diff on a completed plan shows only the added digest block, no status/checkbox changes.
8
todo Bump version, changelog, and README (plan-agent 2.1.0 → 2.2.0)
Adding new behavior is a minor bump per the project versioning rules, and CLAUDE.md requires docs/changelog updates with any plugin change — the new value must be higher than main's, and 2.1.0 was taken on main by the findings-walkthrough feature. Set plan-agent version to 2.2.0 in marketplace.json, add a 2.2.0 CHANGELOG.md entry describing the digest + backfill, and add a "Machine-readable digest" subsection to the plugin README.md showing the awk extraction one-liner.
Verify
marketplace.json shows plan-agent at 2.2.0 (and the .claude/settings.json JSON-validation hook passes); CHANGELOG.md top entry is 2.2.0; the README has the digest subsection with the extraction command.

Tests

Tier 1 — Code-touching plan
Objective Every generated plan carries an extractable, accurate digest

File: tests/plugins/test-plan-digest.sh

Type: smoke test (shell, matching the repo's tests/<area>/*.sh convention)

Asserts: (1) SKELETON.html wraps the {plan-digest} placeholder in a <script type="text/markdown" id="plan-digest"> that is the first element child of <body> (comment nodes before it are allowed — match the first tag after <body>, skipping comments); (2) running the awk extractor against a committed fixture plan returns non-empty markdown containing the fixture's objective and at least one step action; (3) review-plan role-prompts.md and all 7 agents/plan-reviewer-*.md files reference plan-digest and the no-digest full-HTML fallback.

Run: bash tests/plugins/test-plan-digest.sh

Unit Backfill pure functions

File: tests/plugins/test-backfill-digest.mjs

Targets: buildDigest(), hasDigest(), extractSections() exported from scripts/backfill-plan-digests.mjs

Key cases: extractSections() pulls objective/steps/criteria from a sample plan string; buildDigest() emits the spec fields and applies the <\/script guard; hasDigest() is true for a plan already containing the block and false otherwise.

Integration Backfill over a temp copy of docs/plans

File: tests/plugins/test-backfill-digest.mjs

Targets: the backfill-plan-digests.mjs CLI end-to-end against a throwaway temp directory

Key cases: a todo, an in-progress, and a completed fixture plan each gain a digest; a pre-seeded plan is skipped (idempotency); a plan missing a parseable section is skipped and listed (no partial digest); the bytes of data-status, <meta name="plan-status">, and every acceptance-criteria checkbox are byte-identical before and after; a fixture plan whose content contains the literal string </script in a code block is injected and the guard fires correctly (closing tag does not terminate the digest block early).

Integration Digest refresh after review-plan Step 7 edits

File: tests/plugins/test-plan-digest.sh

Targets: the digest-refresh pass (Pass 3) in review-plan/SKILL.md Step 7

Key cases: after a spec-content edit is applied to a fixture plan via review-plan update-in-place mode, the #plan-digest block reflects the updated content; in "review only" mode, the digest is unchanged; status/checkbox bytes are unaffected by either mode.

Integration No-digest fallback in review-plan

File: tests/plugins/test-plan-digest.sh

Targets: reviewer fallback path in review-plan/SKILL.md Step 4 and each agents/plan-reviewer-*.md

Key cases: when a plan has no #plan-digest block, the reviewer defs and role-prompts instruct fallback to full HTML; the smoke test asserts that every agents/plan-reviewer-*.md file contains both the digest-extraction clause and the fallback clause.

Acceptance Criteria

Verification

Generation path: run /plan-agent:implementation-plan on a throwaway objective and confirm the resulting plan has a #plan-digest block as the first element child of <body>, that its markdown matches the visible objective/steps/criteria/verification, that the block renders nothing in a browser, and that the canonical flag-and-exit awk extractor returns the spec. Confirm both the implement and workflow prompts carry the extraction clause.

Backfill path: run node scripts/backfill-plan-digests.mjs --dry-run then a real run over docs/plans/; spot-check one completed, one in-progress, and one todo plan — each must gain a digest while git diff shows no change to data-status, <meta name="plan-status">, or any criteria checkbox. Re-run and confirm 0 injected.

Review path: run review-plan on a sample plan; confirm each reviewer was briefed with the digest (not full HTML), that a digest-less plan falls back to full HTML, and that Step 7 regenerated the digest after applying inline edits.

Tests: bash tests/plugins/test-plan-digest.sh and node tests/plugins/test-backfill-digest.mjs both exit 0.

Completion Checklist

Required

Completion Report

Version criterion — planned 2.2.0, shipped 2.3.0
PR #317 (markdown plan conversion) took 2.2.0 on main while this plan was in flight. The criterion's intent — bump plan-agent above the value on main with a matching CHANGELOG entry — is met at 2.3.0.

Next Steps

Add a CI guard so new plans must ship a digest

Paste this prompt into Claude to execute this follow-up:

Add a CI check to the agentics repo that fails a PR when any added or modified file under docs/plans/ ending in .html (excluding index.html) does not contain a `<script type="text/markdown" id="plan-digest">` block as the first element child of <body> (skip comment nodes when checking). Implement it as a small Node script under scripts/ plus a step in the existing GitHub Actions workflow, mirroring the style of scripts/merge-marketplace.mjs and the tests/ shell smoke tests. Skip plans whose frontmatter meta plan-status is "completed" only if they predate the digest feature; otherwise require the block. Report the files you changed.
Slice the digest per-step for workflow subagents

Paste this prompt into Claude to execute this follow-up:

In kit/plugins/plan-agent/skills/implementation-plan/SKILL.md, update the generated workflow prompt so that when a plan is implemented via /workflows, the orchestrator passes each subagent only its relevant slice of the #plan-digest markdown (the specific step plus shared objective/verification context) instead of having every workflow agent re-read the whole plan file. Define how the workflow script extracts and partitions the digest by step heading, and document the token rationale. Do not change the single-session implement path. Report the SKILL.md sections you edited.
Teach the plan-interview markdown tooling about the digest

Paste this prompt into Claude to execute this follow-up:

The plan-interview plugin's markdown-to-html and plan-status skills operate on .md plan files. Update them to be digest-aware: when markdown-to-html converts a plan to HTML, emit a #plan-digest block as the first element child of <body> using the same spec-only contract defined in plan-agent's implementation-plan SKILL.md; and when plan-status reads a plan, prefer the digest for status-independent spec inspection. Keep the two contracts in sync by referencing plan-agent's definition rather than duplicating it. Report which skills you changed and any contract divergences you had to resolve.
Wish List
A /plan-agent:plan-digest utility command Wish List

Speculative / blue-sky idea — not on the critical path. Paste into Claude when ready to explore:

Design a command-only skill /plan-agent:plan-digest <file> that prints the #plan-digest markdown for any HTML plan to stdout (extracting it with the canonical awk one-liner), and, when the block is missing, falls back to generating an ephemeral digest from the plan's live DOM structure without writing to the file. Cover path-safety (basename resolution under the plans roots), a --raw flag to keep the script wrapper, and a clear error when the file is not a plan. Provide the SKILL.md and an allowed-tools line.
Unresolved Questions
  • Do digest-only reviewers lose the ability to flag rendering / DOM-structure defects?
    In the agentics plan-agent review-plan skill, the 7 reviewer teammates now read only the #plan-digest markdown, not the full HTML. Assess whether any reviewer role (especially architecture, conventions, or accessibility/UX) needs full-HTML access to catch defects the spec-only digest cannot express — e.g. malformed markup, broken copy buttons, missing nav links, or contrast issues. Recommend either (a) keep all 7 digest-only, (b) give a named subset on-demand full-HTML access, or (c) add a single lead-side structural lint pass. Justify with concrete examples of defects each option would catch or miss.
Team Review (2026-06-10 22:54:34 UTC)

Executive Summary: The plan is well-scoped, technically sound, and addresses a genuine token-cost problem with a clean embedded-digest approach. The architecture is defensible — single-file guarantee, no sibling drift, awk-extractable without plugins. The main gaps are: (1) the 7 reviewer agent defs are listed as a glob rather than enumerated names, risking one being missed; (2) three test paths are absent — digest-refresh after Step 7 edits, no-digest fallback behavior, and the </script escape edge case; (3) the {plan-digest} placeholder substitution contract is not fully specified in Step 1; (4) buildImplementPrompt() has no explicit file path in the Files section. All have been addressed inline.

Architecture: Fit is strong. The single-file embedding via <script type="text/markdown"> is the correct pattern — no CDN, no second source-of-truth, browser-silent. The lead/reviewer read split is well-reasoned. One medium concern: the digest contract is partially duplicated across implementation-plan/SKILL.md, review-plan/SKILL.md, role-prompts.md, 7 agent defs, and the backfill script. A future contract change requires coordinated edits in all five locations — worth noting in an Unresolved Question or a Next Step for contract centralization.

Completeness: Steps are specific with action/why/verify triples. Key gap addressed: Step 5 now enumerates all 7 reviewer filenames rather than using a glob. The Files section now notes buildImplementPrompt() is inside implementation-plan/SKILL.md. Step 1 verify now references the placeholder substitution contract.

Testability: The existing smoke + unit + integration tests are solid for the generation and backfill paths. Three missing test cases added: (a) digest refresh after review-plan Step 7 inline edits; (b) no-digest fallback path; (c) </script escape edge case in the backfill integration test.

Risk: Highest risk is the backfill over ~50 existing plans. The "only inject when all sections parse" + dry-run + skip-and-report design is sound mitigation. The </script guard is documented but was untested — now covered. The prose-only enforcement of "status flips must not touch the digest" is a medium-term drift risk; the deferred CI guard (Next Steps) is the correct long-term fix.

Conventions: File naming and script placement follow project conventions. One medium issue: the {plan-digest} placeholder was not explicitly documented as the replacement token — Step 1 verify now calls this out. The 7 reviewer files listed as plan-reviewer-*.md glob is now enumerated explicitly in Step 5.

Highest-Risk Issues (resolved inline):

  1. (High) 7 agent defs listed as glob — now enumerated in Step 5 with all 7 filenames.
  2. (High) No test for </script escape edge case — added to backfill integration test.
  3. (Medium) No test for digest-refresh path after Step 7 edits — added as new integration test card.
  4. (Medium) No test for no-digest fallback — added as new integration test card.
  5. (Medium) buildImplementPrompt() missing from Files section — noted in SKILL.md file entry.
  6. (Medium) {plan-digest} placeholder contract not specified in Step 1 verify — added.