Skip to content

tri pr preflight: the checks a PR must pass before it opens, as a t27 spec #10190

Open

Description

@gHashTag

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/:

  1. t27c check, which parses and typechecks.
  2. 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).
  3. t27c seal <spec> --verify: every hash must MATCH, and a missing seal fails.
  4. tri types classified and tri types ratchet: the ratchet must stay CLEAN. A conflict is fixed by renaming in the newer spec, never by blessing.
  5. 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 a use instead.
  6. 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.
  7. A new .github/workflows/*.yml needs tools/census/ in the same change, and tri census pin --gate must pass.
  8. A modified spec must not have fewer test blocks than it had on origin/master. PR spec fix: 1 specs in specs/queen the reference blocks -- rewrite them in t27 (1 of 1) #8879 removed 12 of 26.
  9. origin/master must 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 test blocks from an existing spec, when the publisher runs tri pr preflight in 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/master first.

Requirements

  • FR-001: Every rule, every verdict and every message MUST live in specs/tri/pr/preflight.t27, and each rule MUST have a test block 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 create for 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.t27 reports 0 FAIL and 0 vacuous passes, and t27c seal specs/tri/pr/preflight.t27 --verify exits 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.rs and publish.py.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions