From eddbf220ca5f5038b90ed8e4c4fce573c390ae03 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 17:42:15 +0700 Subject: [PATCH 1/7] t27f: frame shards as a generic spec, frame_shard.t27 (Closes #10385) The shard partition and the TF_SHARD/TF_SHARDS reader, with the reel length as a parameter, so any renderer opts in with three lines in its main instead of copying them. token_floor.t27 switches to it in its owner's render(wide) rewrite. Lab: test report 5/5, 0 vacuous; sealed. Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/t27f_frame_shard.json | 28 +++++ specs/t27f/frame_shard.t27 | 154 +++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 .trinity/seals/t27f_frame_shard.json create mode 100644 specs/t27f/frame_shard.t27 diff --git a/.trinity/seals/t27f_frame_shard.json b/.trinity/seals/t27f_frame_shard.json new file mode 100644 index 0000000000..6031ab984b --- /dev/null +++ b/.trinity/seals/t27f_frame_shard.json @@ -0,0 +1,28 @@ +{ + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", + "closure": [], + "config": "gen=c,rust,verilog,zig;tests=zig", + "gen_hash_c": "sha256:cc399837fb34f4c10c54c90e26eaa6ccd9dfd11d29da56667addc8cb88bc1a18", + "gen_hash_rust": "sha256:e833a49af5b10636afb6b00a19abbea4802eca5b283f30bf19573498d9aae653", + "gen_hash_verilog": "sha256:9e98a30d7cd30430c01e7b27ffcad468d197af832d41af3969dbfa0f71b6a7d1", + "gen_hash_zig": "sha256:a0ad9a3ac459844ec8e22fad442e970712c10dd892c36fb40f3bef1620d547dc", + "module": "frame_shard", + "ring": 12, + "seal_schema": 2, + "sealed_at": "2026-10-18T10:43:57Z", + "sealed_by": "t27c-bootstrap@0.5.2", + "spec_hash": "sha256:1f04638a243b7a7f4d7a4480faf85f7878ca2e3365a2ec0f001a991fbd353da6", + "spec_path": "specs/t27f/frame_shard.t27", + "tests": { + "failed": 0, + "failing": [], + "forced": false, + "passed": 5, + "total": 5, + "vacuous": 0 + }, + "toolchain": { + "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "zig": "0.16.0" + } +} \ No newline at end of file diff --git a/specs/t27f/frame_shard.t27 b/specs/t27f/frame_shard.t27 new file mode 100644 index 0000000000..415e86de91 --- /dev/null +++ b/specs/t27f/frame_shard.t27 @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: Apache-2.0 +; specs/t27f/frame_shard.t27 -- which frames of a reel one process renders, so N processes render +; it in parallel and their outputs, concatenated, are the one-process output byte for byte. +; -- +; Why: specs/t27f/token_floor.t27 renders 450 frames in 52 s on one of the lab's 48 cores. Shard k +; of N renders the frames [shard_a(k, N, F), shard_b(k, N, F)) of a reel of F frames, and the shards +; of one N tile [0, F) in order. 48 shards render token_floor in 3.43 s, same frames sha256. +; -- +; The contract for a renderer whose frame f is the integral of its physics from frame 0 (most are): +; step the physics from frame 0 up to the shard's last frame, and skip only the drawing of the +; frames before its first one. A renderer opts in with three lines in its main: +; const fa = env_first(FRAMES); +; const fb = env_end(FRAMES); +; while (frame < fb) { ...physics...; if (frame < fa) { frame = frame + 1; continue; } ...draw... } +; -- +; The shard is read from the environment: TF_SHARD (k) and TF_SHARDS (N). Unset, or a k or N that +; names no shard, renders the whole reel, never an empty or a partial one. Only main may call +; env_first and env_end: they reach getenv, so the binary links libc (`-lc`) and the tests, which +; never link libc, do not reach them. +; -- +; The frames themselves are cached by specs/t27f/frame_cache.t27, keyed by the renderer's seal. + +module frame_shard; + +; The first frame of shard k of n, for 0 <= k <= n; shard_a(n, n, frames) is frames. Shard k renders +; [shard_a(k, n, frames), shard_a(k + 1, n, frames)), so shard k + 1 starts where shard k stops. +pub fn shard_a(k: i32, n: i32, frames: i32) -> i32 { + return @divTrunc(k * frames, n); +} + +pub fn shard_b(k: i32, n: i32, frames: i32) -> i32 { + return shard_a(k + 1, n, frames); +} + +; The decimal number at the head of s, or dflt when s has no digit first. At most four digits are +; read, so no input overflows. +pub fn count_or(s: [*:0]const u8, dflt: i32) -> i32 { + var v : i32 = 0; + var i : usize = 0; + while (i < 4 && s[i] >= 48 && s[i] <= 57) { + v = v * 10 + @as(i32, @intCast(s[i] - 48)); + i = i + 1; + } + if (i == 0) { + return dflt; + } + return v; +} + +; The shard a renderer draws, from k and n as read: an n out of 1..frames, or a k out of 0..n - 1, +; is the whole reel. +pub fn shard_n(k: i32, n: i32, frames: i32) -> i32 { + if (n < 1 || n > frames || k < 0 || k >= n) { + return 1; + } + return n; +} + +pub fn shard_k(k: i32, n: i32, frames: i32) -> i32 { + if (shard_n(k, n, frames) == 1) { + return 0; + } + return k; +} + +; The first and the end frame of the shard (k, n) as read, checked. +pub fn first_of(k: i32, n: i32, frames: i32) -> i32 { + return shard_a(shard_k(k, n, frames), shard_n(k, n, frames), frames); +} + +pub fn end_of(k: i32, n: i32, frames: i32) -> i32 { + return shard_b(shard_k(k, n, frames), shard_n(k, n, frames), frames); +} + +; The environment variable `name` as a count; dflt when it is unset. main only (getenv, libc). +pub fn env_count(name: [*:0]const u8, dflt: i32) -> i32 { + const p = std.c.getenv(name); + if (p == null) { + return dflt; + } + return count_or(p.?, dflt); +} + +pub fn env_first(frames: i32) -> i32 { + return first_of(env_count("TF_SHARD", 0), env_count("TF_SHARDS", 1), frames); +} + +pub fn env_end(frames: i32) -> i32 { + return end_of(env_count("TF_SHARD", 0), env_count("TF_SHARDS", 1), frames); +} + +test "the shards of every n from 1 to 64 tile a 450-frame reel in order, with no gap and no overlap" { + var n : i32 = 1; + while (n <= 64) { + assert(shard_a(0, n, 450) == 0); + assert(shard_b(n - 1, n, 450) == 450); + var total : i32 = 0; + var k : i32 = 0; + while (k < n) { + assert(shard_b(k, n, 450) > shard_a(k, n, 450)); + if (k > 0) { + assert(shard_a(k, n, 450) == shard_b(k - 1, n, 450)); + } + total = total + shard_b(k, n, 450) - shard_a(k, n, 450); + k = k + 1; + } + assert(total == 450); + n = n + 1; + } +} + +test "48 shards of 450 frames are 9 or 10 frames each, and 450 shards are one frame each" { + assert(shard_b(0, 48, 450) - shard_a(0, 48, 450) == 9); + assert(shard_b(47, 48, 450) - shard_a(47, 48, 450) == 10); + var k : i32 = 0; + while (k < 450) { + assert(shard_a(k, 450, 450) == k); + assert(shard_b(k, 450, 450) == k + 1); + k = k + 1; + } +} + +test "the tiling holds for reel lengths that n does not divide" { + assert(shard_a(1, 7, 100) == 14); + assert(shard_b(6, 7, 100) == 100); + assert(shard_a(2, 3, 10) == 6); + assert(shard_b(2, 3, 10) - shard_a(2, 3, 10) == 4); + assert(shard_n(0, 11, 10) == 1); + assert(shard_n(9, 10, 10) == 10); +} + +test "a count is read from its leading digits, and anything else falls back" { + assert(count_or("", 7) == 7); + assert(count_or("x3", 7) == 7); + assert(count_or("12", 7) == 12); + assert(count_or("48\n", 7) == 48); + assert(count_or("0", 7) == 0); + assert(count_or("123456", 7) == 1234); +} + +test "a shard that cannot be rendered as asked renders the whole reel" { + assert(shard_n(0, 1, 450) == 1); + assert(shard_n(48, 48, 450) == 1); + assert(shard_n(0, 0, 450) == 1); + assert(shard_n(0 - 1, 4, 450) == 1); + assert(shard_n(0, 451, 450) == 1); + assert(shard_k(48, 48, 450) == 0); + assert(shard_n(3, 48, 450) == 48); + assert(shard_k(3, 48, 450) == 3); + assert(first_of(9, 4, 450) == 0); + assert(end_of(9, 4, 450) == 450); + assert(first_of(3, 48, 450) == 28); + assert(end_of(3, 48, 450) == 37); +} From 5e4d3b99838c4d6916290aa46477abb2dc4110d6 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 21:57:00 +0700 Subject: [PATCH 2/7] t27f: token_floor takes its shards from frame_shard.t27; t27b ledger names frame_shard (Closes #10385) Co-Authored-By: Claude Opus 5.5 --- docs/reports/t27b_expectations.json | 3 +- specs/t27f/token_floor.t27 | 131 +++++----------------------- 2 files changed, 25 insertions(+), 109 deletions(-) diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index 8d982e2ade..d4e6afc1a3 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -12,7 +12,7 @@ "reference-bug": "the reference passes it for the wrong reason; t27b is right not to", "n/a": "outside what t27b is for (say why in the PR that sets it)" }, - "max_not_pass": 132, + "max_not_pass": 133, "entries": [ {"path": "specs/a/b_c.t27", "t27b": "pass"}, {"path": "specs/a_b/c.t27", "t27b": "pass"}, @@ -1436,6 +1436,7 @@ {"path": "specs/t27f/build.t27", "t27b": "pass"}, {"path": "specs/t27f/deck.t27", "t27b": "pass"}, {"path": "specs/t27f/frame_cache.t27", "t27b": "pass"}, + {"path": "specs/t27f/frame_shard.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, {"path": "specs/t27f/hot.t27", "t27b": "pass"}, {"path": "specs/t27f/outfit_atlas.t27", "t27b": "pass"}, {"path": "specs/t27f/particle_engine.t27", "t27b": "blocked", "blocker": "ExprCall(@sin)", "reason": "unimplemented"}, diff --git a/specs/t27f/token_floor.t27 b/specs/t27f/token_floor.t27 index 9470906951..66d5207aa3 100644 --- a/specs/t27f/token_floor.t27 +++ b/specs/t27f/token_floor.t27 @@ -65,9 +65,9 @@ // (#10407): the camera moves the backdrop and the lens dithers it, so it differs in every frame. // To use more cores, `main` renders shard k of N (environment TF_SHARD and TF_SHARDS; unset, 0 of // 1, the whole reel) of the cut TF_CUT names (0 the tall cut, 1 the wide one; unset, both, tall -// first): the frames [shard_a(k, N), shard_b(k, N)). Frame f's state is the integral from frame 0, -// so every shard steps the physics from frame 0 and skips only the splats and the raster before its -// range. The shards of one N and one cut tile [0, FRAMES) in order, so their outputs concatenated +// first): the frames specs/t27f/frame_shard.t27 gives shard k of N. Frame f's state is the +// integral from frame 0, so every shard steps the physics from frame 0 and skips only the splats +// and the raster before its range. The shards of one N and one cut tile [0, FRAMES) in order, so their outputs concatenated // are that cut's one-process output byte for byte. Unchanged frames need no render at all: // specs/t27f/frame_cache.t27 keys them by this spec's seal. // @@ -137,6 +137,12 @@ use t27f::pbr_sphere::clamp01; use t27f::pbr_sphere::swept_mid; use t27f::pbr_sphere::SHUTTER; use t27f::pbr_sphere::NO_NB; +use t27f::frame_shard::shard_a; +use t27f::frame_shard::first_of; +use t27f::frame_shard::end_of; +use t27f::frame_shard::env_count; +use t27f::frame_shard::env_first; +use t27f::frame_shard::env_end; pub const ID : str = "token-floor"; pub const VERSION : u8 = 1; @@ -886,49 +892,6 @@ fn cut_bytes(o: usize) -> i32 { return frame_w(o) * frame_h(o) * 3; } -// ---- shards ---- - -// The first frame of shard k of n, for 0 <= k <= n; shard_a(n, n) is FRAMES. Shard k renders -// [shard_a(k, n), shard_a(k + 1, n)), so shard k + 1 starts where shard k stops. -pub fn shard_a(k: i32, n: i32) -> i32 { - return @divTrunc(k * FRAMES, n); -} - -pub fn shard_b(k: i32, n: i32) -> i32 { - return shard_a(k + 1, n); -} - -// The decimal number at the head of s, or dflt when s has no digit first. At most four digits are -// read, so no input overflows. -pub fn count_or(s: [*:0]const u8, dflt: i32) -> i32 { - var v : i32 = 0; - var i : usize = 0; - while (i < 4 && s[i] >= 48 && s[i] <= 57) { - v = v * 10 + @as(i32, @intCast(s[i] - 48)); - i = i + 1; - } - if (i == 0) { - return dflt; - } - return v; -} - -// The shard main renders, from k and n as read: an n out of 1..FRAMES, or a k out of 0..n - 1, -// is the whole reel, never an empty or a partial one. -pub fn shard_n(k: i32, n: i32) -> i32 { - if (n < 1 || n > FRAMES || k < 0 || k >= n) { - return 1; - } - return n; -} - -pub fn shard_k(k: i32, n: i32) -> i32 { - if (shard_n(k, n) == 1) { - return 0; - } - return k; -} - // Whether main renders cut o when TF_CUT reads c: 0 the tall cut, 1 the wide one, anything else // both, so a mistyped TF_CUT renders the whole stream rather than none of it. pub fn cut_runs(c: i32, o: usize) -> bool { @@ -941,16 +904,6 @@ pub fn cut_runs(c: i32, o: usize) -> bool { return true; } -// The environment variable `name` as a count; dflt when it is unset. Only main calls this, so the -// tests, which never link libc, do not reach getenv. -fn env_count(name: [*:0]const u8, dflt: i32) -> i32 { - const p = std.c.getenv(name); - if (p == null) { - return dflt; - } - return count_or(p.?, dflt); -} - // ---- the row index ---- // Whether a splat of kind k (m 1 for a mirror image) can light the row whose centre is y: an image @@ -1747,11 +1700,9 @@ fn render(o: usize, f_lo: i32, f_hi: i32) -> void { } pub fn main() -> void { - const sk0 = env_count("TF_SHARD", 0); - const sn0 = env_count("TF_SHARDS", 1); const cut = env_count("TF_CUT", 2); - const fa = shard_a(shard_k(sk0, sn0), shard_n(sk0, sn0)); - const fb = shard_b(shard_k(sk0, sn0), shard_n(sk0, sn0)); + const fa = env_first(FRAMES); + const fb = env_end(FRAMES); if (cut_runs(cut, TALL)) { render(TALL, fa, fb); } @@ -2296,57 +2247,21 @@ test "the empty scene's bytes before the lens are the ones the fixed-camera reel assert(light_byte(backdrop(859.5, 1640.5) * TINT_B) == 29); } -test "the shards of every n from 1 to 64 tile the reel in order, with no gap and no overlap" { - var n : i32 = 1; - while (n <= 64) { - assert(shard_a(0, n) == 0); - assert(shard_b(n - 1, n) == FRAMES); - var total : i32 = 0; - var k : i32 = 0; - while (k < n) { - assert(shard_b(k, n) > shard_a(k, n)); - if (k > 0) { - assert(shard_a(k, n) == shard_b(k - 1, n)); - } - total = total + shard_b(k, n) - shard_a(k, n); - k = k + 1; - } - assert(total == FRAMES); - n = n + 1; - } -} - -test "48 shards are 9 or 10 frames each, and FRAMES shards are one frame each" { - assert(shard_b(0, 48) - shard_a(0, 48) == 9); - assert(shard_b(47, 48) - shard_a(47, 48) == 10); +test "the reel splits into shards through frame_shard: 48 shards of FRAMES tile it, a bad pair is the whole reel" { + var total : i32 = 0; var k : i32 = 0; - while (k < FRAMES) { - assert(shard_a(k, FRAMES) == k); - assert(shard_b(k, FRAMES) == k + 1); + while (k < 48) { + assert(first_of(k, 48, FRAMES) == shard_a(k, 48, FRAMES)); + assert(end_of(k, 48, FRAMES) > first_of(k, 48, FRAMES)); + total = total + end_of(k, 48, FRAMES) - first_of(k, 48, FRAMES); k = k + 1; } -} - -test "a count is read from its leading digits, and anything else falls back" { - assert(count_or("", 7) == 7); - assert(count_or("x3", 7) == 7); - assert(count_or("12", 7) == 12); - assert(count_or("48\n", 7) == 48); - assert(count_or("0", 7) == 0); - assert(count_or("123456", 7) == 1234); -} - -test "a shard that cannot be rendered as asked renders the whole reel" { - assert(shard_n(0, 1) == 1); - assert(shard_n(48, 48) == 1); - assert(shard_n(0, 0) == 1); - assert(shard_n(0 - 1, 4) == 1); - assert(shard_n(0, FRAMES + 1) == 1); - assert(shard_k(48, 48) == 0); - assert(shard_n(3, 48) == 48); - assert(shard_k(3, 48) == 3); - assert(shard_a(shard_k(9, 4), shard_n(9, 4)) == 0); - assert(shard_b(shard_k(9, 4), shard_n(9, 4)) == FRAMES); + assert(total == FRAMES); + assert(end_of(47, 48, FRAMES) == FRAMES); + assert(first_of(3, 48, FRAMES) == 28); + assert(end_of(3, 48, FRAMES) == 37); + assert(first_of(48, 48, FRAMES) == 0); + assert(end_of(48, 48, FRAMES) == FRAMES); } test "TF_CUT picks one cut, and anything but 0 or 1 renders both, tall first" { From 0c8dccf7ec6dcd3f51a138ef1e2b2d653d88e3b6 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 22:06:36 +0700 Subject: [PATCH 3/7] t27f: reseal token_floor after the frame_shard swap (Refs #10385) Lab: t27c test-report token_floor 32/32, frame_shard 5/5, 0 vacuous; frame_shard seal verifies unchanged. Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/t27f_token_floor.json | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.trinity/seals/t27f_token_floor.json b/.trinity/seals/t27f_token_floor.json index 3767e7fa07..8343cd6b76 100644 --- a/.trinity/seals/t27f_token_floor.json +++ b/.trinity/seals/t27f_token_floor.json @@ -1,10 +1,14 @@ { - "built_by": "t27c-bootstrap@0.5.2+9448ab4be", + "built_by": "t27c-bootstrap@0.5.2+5e4d3b998", "closure": [ { "spec": "specs/physics/physical_limits.t27", "spec_hash": "sha256:adb7092831e266f0e4bed92f74e7795c78c1bdb1051b5cd9a0c1be94b5e5b19a" }, + { + "spec": "specs/t27f/frame_shard.t27", + "spec_hash": "sha256:1f04638a243b7a7f4d7a4480faf85f7878ca2e3365a2ec0f001a991fbd353da6" + }, { "spec": "specs/t27f/outfit_atlas.t27", "spec_hash": "sha256:6fb47290e7fae3d22258b5a8dfe1282fd58b96790ecb357a9513683c4035cac6" @@ -27,23 +31,23 @@ } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:0f358d8ff0757768f04d35ecbecd679b091c43d6d268fa8c28366fa31a3f9167", - "gen_hash_rust": "sha256:d263a762901fc286cc2d2d20c8f6445f93561933d8bdd043ba079dfcd2e686aa", - "gen_hash_verilog": "sha256:b495c59195d25d5eb3addaaf9da41cf69117a4d2c6fcf4e9320d95cbc3df0314", - "gen_hash_zig": "sha256:4c978f26d1d0a358bde62e9ef6221ec01a06d02aca24c36ada41b3c12d4b85f4", + "gen_hash_c": "sha256:3206763fb219dd142baa945c3504da04d778bea33058bf72fd1b714320b8d309", + "gen_hash_rust": "sha256:2eb10bb19e8ccb8675e39b5344d78f5361e5f89057780dd57583a5b1e6b0a525", + "gen_hash_verilog": "sha256:f1c9e7aa57719f89baccdeb47d6b92d09ee8895ab63f8e8d2fa74f7b5009a895", + "gen_hash_zig": "sha256:c34169797b0d63a8f2c4156edfadf3ce40a0aaf73e77788a478d25fcaac1ece0", "module": "token_floor", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T13:21:32Z", + "sealed_at": "2026-10-18T15:05:50Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:82524e666fafe6098d85d86cfd93932e1e488f318e28ba0eff93c54cb656f8e8", + "spec_hash": "sha256:1d33dca783f83effabb8208a6bbdf311840fbbe6e23081713b009954605807e3", "spec_path": "specs/t27f/token_floor.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 35, - "total": 35, + "passed": 32, + "total": 32, "vacuous": 0 }, "toolchain": { From 3f9fc2320527fce7c0dba9c52ff7d21b950aa304 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 22:10:47 +0700 Subject: [PATCH 4/7] t27f: reseal token_floor_mux, whose closure holds token_floor's hash (Refs #10385) Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/t27f_token_floor_mux.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.trinity/seals/t27f_token_floor_mux.json b/.trinity/seals/t27f_token_floor_mux.json index 6c533d1ff5..5aa1abe9e0 100644 --- a/.trinity/seals/t27f_token_floor_mux.json +++ b/.trinity/seals/t27f_token_floor_mux.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+9448ab4be", + "built_by": "t27c-bootstrap@0.5.2+5e4d3b998", "closure": [ { "spec": "specs/automation/owner_voice_reel.t27", @@ -19,7 +19,7 @@ }, { "spec": "specs/t27f/token_floor.t27", - "spec_hash": "sha256:82524e666fafe6098d85d86cfd93932e1e488f318e28ba0eff93c54cb656f8e8" + "spec_hash": "sha256:1d33dca783f83effabb8208a6bbdf311840fbbe6e23081713b009954605807e3" }, { "spec": "specs/t27f/token_floor_scenes.t27", @@ -34,7 +34,7 @@ "module": "token_floor_mux", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T13:21:31Z", + "sealed_at": "2026-10-18T15:10:37Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:6b83ab94e55a46aa538701fa568cb5493e1c6766ae008386916cf83335e5c7b1", "spec_path": "specs/t27f/token_floor_mux.t27", From e43639b6f250a6d02112dc428f2b0e403ddb8471 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 22:21:42 +0700 Subject: [PATCH 5/7] t27b ledger: list ledger_union.t27 and t27mcp/service.t27, which t27b passes (Refs #10385) Both specs reached master in #10485 and #10484 without ledger lines, so the ratchet reported them UNLISTED. Co-Authored-By: Claude Opus 5.5 --- docs/reports/t27b_expectations.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index d4e6afc1a3..1d43dd90ab 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -188,6 +188,7 @@ {"path": "specs/claw/gates.t27", "t27b": "pass"}, {"path": "specs/claw/gates_pins.t27", "t27b": "pass"}, {"path": "specs/claw/github_surface.t27", "t27b": "pass"}, + {"path": "specs/claw/ledger_union.t27", "t27b": "pass"}, {"path": "specs/claw/preview.t27", "t27b": "pass"}, {"path": "specs/claw/recipes.t27", "t27b": "pass"}, {"path": "specs/claw/refresh.t27", "t27b": "pass"}, @@ -1466,6 +1467,7 @@ {"path": "specs/t27mcp/examples.t27", "t27b": "pass"}, {"path": "specs/t27mcp/find.t27", "t27b": "pass"}, {"path": "specs/t27mcp/seal_verdict.t27", "t27b": "pass"}, + {"path": "specs/t27mcp/service.t27", "t27b": "pass"}, {"path": "specs/t27mcp/spec_brief.t27", "t27b": "pass"}, {"path": "specs/t27mcp/telegram.t27", "t27b": "pass"}, {"path": "specs/t27mcp/tool_schema.t27", "t27b": "codegen", "blocker": "t27b: unsupported construct FnDecl(frame or branch range) at line 0 (fn the round trip fixtures: a tuple, arrays, a boolean, nested objects: conditional branch out of range (function too large))", "reason": "unimplemented"}, From 875be55a0acb037c80d9e9bb6bea306c0101686d Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 22:24:31 +0700 Subject: [PATCH 6/7] t27f: reseal token_floor_mux after merging master (Refs #10385) Master's mux seal recorded the token_floor hash from before the frame_shard swap. Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/t27f_token_floor_mux.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.trinity/seals/t27f_token_floor_mux.json b/.trinity/seals/t27f_token_floor_mux.json index babf18058c..6f7f575dc7 100644 --- a/.trinity/seals/t27f_token_floor_mux.json +++ b/.trinity/seals/t27f_token_floor_mux.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+9448ab4be", + "built_by": "t27c-bootstrap@0.5.2+5e4d3b998", "closure": [ { "spec": "specs/automation/owner_voice_reel.t27", @@ -19,7 +19,7 @@ }, { "spec": "specs/t27f/token_floor.t27", - "spec_hash": "sha256:82524e666fafe6098d85d86cfd93932e1e488f318e28ba0eff93c54cb656f8e8" + "spec_hash": "sha256:1d33dca783f83effabb8208a6bbdf311840fbbe6e23081713b009954605807e3" }, { "spec": "specs/t27f/token_floor_scenes.t27", @@ -34,7 +34,7 @@ "module": "token_floor_mux", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T15:14:29Z", + "sealed_at": "2026-10-18T15:24:22Z", "sealed_by": "t27c-bootstrap@0.5.2", "spec_hash": "sha256:55c02c60e581640d2f3d6db3d9ba2cdfb21d74b172290b386023e8f264e59a04", "spec_path": "specs/t27f/token_floor_mux.t27", From 20c8b0781e17a7785d826df8abca1e9336210a65 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 22:35:07 +0700 Subject: [PATCH 7/7] t27b ledger: list model_route, lesson_reel and reel_topics as CI's t27b run saw them (Refs #10385) model_route.t27 and reel_topics.t27 pass. lesson_reel.t27 is blocked on type [N]T, like frame_shard, so max_not_pass goes from 133 to 134. Co-Authored-By: Claude Opus 5.5 --- docs/reports/t27b_expectations.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index 1d43dd90ab..09b79809ce 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -12,7 +12,7 @@ "reference-bug": "the reference passes it for the wrong reason; t27b is right not to", "n/a": "outside what t27b is for (say why in the PR that sets it)" }, - "max_not_pass": 133, + "max_not_pass": 134, "entries": [ {"path": "specs/a/b_c.t27", "t27b": "pass"}, {"path": "specs/a_b/c.t27", "t27b": "pass"}, @@ -189,6 +189,7 @@ {"path": "specs/claw/gates_pins.t27", "t27b": "pass"}, {"path": "specs/claw/github_surface.t27", "t27b": "pass"}, {"path": "specs/claw/ledger_union.t27", "t27b": "pass"}, + {"path": "specs/claw/model_route.t27", "t27b": "pass"}, {"path": "specs/claw/preview.t27", "t27b": "pass"}, {"path": "specs/claw/recipes.t27", "t27b": "pass"}, {"path": "specs/claw/refresh.t27", "t27b": "pass"}, @@ -1439,6 +1440,7 @@ {"path": "specs/t27f/frame_cache.t27", "t27b": "pass"}, {"path": "specs/t27f/frame_shard.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, {"path": "specs/t27f/hot.t27", "t27b": "pass"}, + {"path": "specs/t27f/lesson_reel.t27", "t27b": "blocked", "blocker": "type [N]T", "reason": "unimplemented"}, {"path": "specs/t27f/outfit_atlas.t27", "t27b": "pass"}, {"path": "specs/t27f/particle_engine.t27", "t27b": "blocked", "blocker": "ExprCall(@sin)", "reason": "unimplemented"}, {"path": "specs/t27f/particle_field.t27", "t27b": "pass"}, @@ -1450,6 +1452,7 @@ {"path": "specs/t27f/reel_particles.t27", "t27b": "blocked", "blocker": "ExprCall(@sin)", "reason": "unimplemented"}, {"path": "specs/t27f/reel_particles_mux.t27", "t27b": "pass"}, {"path": "specs/t27f/reel_t27_basics.t27", "t27b": "pass"}, + {"path": "specs/t27f/reel_topics.t27", "t27b": "pass"}, {"path": "specs/t27f/spec_graph.t27", "t27b": "pass"}, {"path": "specs/t27f/spec_graph_derive.t27", "t27b": "pass"}, {"path": "specs/t27f/spec_graph_export.t27", "t27b": "pass"},