Skip to content

fix: accept a punctuation-delimited reason on the RESULT line - #9

Merged
elkaix merged 1 commit into
mainfrom
fix/result-line-trailing-reason
Aug 13, 2026
Merged

fix: accept a punctuation-delimited reason on the RESULT line#9
elkaix merged 1 commit into
mainfrom
fix/result-line-trailing-reason

Conversation

@elkaix

@elkaix elkaix commented Aug 13, 2026

Copy link
Copy Markdown
Member

What

_write_turn_result_state (hooks/lib-write-turn.sh:27) only matched a RESULT line whose terminal token was the entire rest of the line:

s/^RESULT:[[:space:]]*(DONE|NEEDS_ANSWERS|BLOCKED|FAILED)[[:space:]]*$/\1/p

It now accepts an optional trailing reason that starts with a punctuation character.

Why

The implementer contract in the same file (lib-write-turn.sh:75-78) presents the tokens as:

RESULT: BLOCKED         — missing access/credentials or a destructive step; name the blocker

So implementers emit RESULT: BLOCKED — <reason>. That line did not match, the run was classified IMPLEMENTER_STATE: COMPANION_FAILURE, and the loop exited 11 without ever running the caller's --verify — even though the work and the report were correct.

The fix goes in the parser, not the contract wording: the parser is the layer that authors the disagreement, and rewording cannot help reports already written in that shape.

Observed live — the dispatch that implemented this fix was itself rejected by the old parser, for ending with RESULT: DONE — plan fully executed, verification output pasted below.

Safety — every existing rejection survives

input result
RESULT: BLOCKED BLOCKED
RESULT: BLOCKED — active lock prevented tests BLOCKED
RESULT: DONE - all green DONE
RESULT: FAILED: verifier died FAILED
RESULT: NEEDS_ANSWERS␠␠␠ NEEDS_ANSWERS
RESULT: DONEISH no match
RESULT: DONE_ISH no match
RESULT: DONE and everything passed no match
RESULT: DONE — quoted no match
- RESULT: DONE no match

Two of these carry the safety argument. The ^ anchor keeps the contract's own four token lines inert — they are indented four spaces inside the CONTRACT string — so a report that quotes the contract still cannot self-classify. And trailing prose must start with punctuation, so RESULT: DONE and everything passed stays unparseable rather than being silently read as DONE.

The expression is pure POSIX ERE with no multibyte literal in a bracket expression, so the em dash is matched by a negated ASCII class.

How it was verified

  • bash tests/run.sh — 18 passed, 0 failed
  • bash tests/stop-report.sh — 24 passed, 0 failed
  • bash -n hooks/lib-write-turn.sh — clean
  • Counterexample: reverting only hooks/lib-write-turn.sh turns the new t7b case red (trailing-reason was classified as companion failure) while t7 keeps passing — so the new case isolates exactly the new behaviour and can fail.

Installation impact

The change lands in this repo's hooks/, but dispatches run the installed copy at ~/.claude/hooks/. It takes effect after node install.mjs, not at merge.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of result statuses that include trailing explanatory text.
    • BLOCKED results with additional reasons are now correctly recognized and reported.
    • Preserved the expected blocked outcome, dispatch behavior, and failure classification.
  • Tests

    • Added coverage for blocked results containing trailing reason text.

The result parser only matched a RESULT line whose terminal token was the
entire rest of the line, but the implementer contract in the same file presents
the tokens as "RESULT: BLOCKED — name the blocker". Implementers reasonably
emit that shape, the line failed to match, and a correct run with a correct
report was classified IMPLEMENTER_STATE: COMPANION_FAILURE — exiting 11 without
ever running the caller's --verify.

Accept an optional trailing reason that starts with a punctuation character, so
the parser agrees with the shape its own contract displays. Every existing
rejection survives: RESULT: DONEISH still fails on the token boundary, bare
trailing prose ("RESULT: DONE and everything passed") stays unparseable, and
the ^ anchor keeps the contract's own four indented token lines inert, so a
report quoting the contract cannot self-classify.

The fix goes in the parser rather than the contract wording, because the parser
is the layer that authors the disagreement, and rewording cannot help reports
already written in that shape.

Verified: tests/run.sh 18 passed 0 failed; tests/stop-report.sh 24 passed.
Reverting only lib-write-turn.sh turns the new t7b case red while t7 keeps
passing, so the new case isolates exactly the new behaviour.
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cf09c103-3305-42a5-8d29-90d57dc678ae

📥 Commits

Reviewing files that changed from the base of the PR and between 4951409 and 1790e37.

📒 Files selected for processing (2)
  • hooks/lib-write-turn.sh
  • tests/stop-report.sh

📝 Walkthrough

Walkthrough

The result parser now accepts supported statuses followed by trailing reason text. The stop-report tests add a BLOCKED scenario that verifies exit code 11, one dispatch, and no companion-failure classification.

Changes

RESULT Parsing

Layer / File(s) Summary
Accept trailing RESULT annotations
hooks/lib-write-turn.sh
The parser accepts trailing non-alphanumeric text after DONE, NEEDS_ANSWERS, BLOCKED, or FAILED.
Validate trailing BLOCKED results
tests/stop-report.sh
The test suite adds and registers a trailing-reason BLOCKED scenario. The scenario verifies exit code 11, one dispatch, and no companion-failure classification.

Estimated code review effort: 2 (Simple) | ~10 minutes

Mergeability Score: ⚪ Minimal · up to 1790e

This localized parser change accepts punctuation-delimited reasons on RESULT lines while preserving the existing token boundaries; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the parser fix to accept punctuation-delimited reasons on RESULT lines.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/result-line-trailing-reason

Comment @coderabbitai help to get the list of available commands.

@elkaix
elkaix merged commit 62cff90 into main Aug 13, 2026
2 checks passed
@elkaix
elkaix deleted the fix/result-line-trailing-reason branch August 13, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant