Skip to content

fix(generation): package long workflow context#59

Merged
khaliqgant merged 4 commits into
mainfrom
codex/package-generated-context
May 7, 2026
Merged

fix(generation): package long workflow context#59
khaliqgant merged 4 commits into
mainfrom
codex/package-generated-context

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

Summary

  • Materialize generated workflow context into sidecar files during prepare-context: normalized spec, acceptance contract, non-goals, deliverables, verification plan, lead-plan instructions, implementation instructions, and review checklist.
  • Shrink lead-plan, implementation, and review agent task prompts so agents read packaged context files instead of receiving the full spec inline.
  • Add regression coverage proving long spec sentinels stay out of agent task bodies while still being available in the generated context package.

Validation

  • npx vitest run src/product/generation/pipeline.test.ts
  • npm run typecheck
  • npm test

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR precomputes and writes a multi-file generated context package, updates renderSource to call a runtime writer, changes prepare-context to validate packaged files and emit readiness, rewires step renderers to read artifactsDir-based inputs (normalized spec, acceptance contract, instructions, checklists, optional target-context), and adds tests that ensure long specs are stored in sidecars not inlined into task bodies.

Changes

Context Packaging Refactor

Layer / File(s) Summary
Context File Model
src/product/generation/template-renderer.ts
Introduces GeneratedContextFile type and buildGeneratedContextPackage(...) to construct normalized spec, acceptance contract, non-goals, deliverables, verification plan, instruction/checklist markdowns, matched-skills, and optional target-context file.
Runtime Writer Helpers
src/product/generation/template-renderer.ts
Adds runtime helpers to render and invoke a generated-context writer that writes the packaged files into .workflow-artifacts/generated/<slug>/ before steps run.
Prepare-Context Step Validation
src/product/generation/template-renderer.ts
Refactors renderPrepareContextStep to validate expected files exist under artifactsDir and emit GENERATED_WORKFLOW_CONTEXT_READY (no longer synthesizes file contents).
Writer Injection in renderSource
src/product/generation/template-renderer.ts
renderSource computes context setup and injects a runtime writer call to materialize packaged context files prior to rendering the workflow step sequence.
Pipeline Wiring
src/product/generation/template-renderer.ts
Rewires renderSource to consistently pass artifactsDir into lead-plan, initial/final review steps, and delegates non-code secondary review to the shared review renderer using artifactsDir.
Step Prompt Updates
src/product/generation/template-renderer.ts
renderLeadPlanStep, renderImplementationStep, and renderReviewStep updated to instruct agents to read specific packaged files from artifactsDir instead of embedding spec/instructions inline.
Tests / Helpers
src/product/generation/pipeline.test.ts
Extends artifact scoping assertions; adds tests and helpers (renderedTaskBodies, renderedStepCommand, renderedStepCommands) to verify sentinel content is packaged into sidecars and absent from prepare-context commands and all rendered task: ...`` bodies; updates spec fixture to accept targetContext.

Sequence Diagram(s)

sequenceDiagram
  participant RS as renderSource
  participant Writer as ContextWriter
  participant ArtDir as artifactsDir
  participant Prepare as prepare-context
  participant Steps as workflow steps
  RS->>Writer: buildGeneratedContextPackage + write files to ArtDir
  Writer-->>ArtDir: files stored
  RS->>Prepare: emit prepare-context step (validate files)
  Prepare->>ArtDir: check expected files exist
  Steps->>ArtDir: read packaged files for lead/impl/review steps
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • AgentWorkforce/ricky#52: Modifies template-renderer lead-plan prompting and related generation tests; touches overlapping render pipeline paths.

Poem

🐰 I folded specs into tidy stacks,

sidecar notes for safe-packed facts.
Steps now fetch from artifact lanes,
tiny tasks where the big text remains.
Hop, review, and munch on those gains!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: packaging long workflow context into sidecar files instead of inlining into task bodies.
Description check ✅ Passed The description is directly related to the changeset, detailing the materialization of context files, shrinkage of prompts, and regression coverage added.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/package-generated-context

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/product/generation/pipeline.test.ts (1)

1378-1380: 💤 Low value

Minor fragility in regex if task bodies ever contain backticks.

