Skip to content

feat: prevent parallel task file collisions for undeclared files (#70) (#70)#71

Merged
jafreck merged 3 commits intomainfrom
cadre/issue-70
Feb 23, 2026
Merged

feat: prevent parallel task file collisions for undeclared files (#70) (#70)#71
jafreck merged 3 commits intomainfrom
cadre/issue-70

Conversation

@jafreck
Copy link
Copy Markdown
Owner

@jafreck jafreck commented Feb 23, 2026

Summary

This PR prevents parallel code-writer agents from silently colliding on undeclared files (e.g., test files) by updating the implementation-planner template to require explicit test file paths, adding a detectBatchCollisions() utility to TaskQueue, and injecting sibling task file lists into code-writer context. Together, these changes close the loop on the file-overlap gap that caused issues like #24.

Closes #70

Changes

  • src/agents/templates/implementation-planner.md: Added a rule requiring every task's files list to include all test files it creates or modifies, and updated the example task block to demonstrate a test file alongside a source file.
  • src/execution/task-queue.ts: Added TaskQueue.detectBatchCollisions(tasks), a public static method that scans a batch of tasks for file-path collisions and returns human-readable descriptions of each colliding pair.
  • src/agents/context-builder.ts: Updated ContextBuilder.buildForCodeWriter() to accept an optional siblingFiles?: string[] parameter. When provided and non-empty, the files are included in the written context payload so code-writer agents are aware of files touched by sibling tasks.

Implementation Details

The three source changes are independent and non-breaking:

  • The template update is a documentation/prompt change; existing tool code is unaffected.
  • detectBatchCollisions() is additive — it does not modify selectNonOverlappingBatch() or any existing method.
  • The siblingFiles parameter is optional; all existing call sites that omit it continue to compile and behave identically.

Testing

  • Added describe('detectBatchCollisions') block in tests/task-queue.test.ts with 8 test cases covering: no collisions, single collision, multiple collisions, three-way collision, empty list, single-task batch, test-file collision, and exclusive file ownership.
  • Added describe('buildForCodeWriter siblingFiles') block in tests/context-builder.test.ts with 4 test cases covering: non-empty siblings included, omitted siblings absent, empty-array siblings absent, and base payload fields always present.
  • Added describe('test file inclusion rule') block in tests/implementation-planner-template.test.ts with 3 assertions verifying the updated template wording and example.
  • All existing tests continue to pass.

Integration Verification

  • Build: pass
  • Tests: pass
  • Lint: pass

Notes

  • detectBatchCollisions() is currently a utility method. Calling it after each parallel batch (to emit warnings or fail fast) is a follow-up integration task not included in this PR.
  • The siblingFiles list must be populated by the caller (e.g., the orchestrator loop). This PR only wires up the context-builder side; the orchestrator plumbing is a follow-up.

Cadre Process Challenges

This section is required for all CADRE-generated PRs (dogfooding data).
Document honestly what was difficult, confusing, or error-prone when CADRE processed this issue.

  • Issue clarity: The issue clearly identified three candidate changes but marked two of them ("optionally") — it was unclear which were required for acceptance vs. bonus. The analysis agent flagged this ambiguity but proceeded to implement all three anyway, which was the right call given acceptance criteria wording.
  • Agent contracts: No schema mismatches encountered. The buildForCodeWriter signature change required care to ensure the optional parameter didn't break existing call sites, but the TypeScript optional parameter pattern handled this cleanly.
  • Context limitations: The siblingFiles orchestrator plumbing (who collects sibling files and passes them to buildForCodeWriter) was explicitly left out of scope. This created a slightly unsatisfying half-implementation — the context-builder accepts sibling files but nothing yet passes them in production. A clearer issue or acceptance criteria would have scoped this more precisely.
  • Git/worktree: No branch, worktree, or commit problems observed.
  • Parsing/output: All agent outputs parsed correctly; no schema mismatches.
  • Retry behavior: No retries needed.
  • Overall: The biggest friction was the "optionally" qualifier in the issue, which left the implementation-planner and code-writer agents uncertain about scope. Clearer "MUST / SHOULD / MAY" language in issues would reduce ambiguity and over-building.

Closes #70

@jafreck jafreck merged commit a01038f into main Feb 23, 2026
2 checks passed
@jafreck jafreck added the cadre-generated Pull request automatically generated by cadre label Feb 24, 2026
@jafreck jafreck deleted the cadre/issue-70 branch February 25, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cadre-generated Pull request automatically generated by cadre

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prevent parallel task file collisions for undeclared files (e.g., test files)

1 participant