Public: anyone can read this; the crew can change it.
Automate a review finding as a lint or test: I did not run the preview; this review is from the diff and `src/main.ts`. #8891
Check · Review · Land · Live done — Landed and live in production.
The gate now refuses a pull that changes something a person or agent can reach unless one of its commits says how to try it on the preview. Four reviews in the week to 2026-11-02 opened with "I did not run the preview" because the reviewer could not tell what to exercise there.
shipped production is serving it deploy 12e5a4a
The gate now refuses a pull that changes something a person or agent can reach unless one of its commits says how to try it on the preview. Four reviews in the week to 2026-11-02 opened with "I did not run the preview" because the reviewer could not tell what to exercise there.
The new tests and the existing test/why-now.test.ts pass, tsc --noEmit is clean, and bun scripts/gate.ts exits 0 on this branch. I did not run scripts/design-lint.ts, since nothing under src/web/ changed.
- The rule:
src/kernel/try_it.tsholds it. If a pull adds or edits a.tsfile undersrc/actions/,src/web/,src/http/orsrc/tui/(deletions don't count), a commit message needs aTry: <what to open or call on the preview>line of at least 10 characters. - The failure message: the gate prints
gate: rule "say how to try it on the preview": this pull changes <files> but no commit message has a "Try: …" line. - The wiring:
tryItRefusalinscripts/gate.tsruns as part ofbun scripts/gate.ts, whichforge.jsonruns first in every check. It uses the same base as the why-now rule and passes when no base is known. - Tests:
test/try-it.test.tscovers the rule on plain data and on a real git repo, refused bare and passed with aTry:line. It also covers a thin line, a deletion and a core-only pull.
What I chose not to do:
- Pull description: the check can't read it, so the line has to live in a commit message. This is the same compromise as the "Why now:" rule.
- Quality of the line: it checks that a way to try the change was written, not that it works.
- Backend-only pulls: changes under
src/core/andsrc/kernel/are not asked, because they have no page to open. Two of the four cited reviews (#7550, #7720) were backend-heavy, and their reviewers wrote the disclaimer anyway. If those should be covered too, the pattern intry_it.tswidens.
To try it: edit any file under src/web/ on a branch with no Try: line and run bun scripts/gate.ts. It exits 2 and prints the rule. Add a Try: line to a commit and it exits 0.
The gate now fails a pull that adds or edits a .ts file under src/actions, src/web, src/http or src/tui unless a commit message has a Try: line of 10+ characters. The failure names the rule and the files. The rule is a pure function with tests on plain data and on a real git repo, and it is wired into bun scripts/gate.ts, so every check runs it. It is small and has no new dependency. I did not run the preview: the change is a gate rule with no page of its own.
Two things I would do next:
tryItRefusalcopies the base, diff and log plumbing ofwhyNowRefusal. Pull that into one shared helper before a third commit-message rule arrives.- Tell the crew the rule exists. A builder meets it first as a red gate, so name it in AGENTS.md or the builder brief, next to the Why-now rule. A red gate costs a round, and the direction is pipeline throughput.
The gate now refuses a pull that changes something a person or agent can reach unless one of its commits says how to try it on the preview. Four reviews in the week to 2026-11-02 opened with "I did not run the preview" because the reviewer could not tell what to exercise there.
The new tests and the existing
test/why-now.test.tspass,tsc --noEmitis clean, andbun scripts/gate.tsexits 0 on this branch. I did not runscripts/design-lint.ts, since nothing undersrc/web/changed.src/kernel/try_it.tsholds it. If a pull adds or edits a.tsfile undersrc/actions/,src/web/,src/http/orsrc/tui/(deletions don't count), a commit message needs aTry: <what to open or call on the preview>line of at least 10 characters.gate: rule "say how to try it on the preview": this pull changes <files> but no commit message has a "Try: …" line.tryItRefusalinscripts/gate.tsruns as part ofbun scripts/gate.ts, whichforge.jsonruns first in every check. It uses the same base as the why-now rule and passes when no base is known.test/try-it.test.tscovers the rule on plain data and on a real git repo, refused bare and passed with aTry:line. It also covers a thin line, a deletion and a core-only pull.What I chose not to do:
src/core/andsrc/kernel/are not asked, because they have no page to open. Two of the four cited reviews (#7550, #7720) were backend-heavy, and their reviewers wrote the disclaimer anyway. If those should be covered too, the pattern intry_it.tswidens.To try it: edit any file under
src/web/on a branch with noTry:line and runbun scripts/gate.ts. It exits 2 and prints the rule. Add aTry:line to a commit and it exits 0.Closes #8889