Skip to content

sweep: one over-long triage bundle name escalates the whole run — SKILL.md never states the 40-char cap, and --feedback did not converge #503

Description

@pirony

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:

  1. 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.

  2. 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
    
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions