Repository navigation
t27b lab: lab 2 serves lane requests first; the run loop's next step is decided in corpus_receipt.t27 #9026
Copy link
Copy link
Closed
Labels
Description
Constraint 8 of the downtime epic (see #9025): a lane receipt from the t27b lab takes 1-2 h.
Problem
- Both Railway labs (t27b-lab, key a05db80f53c317f6; t27b-lab-2, key fed03daa6459a7fa) run the same lab.py and both run every master commit: duplicated work by one operator.
- In
contrib/railway/t27b-lab/lab.pymain(), a moved master always runs first (18-22 min on lab 1, about 15 min on lab 2), then at most two lane requests (see t27b-lab: take up to two lane requests per master run #8586). A queued request therefore waits behind every master run; a queue of 4 takes about 100 min on lab 1. - The loop's scheduling decision is hand-written Python. Admission is already t27 (
request_verdict, specs/verified/corpus_receipt.t27); the choice of what runs next is not.
Plan
- specs/verified/corpus_receipt.t27 (extend, no new spec): a pure
lab_next(role, master_moved, judge_ready, admitted, requests_since_master)answering NEXT_MASTER / NEXT_REQUEST / NEXT_IDLE, with- ROLE_MASTER_FIRST: today's loop (a moved master runs first, then up to REQUESTS_PER_MASTER = 2 requests per cycle);
- ROLE_REQUESTS_FIRST: an admitted request runs before a master run, with a starvation guard (after REQUEST_BURST_MAX consecutive requests a moved master runs once);
- no judge -> master run (it builds the judge).
Named constants, NAMES arrays, tests for every branch, and a test that ROLE_MASTER_FIRST replays today's loop.
t27c corpus-receipt schedule -- ROLE FACTS: a fourth action in the existing glue, generated logic only.- lab.py:
T27_LAB_ROLE(default master_first); the loop asks the judge what runs next; the only hand rule is the bootstrap case (no judge yet -> master run). Net hand-written lines across lab.py and the glue <= 0 (see policy: hand-written code in any language but t27 may only shrink (Closes #8227) #8236). - AGENTS.md lane evidence: request from t27b-lab-2, and take base and head receipts from the same lab.
- Deploy both labs from master; T27_LAB_ROLE=requests_first on t27b-lab-2 only; lab 1 stays master-first.
Success criteria
- Both labs' /status.json show the new lab_py_sha; lab 2 reports role requests_first.
- A request submitted to lab 2 for a recent master commit gets its receipt published, with the measured request -> receipt time reported here (before: 1-2 h on lab 1).
- corpus_receipt.t27 seal, gen output and t27b ledger row updated; all checks green.
User Scenarios
- Given a lane request is queued on t27b-lab-2 while a master commit has moved, When the lab's run loop decides what to execute next, Then the admitted request runs before the next master run because the lab operates in ROLE_REQUESTS_FIRST mode.
- Given t27b-lab-1 has no judge built yet for a new master commit, When the run loop starts, Then a master run executes first (bootstrap case) regardless of role setting.
- Given t27b-lab-2 has executed REQUEST_BURST_MAX consecutive requests without a master run, When the run loop decides the next step, Then a moved master runs once as a starvation guard before further requests are admitted.
Requirements
- FR-001: specs/verified/corpus_receipt.t27 MUST define a pure
lab_next(role, master_moved, judge_ready, admitted, requests_since_master)function returning NEXT_MASTER / NEXT_REQUEST / NEXT_IDLE with named constants and NAMES arrays. - FR-002: The spec MUST implement ROLE_MASTER_FIRST behavior matching today's loop (moved master first, then up to REQUESTS_PER_MASTER=2 requests per cycle) and ROLE_REQUESTS_FIRST behavior (admitted request before master, with REQUEST_BURST_MAX starvation guard).
- FR-003: The spec MUST include tests for every branch and a test that ROLE_MASTER_FIRST replays today's loop exactly.
- FR-004: t27c MUST expose a
corpus-receipt schedule -- ROLE FACTSaction that invokes the generatedlab_nextlogic. - FR-005: contrib/railway/t27b-lab/lab.py MUST read T27_LAB_ROLE (default master_first) and call the judge's schedule action to decide the next step, keeping only the bootstrap rule (no judge -> master run).
- FR-006: Net hand-written lines across lab.py and the glue MUST be <= 0 relative to the current codebase.
- FR-007: AGENTS.md MUST document that lane evidence comes from t27b-lab-2 and that base and head receipts are taken from the same lab.
- FR-008: Deployment MUST set T27_LAB_ROLE=requests_first on t27b-lab-2 only; t27b-lab-1 remains master_first.
Success Criteria
t27c seal specs/verified/corpus_receipt.t27exits 0t27c gen specs/verified/corpus_receipt.t27exits 0 and updatesbootstrap/gen/rust/verified/corpus_receipt.rspython -m pytest specs/verified/corpus_receipt.t27exits 0 with at least 5 tests covering all branches and the replay testgrep -q 'T27_LAB_ROLE=requests_first' contrib/railway/t27b-lab/lab.pyexits 0grep -q 'requests_first' AGENTS.mdexits 0- Both labs'
/status.jsonendpoints report the newlab_py_sha; lab 2 reportsrole: "requests_first" - A request submitted to lab 2 for a recent master commit receives a published receipt with measured request→receipt time < 60 min (previously 1-2 h on lab 1)
- All CI checks green
Boundary
- specs/verified/corpus_receipt.t27
- contrib/railway/t27b-lab/lab.py
- AGENTS.md
- bootstrap/gen/rust/verified/corpus_receipt.rs
Reactions are currently unavailable
Activity
t27b lab: lab 2 serves lane requests first; the run loop asks corpus_…
seals: leave queen_QueenGoldenChain.json to the t27b session's own re…
Merge origin/master into feat/lab-requests-first: the GoldenChain sea…
seals: leave queen_QueenHolds.json to the t27b session's own re-save (C…
Merge origin/master into feat/lab-requests-first: the QueenHolds seal…
t27b lab: lab 2 serves lane requests first; the run loop asks corpus_…
gHashTag commentedon Oct 11, 2026
Landed in #9055 (squash 0bc7549, 2026-10-11T12:31:08Z) and deployed.
Deploy
Both services were redeployed with
railway upof a cleangit archive 0bc75496f contrib/railway/t27b-lab.T27_LAB_ROLE=requests_first, the only variable changed. Live at 12:33:12Z. It first reportedrole: requests_firstin /status.json at 12:50:01Z, after its bootstrap master run of a9ad525 built the judge.Lead time: request -> receipt published
Before (lab 1, master first; its own logs, 55 request runs, 2026-10-09..11): median 70 min, mean 79, max 168. The run itself takes about 15 min; the rest is waiting behind master runs.
After (lab 2, requests_first): one live request for master commit 0bc7549, with a fresh 32-byte challenge kept off the record.
941,0,1: ADMIT) and started at once/runs/0bc75496f....receipt.json)t27c corpus-receipt compare R R --challenge c --challenge-head cgives FRESH on both sides, EQUIVALENT, exit 0.Left
scripts/tri_loop/t27b.py(its LAB constant) andspecs/tri/lab/receipt.t27(LAB_URL, used bytri lab receipt --sha A --sha B) still read lab 1 only. The t27b session is repointing t27b.py.specs/jobs/network_job.t27still says lab 2 "has no request path". It now has one: plain ssh to its service instance, as AGENTS.md shows.comparerefusing mixed-lab evidence is not done: the quorum's 2-of-2 EQUIVALENT compares two keys on the same commit (see receipts: more than one signer -- the t27b lab must not be the network's only validator #8606). A narrower rule (different keys AND different commits) is a separate decision.loop: t27b.py reads the lab from T27B_LAB, so lane receipts on lab 2 …