You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Story records quote exact test totals (e.g. "+23 tests, 241/943"). Like the File
List (fixed in #41), these are transcribed by the dev agent from memory and
drift — e.g. claimed 235/935 vs actual 241/943; claimed 253/1027 vs actual
260/1076. Same root cause as #41 (transcription vs computation), same recurring
MEDIUM review finding that three "be more careful" guidelines (AI-1 → AI-2.1 →
AI-3.1) failed to close.
Why it's harder than the File List
The test runner is project-specific (phpunit / pytest / jest / go / …). JUnit XML
is the lever: parsing it is stack-agnostic — one parser reads tests/failures/errors/skipped from any runner (assertions is PHPUnit-only, so
optional). Producing it is stack-specific, so it belongs in per-project config —
no per-runner logic in the tool.
Proposed direction
New test-counts --repo --story [--write] subcommand (sibling of reconcile-story).
A single configurable test_command in the policy override
(_bmad/bmm/story-automator.policy.json) that emits JUnit to a known path.
Capture-first, re-run as the deterministic floor:
Tier 1: parse a fresh JUnit artifact from the dev run (no re-run).
Tier 2: no artifact + test_command set → the orchestrator re-runs it and
parses JUnit.
Tier 3: neither → skip with a logged warning (File List reconcile still runs).
Nudge (optimisation, not a dependency): extend the automator's own dev prompt
(data/prompts/dev.md) to ask the agent to emit JUnit and never omit the test
summary. Tier 2 guarantees correctness if the agent ignores it.
Record test_counts {tests, failures, errors, skipped, assertions?} in data/parse/dev.json so the orchestrator stores real numbers instead of a
self-reported tests_passed.
Design decisions (settled)
Single canonical test environment. Test count must not differ across
environments — only skipped does (env-gated tests). If a project containerises,
the container is the canonical, prod-like env and test_command is the
containerised invocation. No test_command / test_command_container duality,
no per-env merging.
Counts live in one machine-owned place — a ### Test Counts block under Dev
Agent Record, plus test_counts in dev.json. They are removed from the
Change Log / Completion Notes prose. ⚠️Potential breaking change for anyone
relying on counts in the Change Log.
Out of scope (separate, upstream)
A suggestion to bmad-method's core bmad-dev-story to emit JUnit natively would
raise the Tier-1 hit rate and cut double-runs. Decoupled from this issue.
Problem
Story records quote exact test totals (e.g. "+23 tests, 241/943"). Like the File
List (fixed in #41), these are transcribed by the dev agent from memory and
drift — e.g. claimed 235/935 vs actual 241/943; claimed 253/1027 vs actual
260/1076. Same root cause as #41 (transcription vs computation), same recurring
MEDIUM review finding that three "be more careful" guidelines (AI-1 → AI-2.1 →
AI-3.1) failed to close.
Why it's harder than the File List
The test runner is project-specific (phpunit / pytest / jest / go / …). JUnit XML
is the lever: parsing it is stack-agnostic — one parser reads
tests/failures/errors/skippedfrom any runner (assertionsis PHPUnit-only, sooptional). Producing it is stack-specific, so it belongs in per-project config —
no per-runner logic in the tool.
Proposed direction
test-counts --repo --story [--write]subcommand (sibling ofreconcile-story).test_commandin the policy override(
_bmad/bmm/story-automator.policy.json) that emits JUnit to a known path.test_commandset → the orchestrator re-runs it andparses JUnit.
(
data/prompts/dev.md) to ask the agent to emit JUnit and never omit the testsummary. Tier 2 guarantees correctness if the agent ignores it.
test_counts {tests, failures, errors, skipped, assertions?}indata/parse/dev.jsonso the orchestrator stores real numbers instead of aself-reported
tests_passed.Design decisions (settled)
environments — only
skippeddoes (env-gated tests). If a project containerises,the container is the canonical, prod-like env and
test_commandis thecontainerised invocation. No
test_command/test_command_containerduality,no per-env merging.
### Test Countsblock under DevAgent Record, plus
test_countsindev.json. They are removed from theChange Log / Completion Notes prose.
relying on counts in the Change Log.
Out of scope (separate, upstream)
A suggestion to bmad-method's core
bmad-dev-storyto emit JUnit natively wouldraise the Tier-1 hit rate and cut double-runs. Decoupled from this issue.