The non-greedy regex /task:\s*([\s\S]*?)/g will terminate at the first backtick character, which would incorrectly truncate extraction if a task body contained escaped backticks (e.g., \foo``). Current task bodies don't include embedded backticks, so this works today.

💡 More robust alternative (optional)

If future task bodies might contain backticks, consider a state-machine approach or matching the templateLiteral escaping pattern:

 function renderedTaskBodies(content: string): string[] {
-  return [...content.matchAll(/task:\s*`([\s\S]*?)`/g)].map((match) => match[1]);
+  // Match task template literals, accounting for escaped backticks
+  return [...content.matchAll(/task:\s*`((?:[^`\\]|\\.)*)\\`/g)].map((match) => match[1].replace(/\\`/g, '`'));
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/pipeline.test.ts` around lines 1378 - 1380, The helper
renderedTaskBodies currently uses a regex that stops at the first backtick and
will break if a task body contains an escaped backtick; update
renderedTaskBodies to use a pattern that allows either a backslash-escaped
backtick or any non-backtick character repeated (i.e., match sequences of
"(escaped backtick) or (not backtick)" until the closing backtick) so the
capture includes embedded escaped backticks, or alternatively replace the regex
with a tiny template-literal parser/state-machine that walks the string and
honors backslash escapes when extracting the content after "task:".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/product/generation/pipeline.test.ts`:
- Around line 1378-1380: The helper renderedTaskBodies currently uses a regex
that stops at the first backtick and will break if a task body contains an
escaped backtick; update renderedTaskBodies to use a pattern that allows either
a backslash-escaped backtick or any non-backtick character repeated (i.e., match
sequences of "(escaped backtick) or (not backtick)" until the closing backtick)
so the capture includes embedded escaped backticks, or alternatively replace the
regex with a tiny template-literal parser/state-machine that walks the string
and honors backslash escapes when extracting the content after "task:".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ba7022c-841a-4640-80d9-7f684f4c8bcb

📥 Commits

Reviewing files that changed from the base of the PR and between 6601720 and ab5c6b9.

📒 Files selected for processing (2)
  • src/product/generation/pipeline.test.ts
  • src/product/generation/template-renderer.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab5c6b9040

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const commands = [
`mkdir -p ${shellQuote(artifactsDir)}`,
`printf '%s\\n' ${shellQuote(spec.description)} > ${shellQuote(`${artifactsDir}/normalized-spec.txt`)}`,
...contextPackage.map((file) => `printf '%s\\n' ${shellQuote(file.content)} > ${shellQuote(file.path)}`),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid embedding packaged context in one shell command

For very large specs, this still inlines the entire context package into the generated deterministic prepare-context command; that command has to be handed to the shell/runtime before any sidecar files can be written, so specs approaching the OS command-argument limit can fail in prepare-context instead of being packaged. The new package also duplicates the description into normalized-spec.txt, normalized-spec.md, and acceptance-contract.json, lowering that threshold; write these sidecars from generated TS/Node code or otherwise avoid putting the full package in the command string.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/product/generation/pipeline.test.ts (1)

1362-1365: ⚡ Quick win

Avoid hard-coding the current packaging mechanism in this regression.

The important contract here is that the long spec stays out of task bodies and the prepare-context command while the packaged files remain addressable. Requiring content to contain the sentinel and writeRickyGeneratedContextFiles([ will fail if we later materialize the sidecars earlier without changing the externally visible behavior. Prefer asserting the packaged file paths are referenced and the sentinel is absent from prompts/commands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/pipeline.test.ts` around lines 1362 - 1365, The test
currently hard-codes the packaging implementation by asserting presence of
longSpecSentinel and the writeRickyGeneratedContextFiles call; instead update
the assertions to verify only the externally visible contract: keep checks that
content references the packaged file paths
('.workflow-artifacts/generated/packaged-context/normalized-spec.md' and
'.workflow-artifacts/generated/packaged-context/acceptance-contract.json'),
remove the positive assertions for longSpecSentinel and
'writeRickyGeneratedContextFiles([', and add an assertion that longSpecSentinel
is absent from prompts/commands (e.g. ensure content does NOT contain
longSpecSentinel and that the 'prepare-context' command/task bodies do not
include the sentinel), leaving the test resilient to changes in how sidecars are
materialized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/product/generation/template-renderer.ts`:
- Around line 781-799: The lead and review read lists currently omit the actual
target context file; update renderLeadPlanStep and renderReviewStep to accept a
hasTargetContext boolean parameter, and when hasTargetContext is true append
`${artifactsDir}/target-context.txt` to the ordered "Read these files in order"
list inside the task template literal; ensure you update all call sites to pass
the new flag and keep the rest of the template (headings, output file, and end
marker) unchanged so both planner and reviewers see the real target context when
present.

---

Nitpick comments:
In `@src/product/generation/pipeline.test.ts`:
- Around line 1362-1365: The test currently hard-codes the packaging
implementation by asserting presence of longSpecSentinel and the
writeRickyGeneratedContextFiles call; instead update the assertions to verify
only the externally visible contract: keep checks that content references the
packaged file paths
('.workflow-artifacts/generated/packaged-context/normalized-spec.md' and
'.workflow-artifacts/generated/packaged-context/acceptance-contract.json'),
remove the positive assertions for longSpecSentinel and
'writeRickyGeneratedContextFiles([', and add an assertion that longSpecSentinel
is absent from prompts/commands (e.g. ensure content does NOT contain
longSpecSentinel and that the 'prepare-context' command/task bodies do not
include the sentinel), leaving the test resilient to changes in how sidecars are
materialized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f6baca1-cdb4-4f9b-943d-b70933b20250

📥 Commits

Reviewing files that changed from the base of the PR and between ab5c6b9 and 83cf87f.

📒 Files selected for processing (2)
  • src/product/generation/pipeline.test.ts
  • src/product/generation/template-renderer.ts

Comment thread src/product/generation/template-renderer.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/product/generation/template-renderer.ts (1)

136-147: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Move sidecar materialization back into prepare-context.

writeRickyGeneratedContextFiles(...) runs before workflow(...).run(), while prepare-context now only does test -f. That means packaging failures bypass step-level retry/reporting, and retrying prepare-context cannot recreate missing sidecars because the step itself never writes them.

Also applies to: 595-603

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/template-renderer.ts` around lines 136 - 147, The
generated code currently calls renderGeneratedContextWriterCall (which invokes
writeRickyGeneratedContextFiles) before creating and running
workflow(...).run(), so prepare-context only tests for files and cannot recreate
sidecars on retry; move the sidecar materialization into the prepare-context
step by invoking renderGeneratedContextWriterCall from inside the code emitted
by renderPrepareContextStep (i.e., ensure renderPrepareContextStep calls
writeRickyGeneratedContextFiles/its writer), and remove the earlier standalone
renderGeneratedContextWriterCall call before workflow(...).description(...).
This ensures prepare-context both creates and verifies sidecars and that
retries/reporting apply to materialization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/product/generation/template-renderer.ts`:
- Around line 1058-1064: The code currently allows copying arbitrary filesystem
paths from targetContext into target-context.txt (see
rickyWorkflowFs.existsSync, statSync, copyFileSync, writeFileSync), which can
leak sensitive local files; change the logic to only allow reads when
targetContext.value resolves (use fs.realpath) to a path under the repository
root (process.cwd()) and is a regular file before allowing copyFileSync,
otherwise treat targetContext.value as literal content and write it via
writeFileSync; alternatively require an explicit trusted file-reference flag on
the spec before performing any filesystem reads.

---

Outside diff comments:
In `@src/product/generation/template-renderer.ts`:
- Around line 136-147: The generated code currently calls
renderGeneratedContextWriterCall (which invokes writeRickyGeneratedContextFiles)
before creating and running workflow(...).run(), so prepare-context only tests
for files and cannot recreate sidecars on retry; move the sidecar
materialization into the prepare-context step by invoking
renderGeneratedContextWriterCall from inside the code emitted by
renderPrepareContextStep (i.e., ensure renderPrepareContextStep calls
writeRickyGeneratedContextFiles/its writer), and remove the earlier standalone
renderGeneratedContextWriterCall call before workflow(...).description(...).
This ensures prepare-context both creates and verifies sidecars and that
retries/reporting apply to materialization.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f85de1e8-7199-4bac-b257-9b34db2a354b

📥 Commits

Reviewing files that changed from the base of the PR and between 83cf87f and afc76be.

📒 Files selected for processing (2)
  • src/product/generation/pipeline.test.ts
  • src/product/generation/template-renderer.ts

Comment thread src/product/generation/template-renderer.ts
@khaliqgant khaliqgant merged commit fb9b384 into main May 7, 2026
1 check was pending
@khaliqgant khaliqgant deleted the codex/package-generated-context branch May 7, 2026 10:36
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/product/generation/template-renderer.ts (1)

132-147: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Move context-file materialization back under prepare-context.

writeRickyGeneratedContextFiles(...) now runs before .workflow(...), so any write/copy failure aborts before the deterministic prepare-context step exists, and even dry-run/graph-inspection paths will still mutate .workflow-artifacts. That makes the workflow less observable and shifts a step-owned side effect into process startup.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/template-renderer.ts` around lines 132 - 147, The
generated context writer (writeRickyGeneratedContextFiles) is being emitted
before the workflow invocation, so failures mutate artifacts during process
startup; move the writer invocation into the deterministic prepare-context step.
Concretely: remove the call emitted by
renderGeneratedContextWriterCall(contextSetup) from the top-level sequence that
builds main() (before workflow(...)), and instead ensure
renderPrepareContextStep(input.artifactsDir, contextSetup) emits or invokes the
generated writer (i.e., have renderPrepareContextStep include the
writeRickyGeneratedContextFiles logic or call renderGeneratedContextWriterCall
there) so context file materialization happens inside the prepare-context step.
🧹 Nitpick comments (2)
src/product/generation/pipeline.test.ts (2)

1395-1411: ⚡ Quick win

Cover the implementer prompt too.

target-context.txt is also threaded into implement-artifact, but this test only checks the planning and review prompts. A small extra assertion for the body that reads implementation-instructions.md would close the highest-value regression gap here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/pipeline.test.ts` around lines 1395 - 1411, The test
threads target-context sidecars into planning and review prompts but misses
asserting the implementer prompt; update the test "threads target context
sidecars into planning and review prompts" to also check that one of the
rendered task bodies (taskBodies from
renderedTaskBodies(artifact(result).content)) includes both
"implementation-instructions.md" (or the implementer prompt identifier
"implement-artifact") and "target-context.txt" so the
implement-artifact/implementation-instructions.md prompt is validated for the
presence of the target context sidecar.

1362-1393: ⚡ Quick win

Assert the sentinel survives inside the packaged context payload, not just outside task bodies.

This regression currently proves “not inlined into prompts,” but it does not prove “still available in the generated context package.” It would still pass if the generator emitted the sidecar filenames but dropped the long spec content from the serialized normalized-spec.md / acceptance-contract.json entries. Add one positive assertion against the generated-context file payload itself.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/pipeline.test.ts` around lines 1362 - 1393, Add a
positive assertion that the longSpecSentinel actually appears inside the
packaged-context sidecar payload itself: after you get content =
artifact(result).content, load the generated sidecar file (e.g. the
normalized-spec.md path previously asserted:
'.workflow-artifacts/generated/packaged-context/normalized-spec.md') from the
generated artifact and assert it contains longSpecSentinel (and optionally also
check acceptance-contract.json contains it). This ensures the sentinel is
present in the serialized packaged context rather than only referenced by
filename in task bodies; reference artifact(result).content, longSpecSentinel
and the sidecar filename when locating the payload to assert.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/product/generation/template-renderer.ts`:
- Around line 723-750: The rendered lead-plan text requires the literal
"Non-goals" heading but buildLeadPlanGateCommand(...) still accepts synonyms
like "out of scope", causing a validation mismatch; fix by updating
buildLeadPlanGateCommand to validate for the exact heading "Non-goals" (reject
synonyms) so the gate enforces the same contract the template expects, and
ensure any tests or callers that construct the gate (e.g., code paths that
reference artifactsDir/lead-plan.md or GENERATION_LEAD_PLAN_READY) are updated
to use the exact literal; alternatively, if you prefer to relax the contract,
change the template text in template-renderer.ts to allow the accepted synonyms
instead of requiring the exact heading—pick one approach and make the
corresponding change consistently in buildLeadPlanGateCommand and the
lead-plan-instructions content.

---

Outside diff comments:
In `@src/product/generation/template-renderer.ts`:
- Around line 132-147: The generated context writer
(writeRickyGeneratedContextFiles) is being emitted before the workflow
invocation, so failures mutate artifacts during process startup; move the writer
invocation into the deterministic prepare-context step. Concretely: remove the
call emitted by renderGeneratedContextWriterCall(contextSetup) from the
top-level sequence that builds main() (before workflow(...)), and instead ensure
renderPrepareContextStep(input.artifactsDir, contextSetup) emits or invokes the
generated writer (i.e., have renderPrepareContextStep include the
writeRickyGeneratedContextFiles logic or call renderGeneratedContextWriterCall
there) so context file materialization happens inside the prepare-context step.

---

Nitpick comments:
In `@src/product/generation/pipeline.test.ts`:
- Around line 1395-1411: The test threads target-context sidecars into planning
and review prompts but misses asserting the implementer prompt; update the test
"threads target context sidecars into planning and review prompts" to also check
that one of the rendered task bodies (taskBodies from
renderedTaskBodies(artifact(result).content)) includes both
"implementation-instructions.md" (or the implementer prompt identifier
"implement-artifact") and "target-context.txt" so the
implement-artifact/implementation-instructions.md prompt is validated for the
presence of the target context sidecar.
- Around line 1362-1393: Add a positive assertion that the longSpecSentinel
actually appears inside the packaged-context sidecar payload itself: after you
get content = artifact(result).content, load the generated sidecar file (e.g.
the normalized-spec.md path previously asserted:
'.workflow-artifacts/generated/packaged-context/normalized-spec.md') from the
generated artifact and assert it contains longSpecSentinel (and optionally also
check acceptance-contract.json contains it). This ensures the sentinel is
present in the serialized packaged context rather than only referenced by
filename in task bodies; reference artifact(result).content, longSpecSentinel
and the sidecar filename when locating the payload to assert.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0191b4a4-eac6-4f3d-b879-909644703fff

📥 Commits

Reviewing files that changed from the base of the PR and between afc76be and 049d1e9.

📒 Files selected for processing (2)
  • src/product/generation/pipeline.test.ts
  • src/product/generation/template-renderer.ts

Comment on lines +723 to +750
path: `${artifactsDir}/lead-plan-instructions.md`,
content: [
'# Lead Plan Instructions',
'',
'Plan the workflow execution from the packaged context files, not from the short task prompt.',
'',
'Required sections:',
'',
'- Non-goals',
'- Routing contract',
'- Implementation contract',
'- Deliverables',
'- Verification gates',
'',
'Use this exact section heading in the lead plan. Do not rename "Non-goals" to "Out of scope" or another synonym.',
'',
`Write ${artifactsDir}/lead-plan.md and end it with GENERATION_LEAD_PLAN_READY.`,
'',
'Generation-time skill boundary:',
'',
`- Read ${artifactsDir}/skill-application-boundary.json and treat it as generator metadata only.`,
'- Skills are applied by Ricky during selection, loading, and template rendering.',
'- Do not claim generated agents load, retain, or embody skill files at runtime unless a future runtime test proves that path.',
'',
'Loaded skills summary:',
'',
loadedSkillsReport,
].join('\n'),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

The new lead-plan contract is stricter than the gate that enforces it.

These instructions now require the exact Non-goals heading, but buildLeadPlanGateCommand(...) still accepts out of scope/not in scope. The workflow can therefore pass deterministic validation while violating its packaged contract. Either tighten the gate to require the literal heading or relax this instruction text.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/product/generation/template-renderer.ts` around lines 723 - 750, The
rendered lead-plan text requires the literal "Non-goals" heading but
buildLeadPlanGateCommand(...) still accepts synonyms like "out of scope",
causing a validation mismatch; fix by updating buildLeadPlanGateCommand to
validate for the exact heading "Non-goals" (reject synonyms) so the gate
enforces the same contract the template expects, and ensure any tests or callers
that construct the gate (e.g., code paths that reference
artifactsDir/lead-plan.md or GENERATION_LEAD_PLAN_READY) are updated to use the
exact literal; alternatively, if you prefer to relax the contract, change the
template text in template-renderer.ts to allow the accepted synonyms instead of
requiring the exact heading—pick one approach and make the corresponding change
consistently in buildLeadPlanGateCommand and the lead-plan-instructions content.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant