Repository navigation
t27b-lab: judge a lane request's on-origin against a fresh fetch of origin master, not the master the lab last ran #8785
Description
Found by the MVP acceptance lane. Root cause of lost lane receipts on t27b-lab.
Problem
lane_request() in contrib/railway/t27b-lab/lab.py builds the "on origin" set from git ls-remote --heads plus git rev-list --first-parent <master> in CLONE, where <master> is the master the lab LAST RAN. A squash commit that landed after that run is NOT_ON_ORIGIN until the lab's next master run. Its request waits as WAIT_ORIGIN and is dropped once it has waited longer than REQUEST_ORIGIN_GRACE_S. That dropped 6a7b774 (MVP v2, see #8685) on 2026-10-10. The grace went from 30 min to 2 h (see #8320 and see #8715); that softened the symptom and left the cause.
Change
lane_request()fetches origin's REF into its remote-tracking ref (CLONE's checkout does not move) and reads the first-parent line of that fresh ref, plus the ls-remote heads. The master the lab last ran no longer matters.- Hand-written Python stays net <= 0 lines (check_budget, see policy: hand-written code in any language but t27 may only shrink (Closes #8227) #8236).
- specs/verified/corpus_receipt.t27: the comment that says the lab judges on-origin against the master it last ran is corrected, and a test pins the verdicts for a squash commit that is newer than the last master run. request_verdict and request_exit do not change; WAIT_ORIGIN (see verified(corpus_receipt): a request the lab has not fetched yet waits 30 min instead of being dropped (Closes #8320) #8329) and the 2 h grace stay.
- Kept as they are: requests skip the fuzzer (see t27b-lab: a lane request skips the fuzzer (Closes #8267) #8268), and up to two requests run per master run (see t27b-lab: take up to two lane requests per master run (Closes #8586) #8588).
Acceptance criteria
- A scripted reproduction on t27b-lab: with CLONE at an older master M0 and a sha X on origin master's first-parent line newer than M0, master's lab.py leaves X as WAIT_ORIGIN, and drops it as NOT_ON_ORIGIN once X is older than the grace. The PR's lab.py admits X and runs it.
- A waiting request survives a lab restart. /srv/requests is on the volume, the age comes from the file's mtime, and nothing is judged before master's t27c exists.
- Both labs are redeployed right after each one publishes a run, and each lab's /status.json image.lab_py_sha equals
git hash-objectof master's lab.py. - Live: a request for a just-merged squash commit, written before the lab's next master run, is admitted, not dropped.
Boundary
contrib/railway/t27b-lab/lab.py
specs/verified/corpus_receipt.t27
bootstrap/gen/rust/verified/corpus_receipt.rs
.trinity/seals/verified_VerifiedCorpusReceipt.json
User Scenarios
- Given a lab CLONE at master commit M0 and a squash commit X on origin master's first-parent line that is newer than M0, When the lab processes a lane request for X, Then the request is admitted and run (not left as WAIT_ORIGIN or dropped as NOT_ON_ORIGIN).
- Given a waiting request for commit X that is older than REQUEST_ORIGIN_GRACE_S, When the lab restarts, Then the request survives the restart and its age is still derived from the file's mtime in /srv/requests.
- Given both labs have just published a run, When they are redeployed, Then each lab's /status.json image.lab_py_sha equals
git hash-objectof master's lab.py.
Requirements
- FR-001:
lane_request()in contrib/railway/t27b-lab/lab.py MUST fetch origin's ref into its remote-tracking ref and read the first-parent line of that fresh ref plus the ls-remote heads to judge on-origin. - FR-002: The master the lab last ran MUST no longer be used for on-origin judgment.
- FR-003: Hand-written Python in contrib/railway/t27b-lab/lab.py MUST stay net <= 0 lines (check_budget).
- FR-004: specs/verified/corpus_receipt.t27 MUST correct the comment about judging on-origin against the master the lab last ran and MUST add a test pinning verdicts for a squash commit newer than the last master run.
- FR-005: request_verdict and request_exit MUST NOT change; WAIT_ORIGIN and the 2 h grace period MUST stay as they are.
- FR-006: Requests MUST continue to skip the fuzzer and up to two requests MUST run per master run.
Activity
gHashTag commentedon Oct 10, 2026
Landed in #8786 (squash 97d6772). Deploy and live evidence below.
Deploy
Each lab was deployed with
railway up --detachfromgit archive origin/master contrib/railway/t27b-lab, right after it published a master run. Both deploys landed in the idle POLL window, so no run was cut short.railway upOn both labs,
/status.jsonimage.lab_py_sha = 0cbb6a2c7930d4612b7382085163fa102790ca7c =git rev-parse origin/master:contrib/railway/t27b-lab/lab.py.Live: a squash newer than the lab's last master run is admitted (t27b-lab)
lane request '9be6ba8153f253ad6710a121c65137444fd0f650' 907,1,1: ADMIT.lane request '9be6ba8153f253ad6710a121c65137444fd0f650' 1775,0,1: ADMIT.Live: a waiting request survives the restart (t27b-lab)
Another lane requested 738771f (squash of #8776, landed 20:14:14Z); its request file has mtime 20:23:41Z.
lane request '738771f781b0a29cb821b4806808326dca842239' 475,0,0: WAIT_ORIGIN. This is the bug, live: the commit was 17 min on master, and it read as not on origin.1828,0,1: ADMIT. The age counts from the file's mtime, across the restart.Note
While I was setting this up, I overwrote that lane's request file for 738771f with my own challenge for 35 s (20:29:20Z to 20:29:55Z). I then restored it byte for byte from the lane's challenge file (challenge 8679a9a1...). Its mtime is set to 20:23:41Z, the time that lane wrote the challenge. No judge ran in that window, because the lab was mid master run.