From 21f1cb6f17fe31154ffa346338a9c6bfa1728449 Mon Sep 17 00:00:00 2001 From: Paul O'Reilly Date: Tue, 28 Apr 2026 15:37:22 +1200 Subject: [PATCH] Add tdd-impl workflow: parallel TDD implementations with one-shot audit Two agents (impl_a: airouter, impl_b: best-complexity model) implement in parallel against pre-written tests using TDD composites. An audit node compares both outputs and emits a JSON verdict (pass/more_work_needed, winner: a/b/neither, gaps). Harnesses are param-overridable for provider flexibility. F-WE-PDIV note in description for future unique_providers enforcement. Co-Authored-By: Claude Sonnet 4.6 --- workflows/tdd-impl.yaml | 162 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 workflows/tdd-impl.yaml diff --git a/workflows/tdd-impl.yaml b/workflows/tdd-impl.yaml new file mode 100644 index 0000000..6b5a177 --- /dev/null +++ b/workflows/tdd-impl.yaml @@ -0,0 +1,162 @@ +name: tdd-impl +version: 1 +description: > + Parallel TDD implementation: two agents implement against a pre-written test suite, + then an audit node compares both outputs and emits a one-shot JSON verdict. + + Tests must already exist in the repo before dispatching this workflow. Use the + sonnet-test-writer or opus-test-writer template to write tests first if needed. + + Default model routing: impl_a → Airouter Qwen3.6 (cost-efficient), impl_b → + best Anthropic model by complexity score. Override impl_a_harness / impl_b_harness + to change providers. When F-WE-PDIV lands, add unique_providers: true to the + audit node requirements to guarantee cross-provider auditing automatically. + +params: + required: + task_description: + type: string + description: "What to implement — the feature or subsystem covered by the tests" + project_id: + type: string + description: "Target project identifier for task grouping" + repo_url: + type: string + description: "Git repo URL containing the spec and pre-written tests" + agent_repo_url: + type: string + description: "Agent repo URL for branch-per-task output persistence" + optional: + spec_file: + type: string + default: "" + description: "Path to the spec file(s) the tests cover (e.g. spec/my-feature.md). Leave blank to let the agent discover specs." + impl_a_harness: + type: string + default: "code-airouter-tdd-repo/v1" + description: "Harness for implementation A (default: Airouter TDD). Override to change provider." + impl_b_harness: + type: string + default: "code-sonnet-tdd-repo/v1" + description: "Harness for implementation B (default: Sonnet TDD). Override to change provider." + test_file_glob: + type: string + default: "tests/" + description: "Pytest path/glob to run (default: full tests/ directory)" + scope_notes: + type: string + default: "" + description: "Any constraints, prior decisions, or scope boundaries for the agents" + +nodes: + impl_a: + name: "Implementation A" + prompt: | + You are implementing source code to make a test suite pass. + + ## Task + {{ task_description }} + + {% if spec_file %} + ## Spec + Read the spec at `{{ spec_file }}` in the repo for the full requirements. + {% endif %} + + {% if scope_notes %} + ## Scope Notes + {{ scope_notes }} + {% endif %} + + ## Instructions + 1. Run `python -m pytest {{ test_file_glob }} -v --tb=short` to see the current test state. + 2. Implement source code in `lib/` and `controlplane/` (or as specified in the spec) until all tests pass. + 3. Do NOT modify any test files — they are read-only and OS-locked. + 4. Run the full test suite before finishing to confirm everything is green. + 5. Write a brief summary of your implementation approach to `/workspace/project/output.md`. + Include: files created/modified, key design decisions, any known limitations. + + Finish only when `pytest {{ test_file_glob }}` exits 0. + harness: "{{ impl_a_harness }}" + requirements: + labels: [airouter] + min_scores: + cost_efficiency: 8 + + impl_b: + name: "Implementation B" + prompt: | + You are implementing source code to make a test suite pass. + + ## Task + {{ task_description }} + + {% if spec_file %} + ## Spec + Read the spec at `{{ spec_file }}` in the repo for the full requirements. + {% endif %} + + {% if scope_notes %} + ## Scope Notes + {{ scope_notes }} + {% endif %} + + ## Instructions + 1. Run `python -m pytest {{ test_file_glob }} -v --tb=short` to see the current test state. + 2. Implement source code in `lib/` and `controlplane/` (or as specified in the spec) until all tests pass. + 3. Do NOT modify any test files — they are read-only and OS-locked. + 4. Run the full test suite before finishing to confirm everything is green. + 5. Write a brief summary of your implementation approach to `/workspace/project/output.md`. + Include: files created/modified, key design decisions, any known limitations. + + Finish only when `pytest {{ test_file_glob }}` exits 0. + harness: "{{ impl_b_harness }}" + requirements: + min_scores: + complexity: 7 + spec_adherence: 8 + + audit: + name: "Audit — one-shot verdict" + depends_on: [impl_a, impl_b] + prompt: | + You are auditing two independent implementations of the same feature and picking the winner. + + ## Task that was implemented + {{ task_description }} + + {% if spec_file %} + ## Spec (requirements to check against) + Read `{{ spec_file }}` in the repo for the authoritative requirements. + {% endif %} + + ## Implementation A summary + <> + + ## Implementation B summary + <> + + ## Instructions + 1. Read the spec (if provided) to understand the requirements. + 2. Review each implementation summary against the requirements. + 3. Identify any spec gaps, correctness concerns, or quality issues in each. + 4. Pick the stronger implementation, or flag if neither is acceptable. + + Write your verdict to `/workspace/project/output.md` as valid JSON followed by a brief rationale: + + ```json + { + "verdict": "pass" | "more_work_needed", + "winner": "a" | "b" | "neither", + "gaps": ["gap 1", "gap 2"], + "rationale": "one paragraph explaining the decision" + } + ``` + + Use `"verdict": "pass"` only if at least one implementation fully satisfies the spec with no + significant gaps. Use `"more_work_needed"` if both have significant gaps or if `"winner"` + is `"neither"`. Set `"gaps"` to the list of outstanding spec items not addressed by the winner. + harness: planning/v1 + requirements: + min_scores: + complexity: 8 + spec_adherence: 9