Skip to content

scaffold: deliver framework files (protocol.md, templates, workflow-ref) via resolver-aware channels (fresh-install class fix) #1011

Description

@amrmelsayed

Class fix for the fresh-install bug discussed in #738. Spec 618 correctly moved framework files into the package skeleton (resolver tier 4). The resolver works. The bug is consumer-side: prompts, role docs, and protocol docs reference framework files (protocol.md, templates, workflow-reference) by literal path, which bypasses the resolver and fails when the file lives only in the embedded skeleton. This issue covers the whole class of framework-file references reachable from builder-side consumers; the project-bootstrap gap (codev/resources/ not created on init) is tracked separately as #1012. The strategic question in #738 (whether to restore framework file copying broadly) stays separate.

Bug class

In fresh post-Spec-618 installs, any framework-provided file referenced by literal path from a builder-side consumer fails. Three sub-instances observed in current main:

A.1 — Protocol meta-doc references (9 builder-prompts + 1 role file). Every protocol's builder-prompt.md instructs the builder to read codev/protocols/<name>/protocol.md:

codev-skeleton/protocols/air/builder-prompt.md:27
codev-skeleton/protocols/aspir/builder-prompt.md:30
codev-skeleton/protocols/bugfix/builder-prompt.md:28
codev-skeleton/protocols/experiment/builder-prompt.md:27
codev-skeleton/protocols/maintain/builder-prompt.md:26
codev-skeleton/protocols/pir/builder-prompt.md:30, :90
codev-skeleton/protocols/research/builder-prompt.md:27
codev-skeleton/protocols/spike/builder-prompt.md:14
codev-skeleton/protocols/spir/builder-prompt.md:30
codev-skeleton/roles/builder.md:83 (literal `cat codev/protocols/spir/protocol.md`)

A.2 — Template file references in phase prompts and protocol docs. Templates live in <skeleton>/protocols/<name>/templates/*.md and are referenced during phase work:

codev-skeleton/protocols/spir/prompts/plan.md:79
Use the plan template from `codev/protocols/spir/templates/plan.md` if available.
codev-skeleton/protocols/aspir/prompts/plan.md:79
Use the plan template from `codev/protocols/spir/templates/plan.md` if available.
codev-skeleton/protocols/experiment/protocol.md:40
cp codev/protocols/experiment/templates/notes.md notes.md
codev-skeleton/protocols/spike/protocol.md:55
Use the template: `codev/protocols/spike/templates/findings.md`

A.3 — Workflow-reference doc, referenced from inside protocol.md. When protocol.md is delivered to the builder (after A.1 is fixed), it carries a "See workflow-reference.md for stage diagrams" pointer that itself bypasses the resolver:

codev-skeleton/protocols/spir/protocol.md:7
> **Quick Reference**: See `codev/resources/workflow-reference.md` for stage diagrams and common commands.

The roles/architect.md:5 reference to the same file is the architect-side consumer (a different surface from this issue's builder scope) and stays out of scope here.

Verified in current main:

  • packages/codev/src/lib/skeleton.ts:63 (resolveCodevFile) reaches the embedded skeleton correctly. The bug is purely on the consumer side, not in the resolver itself.
  • packages/codev/src/agent-farm/commands/spawn-roles.ts:99-108 (loadBuilderPromptTemplate) loads builder-prompt.md via the resolver but does not include framework-file content in the returned template.
  • packages/codev/src/commands/porch/prompts.ts:77-82 (loadPromptFile) loads per-phase prompts via the resolver and returns them to the builder via porch next JSON. Phase prompts work; the framework-file references inside those phase prompts don't.

Sample

Image

Fix

Three components organized in layers. Together they eliminate the bug class entirely under the no-copy constraint.

Layer 1 — Delivery: inline framework content into AI channels

The builder is the only concrete consumer with high-frequency framework-file needs. Make sure it receives content via the channels that already work (spawn-time prompt, porch JSON), never via literal-path shell reads.

Patch 1 — Spawn-time inline (covers A.1). Extend loadBuilderPromptTemplate() in packages/codev/src/agent-farm/commands/spawn-roles.ts:

functionloadBuilderPromptTemplate(config,protocolName){consttemplatePath=resolveCodevFile(`protocols/${protocolName}/builder-prompt.md`,config.workspaceRoot,);if(!templatePath)returnnull;lettemplate=readFileSync(templatePath,'utf-8');// Inline protocol.md so the builder doesn't have to fetch it.constprotocolDocPath=resolveCodevFile(`protocols/${protocolName}/protocol.md`,config.workspaceRoot,);if(protocolDocPath){template+=`\n\n---\n\n## Protocol Reference (full text)\n\n`+readFileSync(protocolDocPath,'utf-8');}returntemplate;}

~15 LOC. The builder receives protocol.md once in its initial prompt — never re-shipped, no shell command. Covers all 9 builder-prompts and the roles/builder.md:83 cat reference (the builder has the content when it would have tried to cat).

Patch 2 — Per-phase template inline (covers A.2). Two options, plan-gate decides:

  • A — Extend loadPromptFile() in packages/codev/src/commands/porch/prompts.ts to scan loaded prompt content for codev/protocols/<name>/templates/<file> references, resolve each, and inline under a ## Template heading. ~25 LOC code.
  • B — Edit the four affected prompts to embed template content directly. ~40-100 LOC markdown, 0 LOC code.

Either way the builder receives the template content via porch's existing per-phase JSON — no resolver bypass.

Layer 2 — Cleanup: sweep redundant literal-path references from the skeleton

With Layer 1 delivering content, the literal-path instructions in the skeleton are redundant (and a regression risk — the builder might still try them). Remove or rewrite them:

  • Builder-prompts: drop the Follow the <X> protocol: \codev/protocols//protocol.md`` line in all 9 files. The protocol meta-doc is already in the builder's context via Patch 1.
  • roles/builder.md: replace the cat codev/protocols/spir/protocol.md example with reference to the inlined content (or remove the example entirely).
  • Phase prompts referencing templates (if Patch 2 = Option A): rewrite to drop the literal-path reference since auto-detection handles it. If Patch 2 = Option B: literal paths are gone from these prompts by construction.
  • A.3 (workflow-reference.md inside spir/protocol.md:7): plan-gate decides:
    • 1 Recursively inline workflow-reference.md alongside protocol.md (small extension of Patch 1).
    • 2 Strip the "See workflow-reference.md" pointer (informational chrome, not load-bearing).
    • 3 Accept graceful degradation (low impact, but leaves a known fail-source).

Layer 3 — Enforcement: convention docs + doctor audit

The fix only stays fixed if future contributors don't reintroduce literal-path references. Two enforcement steps:

  • AGENTS.md / CLAUDE.md addition: a short section in the contributor guidance: "Framework files (protocols, roles, resources) live in the package skeleton, not in user projects. Never reference them by literal codev/... path in any prompt, doc, or instruction. Content is delivered to builders via the spawn prompt (for protocol.md) and porch JSON (for per-phase prompts and templates)."
  • codev doctor audit check: grep the skeleton (and any local codev/protocols/, codev/roles/, codev/resources/ directories) for cat codev/(protocols|roles|resources)/ and backtick-wrapped literal paths to framework files. Warn on hits with a pointer to the convention doc. ~30 LOC, same pattern as existing doctor checks.

Why these patches, not the rejected alternatives

AlternativeRejected because
Restore framework file copying on init/updateReverses Spec 618; "single source of truth, straightforward updates" is the load-bearing reason to maintain the no-copy model; humans-need-files-locally rationale is mostly speculative
Add codev read <path> CLI for shell consumersSpeculative infrastructure. Every concrete consumer is either served by inlining (builders / AI agents) or not actually helped by a CLI (IDE search, @-mention in chat tools, both bypass shell entirely). No named real consumer that the CLI uniquely serves. Add only if a real shell consumer surfaces.
Inject framework files on every porch next responseWasteful — meta-doc and templates don't change phase-to-phase; redundant re-delivery wastes context budget
Drop literal-path instructions WITHOUT inliningPer-protocol audit cost; per-phase prompts vary in self-containment (PIR may be fine without protocol.md, SPIR likely isn't). Combined WITH inlining (this proposal's Layer 1) it's safe; alone it's not.

Acceptance criteria

  • loadBuilderPromptTemplate() inlines protocol.md content into the returned spawn template when present, under a clear delimiter heading. Covers all 9 protocols uniformly.
  • Phase-prompt delivery (via porch) inlines referenced templates so the builder receives template content without a filesystem cat. Mechanism (auto-detect vs explicit-embed) decided at plan-gate.
  • Skeleton swept: literal-path framework-file references removed from all builder-prompts, roles/builder.md, phase prompts that reference templates (per Patch 2 choice), and A.3 reference (per chosen disposition).
  • AGENTS.md / CLAUDE.md updated with the no-literal-path convention statement.
  • codev doctor audit check added; greps for literal-path framework references and warns with a pointer to the convention.
  • When a framework file does not resolve, consumers proceed without inlining and without error.
  • Existing unit tests updated; new tests added for the per-phase template inline path and for the doctor audit.
  • Manual verification in a fresh codev init test project: the builder's initial prompt contains the protocol meta-doc; per-phase prompts contain referenced templates; no file-hunting visible across the full plan + implement + review cycle.

Out of scope

Suggested protocol

PIR. The fix is mechanically small (Layer 1 ~30 LOC code, Layer 2 ~50-100 LOC skeleton edits, Layer 3 ~50 LOC code + docs), but applies to every builder spawn and every per-phase prompt across every protocol, and the plan-gate has real decisions to lock before code:

  • Heading / delimiter format for inlined sections (## Protocol Reference, ## Template) so per-phase prompts and inlined content don't blur in the builder's context.
  • Patch 2 mechanism: auto-detect template references and inline at load time (Option A), or explicit-embed at edit time (Option B).
  • A.3 disposition: recursive inline / strip the reference / accept graceful degradation.
  • Behavior when a framework file does not resolve (warn vs silently skip; current default is silently skip; worth a conscious decision).
  • Doctor check semantics: warn vs error on literal-path findings; whether to also check user-customized codev/ directories or skeleton only.

The dev-approval gate is load-bearing. The change has to be tested in a running builder in a fresh codev init test project to confirm:

  • The inlined content actually stops the file-hunting behavior.
  • It doesn't introduce new confusion (the builder ignoring per-phase prompts because the inlined material is louder in its context).
  • Per-phase templates land correctly in the right phase prompts.
  • The doctor audit catches a deliberately-introduced literal-path reference (negative test).

PR-diff review alone won't catch these.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/scaffoldArea: Install path — codev init/adopt/update/doctor, codev-skeleton, four-tier resolver

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions