Repository navigation
tri pr preflight: the checks a PR must pass before it opens, as a t27 spec #10190
Description
On 2026-10-18 about 190 pull requests were open, and most of them were red. Some were red for inherited reasons. Others had their own defects: vacuous tests, duplicate bodies, type-name conflicts, deleted tests, missing ledger rows and stale bases. specs/policy/pr_budget.t27 (#10070, #10087) caps how many PRs may be open at once. This issue adds the other half: a preflight that runs before a PR opens, so a PR that opens is already green on what the author can check locally.
The preflight is a t27 spec plus a tri pr preflight subcommand. The spec owns every rule and the verdict. The Rust glue does three things: it runs the commands the spec names, it labels each command's output, and it prints what the spec decides. The Queen publisher (tools/queen/publish.py) runs the preflight in the bee's worktree before gh pr create and skips any branch that does not pass.
The preflight compares the branch against origin/master and runs these checks on the .t27 files the branch adds or modifies under specs/:
t27c check, which parses and typechecks.t27c test-report: it must exit 0 and report 0 vacuous passes (T730, t27c test-report: count executed asserts and flag vacuous passes (sieve C10, T730) #6509).t27c seal <spec> --verify: every hash must MATCH, and a missing seal fails.tri types classifiedandtri types ratchet: the ratchet must stay CLEAN. A conflict is fixed by renaming in the newer spec, never by blessing.tools/dupe_scan.py: no new duplicate body. For an added spec, the report names where the existing body lives, so the author can add auseinstead.- Ledgers:
- A spec the corpus ratchet now calls an UNEXPECTED PASS or FAILURE fails the preflight, and the message says to drop its row or add one.
- An added spec that passes needs a row in
docs/reports/t27b_expectations.json. - A deleted spec must leave both ledgers.
- A new
.github/workflows/*.ymlneedstools/census/in the same change, andtri census pin --gatemust pass. - A modified spec must not have fewer
testblocks than it had onorigin/master. PR spec fix: 1 specs in specs/queen the reference blocks -- rewrite them in t27 (1 of 1) #8879 removed 12 of 26. origin/mastermust be an ancestor of HEAD, so the branch is not on a stale base.
Boundary
- specs/tri/pr/preflight.t27
- gen/rust/tri/pr/preflight.rs
- .trinity/seals/pr_TriPrPreflight.json
- cli/tri/src/main.rs
- cli/tri/src/prcheck.rs
- tools/queen/publish.py
- docs/now/2026-10-18-pr-preflight.md
User Scenarios
- Given a bee branch that deletes
testblocks from an existing spec, when the publisher runstri pr preflightin its worktree, then the preflight exits 1, names the spec and the two test counts, and the branch is not published. - Given a branch that adds a spec with a function body already written elsewhere, when the preflight runs, then it fails the duplicate rule and prints where the existing body lives.
- Given a branch whose changed specs check, test, seal and classify cleanly on a current base, when the preflight runs, then every rule prints PASS and the command exits 0.
- Given a branch based on an old master, when the preflight runs, then the base rule fails and says to merge
origin/masterfirst.
Requirements
- FR-001: Every rule, every verdict and every message MUST live in
specs/tri/pr/preflight.t27, and each rule MUST have atestblock in that spec. - FR-002: The hand-written glue MUST stay within 40 added lines per file and 80 per PR. It MUST only run the commands the spec names, label their output and print the spec's verdict.
- FR-003: The preflight MUST exit 0 only when every rule passes, 1 when any rule fails, and 2 when evidence could not be read.
- FR-004: The publisher MUST NOT run
gh pr createfor a branch whose preflight did not exit 0. - FR-005: A finding that is inherited from master and does not name a changed spec MUST NOT fail the ledger rule.
Success Criteria
t27c test-report specs/tri/pr/preflight.t27reports 0 FAIL and 0 vacuous passes, andt27c seal specs/tri/pr/preflight.t27 --verifyexits 0.- Replayed on at least 3 open bee PRs, including spec fix: 1 specs in specs/queen the reference blocks -- rewrite them in t27 (1 of 1) #8879, the preflight's verdict agrees with each PR's own-defect CI failures. The replay is recorded in the PR body.
- The glue adds at most 80 hand-written lines, across
main.rs,prcheck.rsandpublish.py.
Activity
spec(tri/pr): preflight -- the rules a PR must pass before it opens (…
spec(tri/pr): preflight -- the rules a PR must pass before it opens (C…