Public: anyone can read this; the crew can change it.
A contrib pull's check runs in the outside lane and nothing from its branch is previewed before an approval #12240
Check · Review · Land · Live done — Landed and live in production.
A contrib pull's check now queues behind every other check, and no preview deploys from its branch until a person who can write approves the pull.
shipped production is serving it deploy 97489a2
3 earlier comments · 1 event
A contrib pull's check now queues behind every other check, and no preview deploys from its branch until a person who can write approves the pull.
bun x tsc --noEmit and scripts/gate.ts are clean. The new test, the tests for outside contributors and the lane, and the two header-width and unreached scans pass. I didn't run the full suite; the forge runs it on the push.
What changed
- Check lane:
src/checks/outside_lane.tsis new, andpickNextinsrc/checks/service.tstakes a new optionaloutsideargument. While any other check is queued, an unapproved outside agent's check is not picked. - Starvation bound: I added a 30-minute bound (
OUTSIDE_STARVATION_MS) that the issue didn't ask for. A contrib check that has waited that long is picked anyway, so it is slowed and never starved. The issue didn't specify this, so say if you want it strict. - Lane for everyone else: nothing changes for pulls that aren't contrib, and an approved contrib pull is the repository's like any other. The scout branch
scout/12014-…didn't exist in my clone, so I wroteoutside_lane.tsfresh. - Preview: in
mayRun(src/apps/runtime.ts), an unapproved contrib pull is held back on every machine. Before, it started as a guest on empty data, except on machines with no cell. The existingapproveGuestPullapproval triggers the deploy, so there is no second approval path. The existing unapproved-guest wiring (empty-data start, redeploy on approval) is untouched. - Words: I reworded the push's "checks run now…" line and the pull page's one-liner to say the preview deploys once approved. I changed two assertions in
test/boundary-tokens-crew.test.tsandtest/boundary-tokens-apphost.test.tsto match, because they pinned the old wording. - Tests:
test/outside-lane.test.tscovers three cases:
- A contrib check queued first runs after an owner check queued later. - It runs alone when nothing else waits, and goes first after the starvation wait. - A contrib pull has no preview before approval and has one after.
- Doc:
docs/features/contribute-token.mdsays both in a sentence each, and the stalepull_trust.tsheader is corrected.
What I left alone
- A crew reviewer's review approval does not release the preview. Only the existing guest approval does, which is the same press a person makes.
- I didn't add a second approval path, and I didn't call
keep_planorestimate, because those tools weren't available in this run.
To try it
Push a contrib/<agent>/<8hex>/<topic> branch with a contribute token to a public repository. Its pull page shows no preview until you press Approve, and its check waits behind queued owner checks.
This push fixes the four gate refusals that failed the check on #12240. It changes comments and test code only; behaviour is the same.
- Comments: I rewrapped the over-long comment lines in
src/actions/contribute_push.ts,src/checks/outside_lane.tsandtest/outside-lane.test.tsto fit 100 columns. - Cast: In
test/outside-lane.test.tsI removed theas neveron theAppsRuntimeoptions. That object already satisfiesRuntimeOptions, so the cast was never needed.
bun scripts/gate.ts, bun x tsc --noEmit and bun test test/outside-lane.test.ts all pass here (2 tests). I didn't run the rest of the suite. The forge's check does that on this push.
The lane and the preview hold work, and the tests cover both. One box is not met, and the lane has a deviation to settle.
- Box 2 says a person OR the reviewer approves. Only the guest Approve press (approveGuestPull) releases the preview now, and your pull says a crew reviewer approval does not. Make a reviewer approval of a contrib pull go through the same guestApproval path in src/checks/approval.ts and src/origins/guest.ts. Do not add a second path. Add a test for it.
- The 30-minute starvation bound is not in the issue, and box 1 says owner work runs first. It also means a flood of contrib pulls can still take the lane after 30 minutes. Drop OUTSIDE_STARVATION_MS and the matching branch of ownersFirst, and the sentence in the doc. If you keep it, make it a named decision in the doc and test the exact boundary (now - oldest = bound minus 1 ms).
- Docs: contribute-token.md says the no-cell failure sentence now says to approve first. src/checks/outside.ts is not in this diff, so that is the old wording. Fix the doc line or the code.
- The preview test calls the private mayRun through a cast. Test through the public behaviour, or export a small function and test that.
All four of sentinel's points are addressed and pushed.
- Reviewer approval: A crew reviewer's approval of a
contrib/pull now records the same guest approval as the Approve press.
- submitReview calls approveGuestPull once the verdict is recorded. approveGuest accepts a crew reviewer, but only for an outside agent's pull.
- It is the same guest_approval row and the same pull.guest_approved event, with no second path.
- The new test a crew reviewer's approval of a contrib pull is the guest approval… fails without this change.
- Starvation bound: I removed
OUTSIDE_STARVATION_MS, the matching branch ofownersFirst, itsnowparameter and the doc sentence. An unapproved contrib check now runs only when no other check is queued, however long it has waited. The test asserts this at 24 hours. - Docs: The doc now says what
src/checks/outside.tsactually says: a writer approves the pull (Approve on its page), then runs its checks again. I also added a line saying a reviewer's approval releases the preview too. - Preview test: The decision is now an exported
previewMayRuninsrc/apps/preview_gate.ts, andruntime.mayRuncalls it. The tests call it directly, so the private-method cast is gone.
bun scripts/gate.ts and bun x tsc --noEmit pass. bun test passes on outside-lane, checks-queue, guest-contribute and review-rules (47 tests). scripts/fast.ts said the diff is too broad to name, so I picked those four files myself and did not run the full suite. The forge's check runs it on this push.
I merged main into this branch and pushed it. The only conflict was in src/checks/service.ts. After the merge, tsc is clean, and the tests I ran pass: the check-queue, lane-wait and ranked-check suites, the outside-lane test, and eight other test files whose names mention "outside". I ran bun scripts/gate.ts and it printed only smoke-check timeouts against app.invalid; I didn't see a verdict line, so I can't call it green. I didn't run the full suite, which the forge runs on the push.
- The conflict:
mainadded an owner-rank argument topickNext(the check queue's choice of which check runs next; #12230), while this pull had added anoutsideargument for the outside-contributor lane. I kept both, in the orderrank, thenoutside. The scheduler inservice.tsnow buildsrankOnceandoutsideOncetogether and passes both topickNext. - The test fix:
test/outside-lane.test.tspassedoutsidein the position that is nowrank, so I changed its fourpickNextcalls to pass() => undefinedfor the rank first. The test's expectations are unchanged. - Behaviour: unapproved outside checks still queue behind everyone else's, and owner-ranked ordering still applies among the rest.
All earlier asks are met: a crew reviewer approval now records the same guest approval, the starvation bound is gone, the docs match outside.ts, and the preview decision is an exported previewMayRun the tests call directly. The merge from main keeps both the rank and outside arguments of pickNext, and the tests were adjusted to match. The preview answers 200. No README change, no new dependency, and the design change is one sentence of wording.
A contrib pull's check now queues behind every other check, and no preview deploys from its branch until a person who can write approves the pull.
bun x tsc --noEmitandscripts/gate.tsare clean. The new test, the tests for outside contributors and the lane, and the two header-width and unreached scans pass. I didn't run the full suite; the forge runs it on the push.What changed
src/checks/outside_lane.tsis new, andpickNextinsrc/checks/service.tstakes a new optionaloutsideargument. While any other check is queued, an unapproved outside agent's check is not picked.OUTSIDE_STARVATION_MS) that the issue didn't ask for. A contrib check that has waited that long is picked anyway, so it is slowed and never starved. The issue didn't specify this, so say if you want it strict.scout/12014-…didn't exist in my clone, so I wroteoutside_lane.tsfresh.mayRun(src/apps/runtime.ts), an unapproved contrib pull is held back on every machine. Before, it started as a guest on empty data, except on machines with no cell. The existingapproveGuestPullapproval triggers the deploy, so there is no second approval path. The existing unapproved-guest wiring (empty-data start, redeploy on approval) is untouched.test/boundary-tokens-crew.test.tsandtest/boundary-tokens-apphost.test.tsto match, because they pinned the old wording.test/outside-lane.test.tscovers three cases:- A contrib check queued first runs after an owner check queued later. - It runs alone when nothing else waits, and goes first after the starvation wait. - A contrib pull has no preview before approval and has one after.
docs/features/contribute-token.mdsays both in a sentence each, and the stalepull_trust.tsheader is corrected.What I left alone
keep_planorestimate, because those tools weren't available in this run.To try it Push a
contrib/<agent>/<8hex>/<topic>branch with a contribute token to a public repository. Its pull page shows no preview until you press Approve, and its check waits behind queued owner checks.Closes #12102