From e11faf51d0f61c29bdac5ef2df77a52765a8de7c Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Sun, 18 Oct 2026 09:27:26 +0700 Subject: [PATCH] fix(ci): master green -- rust_convert CSE hoist, mesh crypto mismatch, stale OptimizerStepResult row (Closes #10158) Master 18c98cc77 was red on t27b-native-ratchet (rust_convert: ledger pass, now blocked by FnDecl(reference CSE hoist)) and on Corpus ratchet (tri types classified: STALE OptimizerStepResult after #10088). Every open PR inherited both reds. - rust_convert.t27 / crypto.t27: the .t27 repairs from draft #9637, without its workflow and Python; gen-rust regenerated, both sealed with zig 0.16. - type_conflicts_classified.json + TYPE_CONFLICTS.md: drop the stale row, DRIFT 62 -> 61. Co-Authored-By: Claude Opus 5.5 --- .../src_port::trios_mesh_node_crypto.json | 28 +++++++++++++++++++ .trinity/seals/t27o_T27oRust.json | 14 +++++----- docs/TYPE_CONFLICTS.md | 3 +- docs/reports/type_conflicts_classified.json | 14 +--------- gen/rust/tools/t27o/rust_convert.rs | 7 +++-- .../crates/trios-mesh-node/src/crypto.t27 | 19 +++++++++---- specs/tools/t27o/rust_convert.t27 | 7 +++-- 7 files changed, 60 insertions(+), 32 deletions(-) create mode 100644 .trinity/seals/src_port::trios_mesh_node_crypto.json diff --git a/.trinity/seals/src_port::trios_mesh_node_crypto.json b/.trinity/seals/src_port::trios_mesh_node_crypto.json new file mode 100644 index 0000000000..ea52e0dcd9 --- /dev/null +++ b/.trinity/seals/src_port::trios_mesh_node_crypto.json @@ -0,0 +1,28 @@ +{ + "built_by": "t27c-bootstrap@0.5.2+0d4fe82f2", + "closure": [], + "config": "gen=c,rust,verilog,zig;tests=zig", + "gen_hash_c": "sha256:1e74b996ade22e83796910c9b4e244b1cc04f6253a35505054198be62254e853", + "gen_hash_rust": "sha256:ea7c338992c88064b5375c0b5462bb4868f244384f01a344780f025452123335", + "gen_hash_verilog": "sha256:fc2816200338199bc3a3553bfd5fa97ddc9ec7e707af61b23ec096758d38e309", + "gen_hash_zig": "sha256:11c4e273387ec011bd4e7c6a27d1a0217fc821c5c58f1abb7e225a95d9eee469", + "module": "port::trios_mesh_node_crypto", + "ring": 12, + "seal_schema": 2, + "sealed_at": "2026-10-18T02:25:06Z", + "sealed_by": "t27c-bootstrap@0.5.2", + "spec_hash": "sha256:d1d3ed152196c59afbafb1b1c08af5ef6e270fd7e354dc4f101e5bc9dcf212d7", + "spec_path": "specs/port/trios/crates/trios-mesh-node/src/crypto.t27", + "tests": { + "failed": 0, + "failing": [], + "forced": false, + "passed": 23, + "total": 23, + "vacuous": 0 + }, + "toolchain": { + "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "zig": "0.16.0" + } +} \ No newline at end of file diff --git a/.trinity/seals/t27o_T27oRust.json b/.trinity/seals/t27o_T27oRust.json index 4b9ba5d329..84074f8dd5 100644 --- a/.trinity/seals/t27o_T27oRust.json +++ b/.trinity/seals/t27o_T27oRust.json @@ -1,17 +1,17 @@ { - "built_by": "t27c-bootstrap@0.5.2+e7fbc2639", + "built_by": "t27c-bootstrap@0.5.2+0d4fe82f2", "closure": [], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:5ced192099954e788bc953c0973428c9f278751b7610f050e07758a9a6611a14", - "gen_hash_rust": "sha256:ae84f2ed194de288b42f9dfeb10b6a965c65f99ca992ef82aaf971082aaca512", - "gen_hash_verilog": "sha256:130434cc65aee3c2c38a14354c010aedbfd11c6e2e565a2da72448ca8a471d17", - "gen_hash_zig": "sha256:a3aee0b8ec566bb21157cb64c6330e87ffcb44ce765a2bf150beb95dd0c9b2ab", + "gen_hash_c": "sha256:93076da93a404ea49f455526fa1d25dfc8b6040dda6f2972dcb747074eb755a3", + "gen_hash_rust": "sha256:d912c313830e2ec4ba390adcf66baabba71cecd6f720246e1a619a95b0964334", + "gen_hash_verilog": "sha256:2b7550a7c7d5e0f989df3e4a00597c788e5abc0671043978bef8bd4cfd40aa9c", + "gen_hash_zig": "sha256:a47e14e956324ccd1ff1d9f521f2761b659ee6e61623c53365af62043c731264", "module": "T27oRust", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-12T10:09:28Z", + "sealed_at": "2026-10-18T02:25:04Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:f4ee9bcc7818621bf5d591d8d74f6cb41ef6fcac3e558e550af6dc45d549aec5", + "spec_hash": "sha256:690282a6a0c834606de0def8b4b05499c1a0e415bc270ffac2d908bc3ca5abbf", "spec_path": "specs/tools/t27o/rust_convert.t27", "tests": { "failed": 0, diff --git a/docs/TYPE_CONFLICTS.md b/docs/TYPE_CONFLICTS.md index 3193df6ccb..49e05ef71e 100644 --- a/docs/TYPE_CONFLICTS.md +++ b/docs/TYPE_CONFLICTS.md @@ -61,7 +61,7 @@ definition moves. `tri types classified` cross-checks the file against a live Non-empty drift in either direction exits non-zero. A classification nobody re-reads becomes a claim about a tree that no longer exists. -## DRIFT -- 62 names +## DRIFT -- 61 names One concept, two definitions. These are the ones with a repair. @@ -90,7 +90,6 @@ One concept, two definitions. These are the ones with a repair. | `Match` | 2 | 2 files | Collapse Match/MatchResult/RegexMatch onto regex_advanced.t27's RegexMatch (it is already the... | | `MemPort` | 2 | 2 files | Make fpga/hir.t27 import Memory's MemPort rather than restate it; reconcile MAX_MEM_PORTS (4 ... | | `Message` | 3 | 3 files | Pick one Message and one MessageRole (with fixed discriminants) in provider/schema.t27; have ... | -| `OptimizerStepResult` | 3 | 2 files | Two fixes: (1) delete the second body of adamw.t27 (lines ~460-end duplicate lines ~14-459) o... | | `PinAssignment` | 3 | 3 files | Hoist one PinAssignment (the 9-field version) into a shared boards module and have all three ... | | `PinMapping` | 2 | 2 files | Either give each board its own name (ArtyA7PinMapping / QMTechA100TPinMapping) or use the spe... | | `PolicyOutput` | 2 | 2 files | Rename to PPOPolicyOutput / SACPolicyOutput, matching the SACActorConfig convention already i... | diff --git a/docs/reports/type_conflicts_classified.json b/docs/reports/type_conflicts_classified.json index b8adcf8b58..0dec0b6f75 100644 --- a/docs/reports/type_conflicts_classified.json +++ b/docs/reports/type_conflicts_classified.json @@ -1,7 +1,7 @@ { "note": "Classification of every conflicted type name reported by `tri types dup`. DRIFT = one concept that grew two definitions; DISTINCT = two concepts that collided on a name. Evidence is the reading that decided it. Regenerate the observation with `tri types dup`; cross-check this file against it with `tri types classified`.", "verdicts": { - "DRIFT": 62, + "DRIFT": 61, "DISTINCT": 47 }, "names": [ @@ -581,18 +581,6 @@ "confidence": "certain \u2014 a self-hosting parser's AST and a collections-library list cell are unrelated by construction; the only overlap is the English word \"node\"", "suggested_action": "Leave both; if the type namespace is ever flattened, rename the cache one to LruEntry." }, - { - "name": "OptimizerStepResult", - "sites": [ - "specs/ml/optimizer/adamw.t27:46", - "specs/ml/optimizer/adamw.t27:501", - "specs/ml/optimizer/sgd_momentum.t27:40" - ], - "verdict": "DRIFT", - "evidence": "`updated_params: []gf16::GF16, m: []gf16::GF16, v: []gf16::GF16, step_norm: gf16::GF16` (adamw) vs `updated_params: []gf16::GF16, velocities: []gf16::GF16, step_norm: gf16::GF16` (sgd_momentum). The trailing comments are byte-identical across the two files \u2014 `// New parameter values` on updated_params and `// L2 norm of the parameter update` on step_norm \u2014 so the lineage is copy-paste; only the optimizer's own state field was swapped (Adam's first/second moments m,v for SGD's velocities). Both files namespace their siblings and leave this one bare: AdamWConfig/AdamWState next to a plain OptimizerStepResult, SgdMomentumConfig/SgdMomentumState next to a plain OptimizerStepResult. Separately, sites 1 and 2 are the SAME FILE and byte-identical: specs/ml/optimizer/adamw.t27 (1019 lines) holds two complete copies of its body \u2014 `// 2. Types` at lines 25 and 470, `// 3. Core Functions` at 54 and 509, `pub const AdamWConfig` at 28 and 483, `pub const OptimizerStepResult` at 46 and 501 \u2014 an ASCII/PhiVariant rewrite pasted in without deleting the original, so `init` and `step` are each declared twice in one module and AdamWConfig's last field is `use_phi_betas: bool` in the first copy and `phi_variant: PhiVariant` in the second.", - "confidence": "certain \u2014 identical comment text on the shared fields proves common origin, and both live in specs/ml/optimizer/", - "suggested_action": "Two fixes: (1) delete the second body of adamw.t27 (lines ~460-end duplicate lines ~14-459) or finish the intended replacement; (2) rename to AdamWStepResult / SgdStepResult, or factor a common `{ updated_params, step_norm }` and let each optimizer return its own state alongside." - }, { "name": "OscillatorState", "sites": [ diff --git a/gen/rust/tools/t27o/rust_convert.rs b/gen/rust/tools/t27o/rust_convert.rs index 199a90f884..99102edd9f 100644 --- a/gen/rust/tools/t27o/rust_convert.rs +++ b/gen/rust/tools/t27o/rust_convert.rs @@ -7262,7 +7262,7 @@ pub fn out_format(src: &[u8], st: &mut [usize], out: &mut [u8], a: usize, ret: b } let fq: usize = quoted_end(src, f); let mut p: usize = (f + 1); - let mut piece: usize = (f + 1); + let mut piece: usize = p; let mut arg: usize = skip_ws(src, fq); if tok_is(src, arg, b",") { arg = skip_ws(src, tok_end(src, arg)); @@ -7310,8 +7310,9 @@ pub fn out_format(src: &[u8], st: &mut [usize], out: &mut [u8], a: usize, ret: b refuse(st, R_STRUSE, a, a, fe); return (); } - if ((fq - 1) > piece) { - put_out_piece(src, st, out, piece, (fq - 1)); + let tail_end: usize = (fq - 1); + if (tail_end > piece) { + put_out_piece(src, st, out, piece, tail_end); newline(st, out); } st[(P) as usize] = skip_ws(src, rp); diff --git a/specs/port/trios/crates/trios-mesh-node/src/crypto.t27 b/specs/port/trios/crates/trios-mesh-node/src/crypto.t27 index d088806ae5..3730bca1c2 100644 --- a/specs/port/trios/crates/trios-mesh-node/src/crypto.t27 +++ b/specs/port/trios/crates/trios-mesh-node/src/crypto.t27 @@ -398,10 +398,12 @@ module port::trios_mesh_node_crypto { // crypto.rs lines 41-50: rand fills 32 bytes and they become the secret // directly -- no stretching, unlike from_seed. The OS randomness is the // parameter here; everything after it is the derivation from_seed tails - // with. - pub fn MeshKeypair_random(entropy: [32]u8) -> MeshKeypair { - const public: [32]u8 = pubkey_from_secret(entropy); - const digest: [32]u8 = sha256_32(public); + // with. The X25519 public key of the entropy and the SHA-256 of that public key + // are the host's results (the header: primitives are declared, never called by a + // test), so they arrive as parameters like the entropy; a body that called the + // undefined primitives read bytes nothing wrote, which t27b's interpreter refuses + // and Zig only hides by filling them. + pub fn MeshKeypair_random(entropy: [32]u8, public: [32]u8, digest: [32]u8) -> MeshKeypair { return keypair_from_public(entropy, public, digest); } @@ -600,8 +602,15 @@ module port::trios_mesh_node_crypto { // lines 43-45: the raw 32 random bytes ARE the secret -- no 0xA3 // layout, no stretching; only from_seed does that. const e: [32]u8 = stretch_seed(6); - const kp: MeshKeypair = MeshKeypair_random(e); + const p: [32]u8 = stretch_seed(7); + const d: [32]u8 = stretch_seed(8); + const kp: MeshKeypair = MeshKeypair_random(e, p, d); assert(arr32_eq(kp.secret, e)); + assert(arr32_eq(kp.public, p)); + assert(kp.secret[0] == 6); + assert(kp.public[0] == 7); + assert(kp.dest_hash[0] == 8); + assert(kp.dest_hash[1] == 0xA3); } test b64_alphabet_table { diff --git a/specs/tools/t27o/rust_convert.t27 b/specs/tools/t27o/rust_convert.t27 index 170da2ed90..46e6de8a35 100644 --- a/specs/tools/t27o/rust_convert.t27 +++ b/specs/tools/t27o/rust_convert.t27 @@ -6206,8 +6206,10 @@ pub fn out_format(src: []const u8, st: []usize, out: []u8, a: usize, ret: bool) const f : usize = skip_ws(src, lp + 1); if (!str_tok(src, f)) { refuse(st, R_STRUSE, a, a, fe); return; } const fq : usize = quoted_end(src, f); + // `f + 1` is spelled once: repeated, it became a `_cse` temporary that t27c writes above `const f` + // (t27b: FnDecl(reference CSE hoist), #9632). var p : usize = f + 1; - var piece : usize = f + 1; + var piece : usize = p; // the arguments start after the format string's comma: format!(FMT, a0, a1, ..) var arg : usize = skip_ws(src, fq); if (tok_is(src, arg, ",")) { arg = skip_ws(src, tok_end(src, arg)); } @@ -6240,7 +6242,8 @@ pub fn out_format(src: []const u8, st: []usize, out: []u8, a: usize, ret: bool) refuse(st, R_STRUSE, a, a, fe); return; } - if (fq - 1 > piece) { put_out_piece(src, st, out, piece, fq - 1); newline(st, out); } + const tail_end : usize = fq - 1; + if (tail_end > piece) { put_out_piece(src, st, out, piece, tail_end); newline(st, out); } st[P] = skip_ws(src, rp); if (ret) { puts(st, out, "return t27o_w;"); } }