Skip to content

[PIR #1011] Deliver framework files via resolver-aware channels (fresh-install class fix)#1015

Draft
amrmelsayed wants to merge 19 commits into
mainfrom
builder/pir-1011
Draft

[PIR #1011] Deliver framework files via resolver-aware channels (fresh-install class fix)#1015
amrmelsayed wants to merge 19 commits into
mainfrom
builder/pir-1011

Conversation

@amrmelsayed

@amrmelsayed amrmelsayed commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Draft for team feedback. Opened mid-PIR (at the dev-approval gate) to get eyes on the design before it's finalized. The formal review-phase flow (review file, 3-way consult, pr gate) still follows; this PR will be reused, not replaced.

Fixes #1011.
Fixes #1013.

Problem

Post-Spec-618, framework files (protocol docs, role docs, templates, resources) live only in the package skeleton and resolve via the four-tier resolver. But various builder-side consumers referenced them by literal codev/... path (cat/cp, "read this file"), which bypasses the resolver and fails in fresh installs — builders waste turns hunting for files that aren't on disk. #1011 is the class fix.

Approach — three layers

Layer 1 — Delivery (fresh-at-spawn, no committed copy).
buildPromptFromTemplate fills a {{protocol_reference}} placeholder by reading protocol.md fresh through the resolver at spawn, and resolves {{> path}} include directives inside it (for protocol templates). Nothing is committed into the prompts, so nothing can go stale. The reference is unconditional — every shipped protocol ships a protocol.md (a unit test enforces that), so no {{#if}} guard is needed.

Layer 2 — Cleanup (sweep).
Removed the literal protocol.md pointer from all 9 builder-prompts (restoring "Read and internalize the protocol…"), fixed the cat codev/protocols/... example in roles/builder.md, dropped the redundant plan-template pointers in spir/aspir plan prompts (those prompts already carry a self-contained ### Plan Structure), and stripped the workflow-reference.md pointer from spir/protocol.md.

Layer 3 — Enforcement.
A scoped convention note in CLAUDE.md / AGENTS.md (don't shell-cat/cp framework files in builder-facing prompts) plus a narrow codev doctor audit (lib/framework-ref-audit.ts) that flags only shell-fetch verbs reading codev/(protocols|roles)/..., warn-not-error. codev doctor is an end-user tool, so it scans the project's local codev/ overrides (what the user controls); the shipped skeleton is guarded separately by the framework's own CI (a unit test scanning codev-skeleton/).

Also includes #1013 (folded in — doc hygiene with a correctness edge)

Because Layer 1 now reliably inlines protocol.md into builders, stale/duplicated protocol-doc content stops being cosmetic and starts reaching agents' context. So this PR also:

  • Rewrites bugfix/protocol.md from a stale 548-line manual-flow doc (manual "send architect 'Merge it'" merge, manual architect CMAP, deprecated projectlist section) to a concise ~78-line porch-accurate doc grounded in the real flow (protocol.json phases + the pr gate; prompts/{investigate,fix,pr}.md), and ships it to the skeleton (it was absent), so fresh-install bugfix builders get a correct meta-doc consistent with every other protocol.
  • Removes experiment/protocol.md's ## notes.md Template partial copy (a relative-ref duplicate of notes.md); the fresh {{> }} include already delivers the canonical template.

Unused framework files (kept for reference, not deleted)

These template files ship in the package but are not referenced by any builder-facing instruction — the relevant structure is documented inline in the protocol doc instead. They are intentionally kept for reference, not removed:

  • protocols/maintain/templates/maintenance-run.md (skeleton + codev/) — the maintenance run-file structure is documented inline in maintain/protocol.md; the template file is orphaned.
  • codev/protocols/maintain/templates/audit-report.md and codev/protocols/maintain/templates/lessons-learned.md (codev/ tree only) — not referenced by any maintain prompt.

No builder instruction points at these paths, so they don't affect fresh-install accuracy; this note just records that they are reference-only.

Open questions for reviewers

  1. Two delivery mechanisms. protocol.md is delivered via a context variable ({{protocol_reference}}, so the existing {{#if}} can conditionally show a "see below" reference and omit it cleanly for protocol-less protocols); templates use a {{> path}} include directive (new, resolved by resolveIncludes, modeled on Handlebars partials). The {{#if}}/{{var}} is existing codev template syntax; {{> }} is new surface. Is the two-mechanism split worth it, or collapse to one (lose the conditional reference, or use a non-Handlebars marker like <!-- include: ... -->)?
  2. Doctor scope. The audit deliberately flags only shell-fetch of framework files, not documentation references (the skeleton has ~60 legit codev/... mentions, incl. the documented protocol list in templates). It runs in codev doctor against the project's local codev/ overrides (end-user-controlled), warn-not-error; the shipped skeleton is guarded by a CI unit test instead. Right split?
  3. bugfix rewrite. I rewrote a long stale doc down to ~78 lines, grounded in protocol.json + the phase prompts. Worth a careful read that the porch-era flow (pr gate, CMAP, gate-driven merge) is described correctly.

Scope / tests

  • 46 files (+939/−619; the deletions are mostly the stale bugfix doc). Core code: packages/codev/src/agent-farm/commands/spawn-roles.ts, packages/codev/src/lib/framework-ref-audit.ts, packages/codev/src/commands/doctor.ts; the rest is skeleton/codev/ markdown + tests.
  • npm run build ✓, full suite ✓ (3271 passed, 13 pre-existing skips). New unit tests cover the placeholder fill, {{> }} include resolution, the doctor audit (positive + negative), and the skeleton sweep; updated the Spec 746 baselines + a bug: ASPIR builder-prompt references SPIR, spawn --task skips porch init, fragile phases check #619 assertion the sweep invalidated.
  • Verified end-to-end against the real skeleton: protocol.md inlines fresh, "Read and internalize" restored, {{> }} expands, zero handlebar residue.

…ctor audit)

- Layer 2: drop protocol.md pointer from all 9 builder-prompts; fix roles/builder.md
  cat example; strip A.3 workflow-reference line from spir/protocol.md (both trees)
- Patch 2 (A.2): drop redundant plan-template pointers (spir/aspir); embed notes.md /
  findings.md into experiment/spike protocol.md under drift-guarded sentinels (both trees)
- Layer 3: 'Framework files: never shell-fetch by literal path' convention in
  AGENTS.md + CLAUDE.md; lib/framework-ref-audit.ts + doctor() section (warn, skeleton-only)
- Tests: new framework-ref-audit + skeleton-sweep guards; update Spec 746 baselines and
  bugfix-619 assertion for the swept builder-prompts
Per dev-approval feedback, replace the static embed/append (stale duplicate) with
fresh-at-delivery placeholders:
- spawn-roles.ts: resolveIncludes() ({{> path}}, recursive) + resolveProtocolReference();
  buildPromptFromTemplate fills {{protocol_reference}} from protocol.md read fresh at spawn
- builder-prompts: restore 'Read and internalize...'; reference + {{protocol_reference}}
  placeholder under {{#if}} (bugfix renders cleanly with neither)
- experiment/spike protocol.md: {{> ...templates...}} include instead of committed copy
- tests: placeholder + include resolution; drift test asserts include-present/no-embed;
  re-sweep Spec 746 baselines to the new ## Protocol line
Per dev-approval feedback: the blanket 'never shell-fetch a framework file by
literal path' overreached (role docs can be tier-2 overridden into the workspace)
and was advisory-not-load-bearing (the doctor check is the mechanical guard).
Scope it to builder-facing prompts/role-docs, acknowledge the override, drop the
absolute framing.
…ent partial copy

#1011's Layer 1 now reliably inlines protocol.md into builders, so the stale bugfix
doc reaching builders is a correctness risk. Resolved here:
- bugfix/protocol.md: rewrite the stale 548-line manual-flow doc as a concise,
  porch-accurate ~78-line doc (merge gated by the pr gate, not a manual handshake;
  drop projectlist + manual architect CMAP; fix branch naming). Ship to the skeleton
  (was absent) so fresh-install bugfix builders get a correct meta-doc.
- experiment/protocol.md: remove the redundant '## notes.md Template' partial copy;
  the fresh {{> ...}} include already delivers it.

Fixes #1013.
The two '**Template**: templates/spec.md|plan.md' annotations and the '## Templates'
section pointed builders (via the inlined protocol.md) at template paths absent in
fresh installs. The spec/plan structure is delivered by the specify/plan phase
prompts; reword to point there and describe templates as skeleton-shipped reference,
not on-disk files to fetch. No builder behavior change.
experiment/spike default to mode:soft (no porch phase prompts) -> protocol.md is
their only guidance channel, which is why templates are injected into it (and why
strict protocols whose phase prompts carry structure are not). Documents the
strict-vs-soft distinction and retracts the unneeded 'give them phase prompts'
follow-up.
…ser scope)

codev doctor is an end-user tool; auditing the global package skeleton was
pointless (user can't fix it; CI already guarantees it clean). Scan the project's
local codev/protocols + codev/roles overrides instead (no-op when absent), inside
the in-a-project block. Shipped-skeleton guard stays in the framework-ref-audit
unit test (scans codev-skeleton/, runs in CI). Rename lib param skeletonDir->rootDir;
update CLAUDE/AGENTS convention line + plan decision #5.
….md completeness

All protocols now ship a protocol.md (bugfix got one in #1013), so the {{#if}}
guard was always-true / dead code. Make the protocol reference unconditional in
all 9 builder-prompts (both spots, both trees), and add a unit test enforcing that
every shipped skeleton protocol with a protocol.json also ships a protocol.md — so
the invariant is true-by-construction, not just currently-true. Update the
spawn-roles 'absent' test + mock template; re-sweep the Spec 746 baselines.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant