fix(spec): route any non-empty Ambiguities section to awaiting_human
All checks were successful
test / contract-and-unit (pull_request) Successful in 12s

The spec-refiner at src/damascus/phases.py:74 guarded the awaiting_human
transition on a trailing question-mark character. The contract at
wiki/concepts/spec-refiner-contract.md says the trigger is any non-empty
section. A spec whose Ambiguities section lists an open question without
ending it in '?' (e.g. '- the auth model is unclear because of X') fell
through to phase='build' with the human never seeing the issue.

Replaces the regex check with a non-empty-after-strip check. Verified by:
- contract test (PR #11): test_refine_spec_routes_non_empty_ambiguities_to_awaiting_human
  now passes (RED on broken code, GREEN on this fix).
- full contract suite: 19/19 pass.
- unit suite: 10/10 pass.

Gap note: wiki/queries/damascus-orchestrator/spec-refiner-ambiguity-routing-drift-2026-06-24.md

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
damascus-heartbeat
2026-06-24 07:48:42 +00:00
parent bb96bdb83f
commit abc8f4a0c7

View File

@@ -71,7 +71,14 @@ def refine_spec(cur, item: dict) -> dict:
"output_tokens": result["output_tokens"], "usd": result["usd"],
})
if "## Ambiguities" in text and re.search(r"\?\s*$", _section(text, "Ambiguities")):
# Per spec-refiner-contract.md §3: any non-empty `## Ambiguities` section
# triggers the awaiting_human channel. The previous implementation required
# the section to end with a question-mark character, which silently
# swallowed list-style ambiguities (e.g. "- the auth model is unclear
# because of X") and routed them to build with the human never seeing
# the issue.
ambiguities_section = _section(text, "Ambiguities")
if "## Ambiguities" in text and ambiguities_section.strip():
issue_id = state.open_human_issue(
cur, item["id"], f"[{project}/{story_id}] {title}: {_section(result['text'], 'Ambiguities')}"
)