fix(specs): _STATUS_VALUE_RE accepts both **Status**: and **Status:**#57
Merged
Conversation
The regex previously only matched `**Status**:` (colon outside
asterisks). Real specs in this repo overwhelmingly use `**Status:**`
(colon inside) — a quick grep showed ~7 of 8 status lines in that
form. The dashboard's Status column and the MCP gui_get_spec_status
tool were silently returning None for those specs.
_STATUS_RE — old: r"^\s*\*\*Status\*\*:.*$"
— new: r"^\s*\*\*Status(?:\*\*:|:\*\*).*$"
_STATUS_VALUE_RE — old: r"\*\*Status\*\*:\s*(\S+)"
— new: r"\*\*Status(?:\*\*:|:\*\*)\s*(\S+)"
The alternation accepts either order of the closing asterisks and
colon. Malformed look-alikes (`**Status:`, `**Status: foo` without
closing asterisks, `**Statuss**: foo`, `## Status: foo`) still get
correctly rejected.
Tests:
- test_cowork_specs.py:
• test_status_regex_accepts_both_markdown_emphasis_styles
(4 parametrized happy paths covering both formats, the
dashed-phrase form, and indented lines)
• test_status_regex_rejects_malformed_lines (4 parametrized
negative cases)
- test_mcp_tools.py:
• test_get_spec_reads_colon_inside_status_format — covers the
MCP path, not just the FastAPI route
The PUT-status route's substitution still rewrites in the
`**Status**:` form; that's a separate normalization choice and
isn't changed here. Surfaced during PR #52's MCP Phase 2 work and
flagged via a follow-up chip; this closes the chip's intent.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
source_hash drift only — no narrative change. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_STATUS_REand_STATUS_VALUE_REinsidecar/attune_gui/routes/cowork_specs.pypreviously only matched**Status**:(colon outside the asterisks). Real specs in this repo overwhelmingly use**Status:**(colon inside) — a quickgrep -h "Status" specs/*/requirements.md docs/specs/*/decisions.mdreturned ~7 of 8 status lines in that form.Net result: the dashboard's Status column and the new MCP
gui_get_spec_statustool were silently returningNonefor the majority of specs in the wild.The fix
Tiny alternation in both regexes:
The
(?:\*\*:|:\*\*)matches**:or:**— covering both legitimate markdown emphasis styles. Manual confirmation:**Status**: approvedapproved**Status:** approvedapproved**Status:** Closed — finalClosed**Status**: pendingpending**Status:**Status: approved**Statuss**: approved## Status: approvedTests
test_cowork_specs.py— 8 new parametrized tests:test_status_regex_accepts_both_markdown_emphasis_styles(4 happy paths covering both formats, the common dashed-phrase form, and indented lines)test_status_regex_rejects_malformed_lines(4 negative cases proving the looser regex still rejects look-alikes)test_mcp_tools.py— 1 new test (test_get_spec_reads_colon_inside_status_format) locking in the fix on the MCP pathWhat's NOT changed
The PUT-status route's substitution still rewrites in the
**Status**:form (line ~442 of cowork_specs.py). That's a separate normalization choice — when the route rewrites a**Status:**line, it'll convert it to**Status**:. Could be revisited later but out of scope here.Test plan
pytest sidecar/tests/test_cowork_specs.py sidecar/tests/test_mcp_tools.py sidecar/tests/test_mcp_integration.py— 40/40 greenversion == 'dev'worktree quirk)ruff check sidecar/— cleanProvenance
Surfaced during #52's MCP Phase 2 work, when the test fixtures had to use the rare
**Status**:form to work around this latent bug. Flagged via a follow-up chip at the time; this PR closes the chip's intent.🤖 Generated with Claude Code