Description
A real bmad-loop sweep run escalated (whole run PAUSED) because the triage session named a bundle integration-double-checkout-shared-client — 41 characters, one over BUNDLE_NAME_RE = ^[a-z0-9][a-z0-9-]{1,39}$ (sweep.py:37). Three distinct problems compound here:
-
The constraint is missing where the naming rule is introduced. data/skills/bmad-loop-sweep/SKILL.md:67 tells the triage session only that name is "kebab-case (e.g. unicode-string-hardening)". The regex (with its 40-char cap) appears only in automation-mode.md:60. A session that follows SKILL.md's naming guidance can produce a name the validator must reject.
-
The --feedback re-drive did not converge on this failure class. The engine correctly re-drove triage with the validation errors (_write_feedback → /bmad-loop-sweep --feedback <path>), and the second session re-emitted the exact same 41-char name, hitting max_triage_attempts = 2 → escalation. Journal excerpt:
session-start sweep-triage-triage-1 prompt: /bmad-loop-sweep
session-start sweep-triage-triage-2 prompt: /bmad-loop-sweep --feedback .../feedback...
triage-decision attempt=2 ok=false errors=["bundle name 'integration-double-checkout-shared-client' invalid (want ^[a-z0-9][a-z0-9-]{1,39}$)"]
story-escalated sweep-triage
run-paused
-
The severity is out of proportion to the defect. The bundle name is a label; ids, dedupe and cycle-collision safety come from elsewhere (dw{N}- prefixing, uniqueness check). One over-long label costs the whole sweep — two triage sessions (~650k weighted tokens here) and a human resolve — when a deterministic normalization would have been lossless.
Steps to reproduce
Run bmad-loop sweep on a ledger whose open entries induce a bundle whose natural kebab-case description exceeds 40 chars (ours: an integration-test bundle spanning double-checkout/shared-client entries). Triage emits the name, validation rejects, feedback re-drive repeats it, run escalates.
Expected behavior
Any of (smallest first — happy to PR whichever you prefer):
- Docs: state the full
^[a-z0-9][a-z0-9-]{1,39}$ rule (and the ≤40 length in words) at SKILL.md's name definition, not only in automation-mode.md.
- Deterministic repair: an invalid-only-by-shape name is normalizable in plain Python before rejection — lowercase, strip invalid chars, truncate to 40 with the
dw{N}- uniqueness mechanics untouched — journalled as a rename rather than escalated.
- Feedback emphasis: when the same validation error repeats on the re-drive, the feedback file could lead with the failing field and the literal constraint, so attempt 2 spends its attention on the one thing that failed.
Actual behavior
PAUSED: triage output failed validation: bundle name 'integration-double-checkout-shared-client' invalid (want ^[a-z0-9][a-z0-9-]{1,39}$) after two triage sessions; migration phase committed fine.
Environment
bmad-loop 0.9.0 (main @ 43a2853 + the PR #502 branch — sweep paths untouched by it), macOS (darwin 25.5.0), adapter claude, tmux 3.6a.
🤖 Generated with Claude Code
Description
A real
bmad-loop sweeprun escalated (whole run PAUSED) because the triage session named a bundleintegration-double-checkout-shared-client— 41 characters, one overBUNDLE_NAME_RE = ^[a-z0-9][a-z0-9-]{1,39}$(sweep.py:37). Three distinct problems compound here:The constraint is missing where the naming rule is introduced.
data/skills/bmad-loop-sweep/SKILL.md:67tells the triage session only thatnameis "kebab-case (e.g.unicode-string-hardening)". The regex (with its 40-char cap) appears only inautomation-mode.md:60. A session that follows SKILL.md's naming guidance can produce a name the validator must reject.The
--feedbackre-drive did not converge on this failure class. The engine correctly re-drove triage with the validation errors (_write_feedback→/bmad-loop-sweep --feedback <path>), and the second session re-emitted the exact same 41-char name, hittingmax_triage_attempts = 2→ escalation. Journal excerpt:The severity is out of proportion to the defect. The bundle name is a label; ids, dedupe and cycle-collision safety come from elsewhere (
dw{N}-prefixing, uniqueness check). One over-long label costs the whole sweep — two triage sessions (~650k weighted tokens here) and a human resolve — when a deterministic normalization would have been lossless.Steps to reproduce
Run
bmad-loop sweepon a ledger whose open entries induce a bundle whose natural kebab-case description exceeds 40 chars (ours: an integration-test bundle spanning double-checkout/shared-client entries). Triage emits the name, validation rejects, feedback re-drive repeats it, run escalates.Expected behavior
Any of (smallest first — happy to PR whichever you prefer):
^[a-z0-9][a-z0-9-]{1,39}$rule (and the ≤40 length in words) at SKILL.md'snamedefinition, not only in automation-mode.md.dw{N}-uniqueness mechanics untouched — journalled as a rename rather than escalated.Actual behavior
PAUSED: triage output failed validation: bundle name 'integration-double-checkout-shared-client' invalid (want ^[a-z0-9][a-z0-9-]{1,39}$)after two triage sessions; migration phase committed fine.Environment
bmad-loop 0.9.0 (main @ 43a2853 + the PR #502 branch — sweep paths untouched by it), macOS (darwin 25.5.0), adapter claude, tmux 3.6a.
🤖 Generated with Claude Code