review_now.py parses dispatch.py's prose, and nothing binds the two nf-2ccf ← Beads

open priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/585 by tools/beads/import_github.py's reconcile pass.

tools/pr/review_now.py (new in #578) decides what to tell the session by string-matching dispatch.py's human-readable stdout. Nothing binds the two. Rename a dispatcher log line and review_now silently starts reporting the wrong outcome — no test fails, no error, just a confident sentence that is not true.

Measured, now

Nine literals in conclusion() are load-bearing, and all nine currently appear in dispatch.py:

``` '#{number}: done' 'delta re-verified' 'up to date' '#{number}: FAILED' 'no review ever requested' 'reviewer muted for this PR' 'review in flight' 'skip (' 'backoff' ```

That they all match today is luck plus recency, not a guarantee — the check above is a script I ran by hand, not something in the suite.

This exact class already bit, in the same PR

conclusion() shipped with an unreachable branch: the dispatcher's fresh-failure line is

``` #N: FAILED — see <log> (backoff 45m; rev:pending stays on; --force retries) ```

which contains the word "backoff", so a backoff test placed first swallowed it and reported a just-failed spawn as a pre-existing one, in the wrong tense, dropping the log pointer.

The root cause was in the test, and it is the same coupling problem one layer down: ConclusionTest fed *paraphrases* of the dispatcher's lines rather than the lines themselves, and the paraphrase dropped the one word that distinguished the two branches. Both branches passed against inputs that could not tell them apart. #578 pins the real strings as named constants, which fixes the two known cases and does nothing for the tenth literal someone adds next.

The repo has already solved this class once

nflib/verdict.py's docstring:

> ⚠️ CHARTER.md is the authority; nflib/verdict.py is the only parser. This line was stale for months — it lost CONVERGED when that result was added, because the schema existed in four places and no place at all. A contract test in test_nflib_verdict.py now reads CHARTER.md and fails if the parser and the charter disagree.

Design 001 §2.6 states the principle: *prompt files are source code*. The same argument applies to a sibling tool's stdout vocabulary — it is an interface, it just is not spelled like one.

Shapes of a fix

Unclaimed. Found working #576; not folding it into that chunk.

Dependencies

None.

Comments

No comments.

Add a comment