fix(spec-refiner): broaden _section regex to accept parenthesized headers #28

Merged
kaykayyali merged 1 commits from fix/spec-refiner-parenthesized-suffix into main 2026-06-26 16:21:01 +00:00
Owner

Bug

The spec-refiner prompt lists section headers with parenthesized descriptions (## Acceptance Criteria (numbered), ## TDD Plan (list the failing tests), etc.). The LLM faithfully copies them. The post-check regex ^##\\s+<name>\\s*\\n rejects parenthesized suffixes — every spec went spec_wrong on first attempt (2026-06-26).

Fix

Broaden _section() regex to \\s*(\\([^)]*\\))?\\s*\\n. Accepts both bare and parenthesized headers. The prompt's parentheticals are intentional hints to the LLM about what belongs in each section's body — kept.

Coverage

  • tests/unit/test_phases_section.py — 10 unit tests pinning regex behavior.
  • tests/contract/test_contracts_match_source.py::test_refine_spec_prompt_section_names_match_post_check — pins both prompt AND regex.

Companion gap analysis

The structural fix (replace text parsing with Pydantic-in / JSONB-out) lives at wiki/queries/damascus-orchestrator/spec-refiner-text-parsing-2026-06-26.md (tracked separately).

Verification

pytest tests/test_conftest_safety.py tests/unit/ tests/contract/ → 90 passed, 0 failed.

## Bug The spec-refiner prompt lists section headers with parenthesized descriptions (`## Acceptance Criteria (numbered)`, `## TDD Plan (list the failing tests)`, etc.). The LLM faithfully copies them. The post-check regex `^##\\s+<name>\\s*\\n` rejects parenthesized suffixes — every spec went `spec_wrong` on first attempt (2026-06-26). ## Fix Broaden `_section()` regex to `\\s*(\\([^)]*\\))?\\s*\\n`. Accepts both bare and parenthesized headers. The prompt's parentheticals are intentional hints to the LLM about what belongs in each section's body — kept. ## Coverage - `tests/unit/test_phases_section.py` — 10 unit tests pinning regex behavior. - `tests/contract/test_contracts_match_source.py::test_refine_spec_prompt_section_names_match_post_check` — pins both prompt AND regex. ## Companion gap analysis The structural fix (replace text parsing with Pydantic-in / JSONB-out) lives at `wiki/queries/damascus-orchestrator/spec-refiner-text-parsing-2026-06-26.md` (tracked separately). ## Verification `pytest tests/test_conftest_safety.py tests/unit/ tests/contract/` → 90 passed, 0 failed.
kaykayyali added 1 commit 2026-06-26 16:17:34 +00:00
fix(spec-refiner): broaden _section regex to accept parenthesized headers
Some checks failed
test / contract-and-unit (pull_request) Failing after 15s
a92d56b988
The spec-refiner's prompt lists section headers with parenthesized
descriptions:
  ## Goal
  ## Acceptance Criteria (numbered)
  ## TDD Plan (list the failing tests)
  ## File Scope (list of paths/globs the implementation may touch)
  ## Test Command (the exact shell command that proves done)
  ## Ambiguities (any open questions for a human)

The post-check regex was strict:
  re.search(r"^##\s+<name>\s*\n", text)

This rejected any header with a parenthesized suffix because (numbered),
(list the failing tests), etc. sat between the section name and the
newline. The LLM faithfully copied the prompt's headers into its output,
the post-check failed to recognize them, and every spec went
`spec_wrong` on first attempt (2026-06-26).

Fix: broaden the regex to allow an optional `(...)` suffix:
  re.search(r"^##\s+<name>\s*(\([^)]*\))?\s*\n", text)

This accepts both bare headers (`## Goal`) and parenthesized ones
(`## TDD Plan (list the failing tests)`). The prompt's parentheticals
are intentional hints to the LLM about what belongs in each section's
body — we keep them.

Regression coverage:
- tests/unit/test_phases_section.py — 10 unit tests pinning the
  regex behavior (bare headers, parenthesized, multi-section,
  whitespace variations, line-start anchoring, complex bodies,
  post-check integration). Replaces the OLD test that expected
  parenthesized headers to be REJECTED.

- tests/contract/test_contracts_match_source.py::test_refine_spec_prompt_section_names_match_post_check
  — pins both sides of the contract: the regex contains the
  optional-suffix group, AND the prompt's parenthetical hints are
  present in refine_spec.

Companion gap analysis: see the BMAD gap-analysis page at
`wiki/queries/damascus-orchestrator/spec-refiner-text-parsing-2026-06-26.md`
(tracked separately). That page recommends replacing text parsing
with Pydantic-in / JSONB-out as the durable fix; this regex broadening
is the tactical unblock for the spec-refiner cycle.

Verification:
- pytest tests/unit/test_phases_section.py         → 10 passed
- pytest tests/contract/test_contracts_match_source.py::test_refine_spec_prompt_section_names_match_post_check → 1 passed
- pytest tests/test_conftest_safety.py tests/unit/ tests/contract/ → 90 passed, 0 failed
kaykayyali merged commit 62f6234a18 into main 2026-06-26 16:21:01 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kaykayyali/damascus-orchestrator#28