fix(spec): route any non-empty Ambiguities section to awaiting_human #12
Reference in New Issue
Block a user
Delete Branch "fix/spec-refiner-ambiguity-routing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes the spec-refiner ambiguity-routing drift (gap note:
wiki/queries/damascus-orchestrator/spec-refiner-ambiguity-routing-drift-2026-06-24.md).The spec-refiner guarded the
awaiting_humantransition on the Ambiguities section ending with a question-mark character. The contract says any non-empty section should trigger the channel. List-style ambiguities (e.g. "- the auth model is unclear because of X") fell through tobuildand the human never saw the issue.Change
Single-file, 8 insertions, 1 deletion in
src/damascus/phases.py. Replaces the trailing-?regex check with a non-empty-after-strip check on the parsed section.Verification
test_refine_spec_routes_non_empty_ambiguities_to_awaiting_human(PR #11): PASS (was RED on broken code).The contract test is the structural counterpart: it source-greps for the buggy regex literal and asserts it's gone, plus the positive checks for
awaiting_humanrouting andopen_human_issueside effect.Why this is gap-finding-discipline compliant
Out of scope
Self-review
Heartbeat authored, heartbeat cannot self-approve. Kay's call to merge. The fix is small, the contract test backs it, the gap note documents the rationale.
Self-review (heartbeat tick)
Diff walk
8 insertions, 1 deletion. Single condition change. The
ambiguities_sectionlocal is computed once and reused on the next line forstate.open_human_issue's f-string argument (no behavioral change there — that's_section(result['text'], 'Ambiguities'), same value).Contract walk
wiki/concepts/spec-refiner-contract.md §3 says: "On ambiguity: row transitions
spec → awaiting_human,human_issuesrow is created with the question text." The trigger condition in the contract is "any non-empty## Ambiguitiessection." The previous regex\?\s*$narrowed this to "ends with?" — a subset that swallows list-style ambiguities.The fix removes the regex. The new check
.strip()is non-empty-after-whitespace, which matches the contract's "non-empty" semantics. Whitespace-only sections (template stubs) are still treated as empty.Test walk
test_refine_spec_routes_non_empty_ambiguities_to_awaiting_human) — source-greps for the literal bug pattern (6 chars:\,?,\,s,*,$) insiderefine_spec. PASS on this branch. RED on main. This is the structural counterpart to the runtime fix.Pitfalls avoided
\?\s*$string. The contract test source-greps the wholerefine_specbody (including comments), so the test failed RED even on the fix. Fixed by paraphrasing the bug description in plain English. Caught by running the test before committing.fix/spec-refiner-ambiguity-routingfrom a single commit on top ofmain. No rebase, no update-ref hack needed.tea pulls approvepitfall, the bot authored this PR and cannot approve it. Posted self-review here; merge is Kay's call.Risk
Low. The change widens the ambiguity trigger (more specs go to
awaiting_humanthan before). A spec whose Ambiguities section is now non-empty but was previously silently ignored will surface ahuman_issueto the operator instead of falling through to a doomed build. This is the intended behavior per the contract.The reverse — a spec that previously routed correctly via the
?check — still routes correctly via.strip(). No regression.Recommendation
Merge. Single-line condition change, contract-aligned, contract-tested, gap-noted.