Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/t27b-loop/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Take the first unchecked item of epic #8326 that is not already claimed, either
- **Bring the files back to a sparse worktree on the Mac.** `git worktree add --no-checkout`, `git sparse-checkout set --no-cone <paths>`, then copy each file with `ssh ... cat`. `gen/` is gitignored: use `git add -f`.
- **Ledger rows: the steward writes them.** The t27b ledger steward (`specs/jobs/t27b_ledger_steward.t27`, rules in `specs/tri/t27b/ledger_steward.t27`, #8654) adds the row from master's next run after a spec PR merges, and opens one ledger PR with auto-merge. Once the Queen runs that card (see gHashTag/trios#1751), spec PRs leave `docs/reports/t27b_expectations.json` alone.
- **Until then, every new spec in a PR still gets its row.** A missing row turns master's `t27b-native-ratchet` red for everyone (UNLISTED). That happened 6 times in 30 minutes on 2026-10-09.
- **The steward refuses** UNEXPECTED FAILURE, MOVED, BAD REASON, OVER CAP, a defect where the reference passes, a cap rise larger than the new rows, and more than 16 STALE rows. For a refused run it opens one issue labelled `t27b-ledger-steward` and no PR. Those issues are this loop's to read.
- **The steward refuses** UNEXPECTED FAILURE, MOVED, BAD REASON, OVER CAP, a defect where the reference passes, a cap rise larger than the new rows, and more than 16 STALE rows. A refused finding no longer holds the run back: the steward applies its other rows, leaves the refused row as master has it, and lists it in the ledger PR's table. Only a run with nothing else to apply, a cap rise or a STALE flood gets one issue labelled `t27b-ledger-steward` and no PR. Those issues and the REFUSE rows in steward PRs are this loop's to read.
- **Receipts:** while master moves every 10-20 minutes, compare a lane's squash commit on master against its parent after the merge:
- `cd /work/t27 && /work/t27c-master corpus-receipt compare BASE.receipt.json HEAD.receipt.json --challenge-head <nonce>` on t27b-lab;
- a master receipt carries no nonce and is accepted as BASE;
Expand Down
9 changes: 5 additions & 4 deletions .trinity/seals/jobs_JobT27bLedgerSteward.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"built_by": "t27c-bootstrap@0.5.2+55eb214ac",
"built_by": "t27c-bootstrap@0.5.2+063da049b",
"closure": [],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:ac9254171852a74a08f26cee469556437586afc64ff5d04662493e1b07fd122b",
Expand All @@ -9,16 +9,17 @@
"module": "JobT27bLedgerSteward",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-10T14:43:21Z",
"sealed_at": "2026-10-18T03:55:24Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:869202696ec9a11cd45189276828631c767967d44ee6ba7f91404ba214e43a27",
"spec_hash": "sha256:87951c2be3a5159c61bb3c98591972ba3615fdaf102b56f2b63ed086e50329ca",
"spec_path": "specs/jobs/t27b_ledger_steward.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 2,
"total": 2
"total": 2,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d",
Expand Down
19 changes: 10 additions & 9 deletions .trinity/seals/t27b_T27bLedgerSteward.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
{
"built_by": "t27c-bootstrap@0.5.2+55eb214ac",
"built_by": "t27c-bootstrap@0.5.2+063da049b",
"closure": [
{
"spec": "specs/tri/t27b/steward.t27",
"spec_hash": "sha256:70867c8cd8a8155d82f352b6833168f04c846a736413d6b2420d54774994123e"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:e68d532298ecd4aac96e32088f179d581147705775933c8f93ebda82221aabab",
"gen_hash_rust": "sha256:d8faa3518e7703b7f8c7e3cac99fce073a4ae01c1a7c3f1b0195e502226d3b74",
"gen_hash_verilog": "sha256:806a630d9e2970ef50e7ea4b777b101b6c24616736caa484b3dc012f55c914f9",
"gen_hash_zig": "sha256:cf898366b4bc6cd30fc0232d7dde252a94afaf03e0868d783e15ef7bf4338cd9",
"gen_hash_c": "sha256:7f6f95d85401dbb6dbaa7786ebc835a79450218b97ee0e9fa35a066805841e04",
"gen_hash_rust": "sha256:b002afd8a8e09a735fc529b7fde408eec6234131409a67812facd05a45670a31",
"gen_hash_verilog": "sha256:6c380f5e56877102b97dd5e81447238ef664b32598cafba68c3ee45fcafcb798",
"gen_hash_zig": "sha256:07cdd78d6c7a7380a47e7ebbb1047ad8645cf6670349f77af069ad317ef73621",
"module": "T27bLedgerSteward",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-10T14:40:39Z",
"sealed_at": "2026-10-18T03:55:24Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:e2a58a7ef6fb10c371af1dcb8cf02cd1f206f3327dc4851546f5eb4696ce4132",
"spec_hash": "sha256:731eca094910d21ec239964b4df2f4e9890babd1d53395d000440df283b3c8b3",
"spec_path": "specs/tri/t27b/ledger_steward.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 10,
"total": 10
"passed": 11,
"total": 11,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d",
Expand Down
6 changes: 4 additions & 2 deletions specs/jobs/t27b_ledger_steward.t27
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
; 1 EFFECT steward-refusals-issue when run_verdict is REFUSE: one issue for this run, listing each
; refused finding with its refusal_reason (or run_refusal) and the
; rows the steward would have applied; otherwise PASS, nothing done
; 2 CHECK steward-appliable run_verdict is APPLY: every finding is the steward's and the cap
; fits (cap_fits); REFUSE fails the job, pointing at the issue
; 2 CHECK steward-appliable run_verdict is APPLY: some finding is the steward's, the cap fits
; (cap_fits) and STALE is no flood; a refused finding stays as
; master has it and is listed in the PR; REFUSE fails the job,
; pointing at the issue
; 3 EFFECT steward-ledger-issue the issue the ledger commit and the PR close (the Issue Gate:
; `Closes #N` in the commit and on line 1 of the PR body),
; labelled ISSUE_LABEL
Expand Down
50 changes: 43 additions & 7 deletions specs/tri/t27b/ledger_steward.t27
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
; UNLISTED spec t27b fails, mismatches, crashes or times out on (a defect is never "unimplemented"),
; a cap rise larger than the new rows, more STALE rows in one run than STALE_LIMIT (the reference
; moved, not the specs), and any finding code this file does not know.
; One refused finding refuses the run: a ledger PR that leaves the ratchet red is noise, and the person
; who reads the issue writes the whole batch, as #8548 was written.
; A refused finding is left as master has it, and the rest of the run is still applied: the PR's table
; names every refused row, so the ratchet stays red only for those. Until #10189 one refused finding
; refused the whole run, and from 2026-10-13 to 10-18 the lab refused 63 of 75 master runs for the same
; two or three rows (rust_convert, trios-mesh-node crypto, emit_kit) while about 250 safe rows waited
; and sessions wrote them into the ledger by hand 17 times in a day. A run with nothing to apply but a
; refused finding is still refused, and a stale flood or a cap rise still refuses the whole run.
; Codes are steward.t27's; the invariant at the end checks the numbering against its entry_code.
; ASCII only (L3).
; phi^2 + 1/phi^2 = 3 | TRINITY
Expand Down Expand Up @@ -92,8 +96,10 @@ pub const RR_UNKNOWN : u8 = 8;

/// The run's verdict.
/// NOTHING no finding to apply: the ratchet is green, no job
/// APPLY every finding is the steward's: compose the ledger, one PR, auto-merge
/// REFUSE some finding is a person's: one issue for the run, no PR
/// APPLY some finding is the steward's: compose the ledger from those, one PR, auto-merge; a
/// refused finding stays as master has it and is listed in the PR
/// REFUSE nothing to apply but a person's finding, or the run as a whole is refused (a stale
/// flood, a cap rise): one issue for the run, no PR
/// SKIP not a run the steward reads: not a master run, asserts not counted, or master's ledger
/// moved since the run (the next run is read instead)
pub const RV_NOTHING : u8 = 0;
Expand Down Expand Up @@ -205,13 +211,16 @@ pub fn run_stewardable(is_master: bool, asserts_counted: bool, same_ledger: bool
return true;
}

/// A refused finding no longer holds back the steward's own rows: they are applied, and the refused
/// row stays as master has it. The cap is counted on the composed ledger, so a refused row never
/// raises it.
pub fn run_verdict(stewardable: bool, refused: u32, applied: u32, stale: u32, cap_ok: bool) -> u8 {
if (stewardable == false) { return RV_SKIP; }
if (refused > 0) { return RV_REFUSE; }
if (stale_flood(stale)) { return RV_REFUSE; }
if (cap_ok == false) { return RV_REFUSE; }
if (applied == 0) { return RV_NOTHING; }
return RV_APPLY;
if (applied > 0) { return RV_APPLY; }
if (refused > 0) { return RV_REFUSE; }
return RV_NOTHING;
}

/// The run-level reason the issue leads with when no single finding was refused.
Expand Down Expand Up @@ -316,6 +325,33 @@ test batch_8548_without_its_failures_is_applied {
assert run_verdict(true, refused, applied, 4, cap_fits(25, 23, fresh)) == RV_APPLY;
}

test run_18c98cc77_applies_its_rows_around_two_refused {
// lab run 18c98cc77 (2026-10-18): UNEXPECTED FAILURE tools/t27o/rust_convert (blocked) and UNLISTED
// trios-mesh-node crypto (fail) refused; 248 UNLISTED passes waited behind them
var refused : u32 = tally_refused(0, RC_UNEXPECTED_FAILURE, T_BLOCKED, 1);
refused = tally_refused(refused, RC_UNLISTED, T_FAIL, 1);
refused = tally_refused(refused, RC_UNLISTED, T_PASS, 248);
var applied : u32 = tally_applied(0, RC_UNEXPECTED_FAILURE, T_BLOCKED, 1);
applied = tally_applied(applied, RC_UNLISTED, T_FAIL, 1);
applied = tally_applied(applied, RC_UNLISTED, T_PASS, 248);
var fresh : u32 = tally_new_not_pass(0, RC_UNLISTED, T_FAIL, 1);
fresh = tally_new_not_pass(fresh, RC_UNEXPECTED_FAILURE, T_BLOCKED, 1);
fresh = tally_new_not_pass(fresh, RC_UNLISTED, T_PASS, 248);
assert refused == 2;
assert applied == 248;
assert fresh == 0;
// neither refused row enters the composed ledger as a non-pass, so the cap holds
assert cap_fits(25, 25, fresh) == true;
assert run_verdict(true, refused, applied, 0, cap_fits(25, 25, fresh)) == RV_APPLY;
assert effect_wanted(RV_APPLY, EF_PULL_REQUEST) == true;
assert effect_wanted(RV_APPLY, EF_REFUSAL_ISSUE) == false;
// the same two refusals with nothing else to apply are still a person's
assert run_verdict(true, refused, 0, 0, true) == RV_REFUSE;
// and a refusal never lets a cap rise or a stale flood through
assert run_verdict(true, refused, applied, 0, false) == RV_REFUSE;
assert run_verdict(true, refused, applied, STALE_LIMIT + 1, true) == RV_REFUSE;
}

test the_steward_applies_these {
assert finding_action(RC_UNLISTED, T_PASS) == ACT_ADD;
assert finding_action(RC_UNLISTED, T_PASS_VACUOUS) == ACT_ADD;
Expand Down
Loading