Skip to content

Gate integrity: one prompt, a status for every verdict, the range on the fact - #102

Merged
abedegno merged 16 commits into
mainfrom
spec/back-half-closed-loop
Sep 19, 2026
Merged

abedegno merged 16 commits into
mainfrom
spec/back-half-closed-loop

Conversation

@abedegno

Copy link
Copy Markdown
Owner

What

Gate integrity, the first of the five PRs in docs/superpowers/specs/2026-09-19-back-half-closed-loop-design.md (§4).

  • One reviewer prompt, in the coordinator, naming the range origin/<base>...<head>; the bash copy and the byte-identity test are gone.
  • The derivation posts bircher/cross-review for every verdict: success / failure (with the blocking count) / error, described as <vendor> round <n> <word> on <merge-base7>..<head7>, through the journalled effect path.
  • The verdict fact records head_sha, merge_base_sha and delta_digest (schema version 2); the runner passes them through a ten-field derivation tuple.
  • The delta digest has one implementation, in Python, used by the derivation and by the runner's re-stamp.
  • The runner's own status post is now an idempotent fallback that keeps the reviewed description.

Why

On muesli PR #769 a cross-review of one commit posted a green gate on a 38-file PR, and a later FAIL posted nothing, leaving that green standing. The record is docs/design/front-half-live-log.md. Supersedes #101.

Verification

  • cd v2 && python -m pytest -q: all green.
  • bash batch/run-queue.sh --self-test: rc 0 as a non-root user (the runner's root-only self-test failure is pre-existing and unrelated).
  • Acceptance lines from the spec satisfied here: every recorded verdict has a status whose state matches the verdict and whose description names the range; the pipeline's reviewer prompt exists once (Python) and names the range, and the cross-review skill's template now names it too.
  • Final whole-branch review (8 Important, 10 Minor) fixed in 488bee5, ecbb7ef, 56eef8e; three Minor residuals on the blocking-finding count's heading detection are recorded for a follow-up issue.

The reviewer prompt now exists once, in coordinator/review.py. The bash
copy (_recovery_review_prompt in batch/run-queue.sh) and the test that
kept the two byte-identical are gone.

review_prompt and dispatch take a base parameter and tell the reviewer
the PR's merge-base range (git diff origin/{base}...{co}), not just the
pinned head commit -- a reviewer once read "EXACTLY commit X" as "only
the head commit's own diff" and passed a 38-file PR after reading one
file. wiring.py's do_review resolves the PR's base via gh and passes it
through.

Deleting 80 lines from run-queue.sh moved every line-numbered citation
below it, so docs/design/effect-site-inventory.md and
docs/design/scar-effect-matrix.md are repointed with
tools/repoint-citations.py (baseline HEAD) to keep test_routing.py and
test_scar_equivalence.py green.
…llow the reviewers

The status key was `status:<head>:<round>`, and the round only advances on a
recorded review_verdict fact -- which an `error` or a terminal FAIL does not
write. A later PASS on the same head therefore replayed the earlier key and
the kernel returned the prior external id without executing: the gate kept
showing the superseded verdict. The key is now content-addressed over the
state and the description, as the PR comment's key already was.

blocking_count missed the heading shapes live reviewers actually write:
`## Blocking findings` and `### **Blocking findings**` counted nothing, a `##`
closing heading did not close, a prose trailer on a closer did not close, a
parenthetical section count was counted as a finding, and the phrase
continuing as prose opened a section and counted the sentence. Fixtures for
every one of those, measured.

Also: the reviewer's setup fetches the base branch it is told to diff against,
so `origin/<base>` exists in its clone on a non-default base; the merge-base
gets the same 40-hex validation the head gets before it reaches the tuple, the
description and the runner's hand-built JSON; `delta_digest` catches OSError so
a missing `gh` binary is an unprovable delta rather than a traceback; the
status log line says "recorded", since an idempotent replay posts nothing; and
`_round_number` has a test proving it ever returns more than one.
…ict carries it

_post_cross_review_status's default description is legacy text that names
nothing, and it fires in exactly one case: the derivation's own post did not
land, or could not be read back. There it OVERWROTE the merge head's
range-naming description -- the status ceasing to attest to anything at the
one moment it is the only record. run_item holds the merge-base and the
observed head at its merge_ready_pr call site, so it composes the fallback
description there and merge_ready_pr threads it through; every other caller
passes none and keeps the legacy text, which is all that can honestly be said
when the range is unknown.

recover_pr_cmd parsed the tuple's two range fields into `_ _` and recorded a
verdict with no range at all, though it drives the same derivation run_item
does. It now reads them and passes them as record_review's arguments 9-11.

Minors: the composed re-stamp description is truncated to GitHub's 140 (it is
longer than that by construction, and the overflow cut the suffix saying it
was a re-stamp); the two delta CLI calls no longer discard stderr, and the
escalation says the CLI failing is one of the causes; the status POST quotes
its state argument like every other.

Tests: the self-test drives merge_ready_pr both ways and reads the description
off the POST (verified by mutation: dropping the argument fails it); the
recovery's reader width is asserted against Derived.FIELDS beside run_item's.
…ange

ARCHITECTURE.md still described the derivation's boundary as an eight-field
tuple and listed "the eight-field boundary's fail-closed width check" among
the things that are done. It is ten, and the two new fields are the point of
this branch: the merge-base and the three-dot delta digest of what the
reviewer read. Both are named, with what they carry and why.

skills/cross-review/SKILL.md carries a SECOND reviewer template -- the lead
session's, pinned to FETCH_HEAD -- and it said nothing about a range, so the
prompt fixed in the coordinator was still wrong in the place a human copies
from. It now carries the same sentence, adapted to its placeholders, and
fetches the base branch it is told to diff against.
@abedegno
abedegno merged commit bb402d4 into main Sep 19, 2026
2 checks passed
@abedegno
abedegno deleted the spec/back-half-closed-loop branch September 19, 2026 18:32
@abedegno abedegno mentioned this pull request Sep 20, 2026
3 tasks done
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