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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

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

opened this

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.ts is new, and pickNext in src/checks/service.ts takes a new optional outside argument. 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 wrote outside_lane.ts fresh.
  • 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 existing approveGuestPull approval 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.ts and test/boundary-tokens-apphost.test.ts to match, because they pinned the old wording.
  • Tests: test/outside-lane.test.ts covers 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.md says both in a sentence each, and the stale pull_trust.ts header 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_plan or estimate, 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

3 earlier comments · 1 event
commented

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.ts is new, and pickNext in src/checks/service.ts takes a new optional outside argument. 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 wrote outside_lane.ts fresh.
  • 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 existing approveGuestPull approval 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.ts and test/boundary-tokens-apphost.test.ts to match, because they pinned the old wording.
  • Tests: test/outside-lane.test.ts covers 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.md says both in a sentence each, and the stale pull_trust.ts header 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_plan or estimate, 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.

commented

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.ts and test/outside-lane.test.ts to fit 100 columns.
  • Cast: In test/outside-lane.test.ts I removed the as never on the AppsRuntime options. That object already satisfies RuntimeOptions, 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.

Changes requested — before the latest 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.

  1. 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.
  2. 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).
  3. 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.
  4. The preview test calls the private mayRun through a cast. Test through the public behaviour, or export a small function and test that.
commented

All four of sentinel's points are addressed and pushed.

  1. 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.

  1. Starvation bound: I removed OUTSIDE_STARVATION_MS, the matching branch of ownersFirst, its now parameter 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.
  2. Docs: The doc now says what src/checks/outside.ts actually 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.
  3. Preview test: The decision is now an exported previewMayRun in src/apps/preview_gate.ts, and runtime.mayRun calls 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.

commented

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: main added an owner-rank argument to pickNext (the check queue's choice of which check runs next; #12230), while this pull had added an outside argument for the outside-contributor lane. I kept both, in the order rank, then outside. The scheduler in service.ts now builds rankOnce and outsideOnce together and passes both to pickNext.
  • The test fix: test/outside-lane.test.ts passed outside in the position that is now rank, so I changed its four pickNext calls to pass () => undefined for 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.
Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs