diff --git a/.trinity/seals/claw_ClawGates.json b/.trinity/seals/claw_ClawGates.json index 9beed58429..08de0933c1 100644 --- a/.trinity/seals/claw_ClawGates.json +++ b/.trinity/seals/claw_ClawGates.json @@ -7,16 +7,16 @@ } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:723a598914ee23e57be303db50d42531cc4e060b0dc2f4cb56234e53ef1f545c", - "gen_hash_rust": "sha256:a959e6e61dbce9d00050932baed8e74633a5ce6e4a6dc376f9ee3c5494445473", - "gen_hash_verilog": "sha256:27185ecb4aa7e109f3c9fb7280863ac2fff7f4262bf8b02b9c3177612079580f", - "gen_hash_zig": "sha256:d96163a4182c592c121c7cf497d5770791f41fb7fb382300b2d79dee3ef3c79e", + "gen_hash_c": "sha256:e83faa16fdda54ccb71a5cef820dcbcb0b115a1a964b1b769e8efa3fe4f46de4", + "gen_hash_rust": "sha256:f5a230d83ed3b53022cda5241bcb97a98a6f7d35118813dd896bfd94a408db57", + "gen_hash_verilog": "sha256:e60c97323fe49104fa91dec8d4d70db8c3070acb09e10955bae928b09a0aaeac", + "gen_hash_zig": "sha256:2bb85ab7683c3ce5f9e68d5cdeec753084408e7c0b36e65e68a3aba22a8312e8", "module": "ClawGates", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T22:24:12Z", + "sealed_at": "2026-10-18T22:41:04Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:1976cf9af48f8799d5d7584648c3cca97ca35d0ccd31b5019b0a1fed909f1e90", + "spec_hash": "sha256:944d2af8d1a9f6ad261a527445f94922e3f299d5bb3657341f6f5cdc5c38f9c1", "spec_path": "specs/claw/gates.t27", "tests": { "failed": 0, diff --git a/.trinity/seals/claw_ClawGatesPins.json b/.trinity/seals/claw_ClawGatesPins.json index fce3514a73..804d43fe68 100644 --- a/.trinity/seals/claw_ClawGatesPins.json +++ b/.trinity/seals/claw_ClawGatesPins.json @@ -1,33 +1,33 @@ { - "built_by": "t27c-bootstrap@0.5.2+4ab200073", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/claw/gates.t27", - "spec_hash": "sha256:3ae3db764f44ce4e0c45b8c7af6f17db39755e3c23be43c17a75409394a0a32d" + "spec_hash": "sha256:944d2af8d1a9f6ad261a527445f94922e3f299d5bb3657341f6f5cdc5c38f9c1" } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:cd501815d2c74fa080136736e0518a67b592c44a853000153812721f8e8ea57d", - "gen_hash_rust": "sha256:af20324af83bbf7f3eba345a64033ca44fca7934a470055624ec381a77ff74e3", - "gen_hash_verilog": "sha256:1e0ce75eba74ad61a29409655a21add1b64eafd9d90a7c12d748d4173f082478", - "gen_hash_zig": "sha256:ca3b9d27acacfadaeea3cedd46f29834c25e2e258819017d71653a3a24df473b", + "gen_hash_c": "sha256:9b019d7001ef279fa03cb313208c21af916bcd0b04a18301b3ba9a11b61c4c7e", + "gen_hash_rust": "sha256:82c7f3aa3cdb72a027efb1f3c66b96052c7dfdb63d0be68a44458ff8d694e240", + "gen_hash_verilog": "sha256:0ae1fdb0af1f915ab3ec0b2926c26061de7ca11cf1d76919464dda405b48b3f5", + "gen_hash_zig": "sha256:7ad136326adee3ce56c546e7d70a4f5d8a7283ffd0f12b9efbdde3a31a5d3036", "module": "ClawGatesPins", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:41:14Z", + "sealed_at": "2026-10-18T22:41:06Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:e18a7800770e75607f68b089aaa38880e490276fbe6706372b0e302bb990238c", + "spec_hash": "sha256:a6ab857762046c32d4b9b1314e8709e2e74a1b6faada15b2d38aeecb7fab5ef8", "spec_path": "specs/claw/gates_pins.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 5, - "total": 5, + "passed": 6, + "total": 6, "vacuous": 0 }, "toolchain": { - "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10", "zig": "0.16.0" } } \ No newline at end of file diff --git a/gen/c/claw/gates.c b/gen/c/claw/gates.c index a1f4491a12..6e66ee09e5 100644 --- a/gen/c/claw/gates.c +++ b/gen/c/claw/gates.c @@ -26,6 +26,7 @@ static const const char* NAMES[67] = { "agent-runner-docker", "auto-merge-ready-prs", "bootstrap-tests", "build-paper", "build-vivado-image", "catalog-count-gate", "cli-tri", "conflict-markers", "conformance-integrity-gate", "coq-kernel", "coq-proofs", "corpus-ratchet", "damage-negatives", "deploy-api", "documented-commands", "dupe-ratchet", "emit-bitexact-gate", "exhaustive-nightly", "fix-carries-source", "fpga-build", "gate-topology", "gf-wide-conformance", "gf16-conformance", "harness-scratch", "issue-gate", "l1-traceability", "lean-proofs", "loop-tools-gate", "needs-boundary", "oracle-nightly", "orphan-modules", "own-language", "pack-index-consistency-gate", "phi-loop-ci", "pr-budget", "pr-dashboard", "pusher", "queen-doctor", "queen-export-push", "queen-feed-empty-bodies", "queen-feed-roadmap", "queen-feed-untested", "queen-publish", "queen-refile", "queen-watchdog", "release", "rings-rust", "sandbox-docker", "sbom", "schema-validation", "scorecard", "seal-coverage", "seal-staleness-warn", "secret-scan", "sign-release", "spec-guards", "spec-parse-ratchet", "t27b-native", "t27o-golden", "t27o-release", "untrusted-input-gate", "verilog-widths", "vivado-synth", "wasm-explorer", "withdrawn-live-gate", "xilinx7-l3-bench", "zenodo-publish" }; static const size_t NAME_LENS[67] = { 19, 20, 15, 11, 18, 18, 7, 16, 26, 10, 10, 14, 16, 10, 19, 12, 18, 18, 18, 10, 13, 19, 16, 15, 10, 15, 11, 15, 14, 14, 14, 12, 27, 11, 9, 12, 6, 12, 17, 23, 18, 19, 13, 12, 14, 7, 10, 14, 4, 17, 9, 13, 19, 11, 12, 11, 18, 11, 11, 12, 20, 14, 12, 13, 19, 16, 14 }; static const uint8_t CLASSES[67] = { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static const size_t EVENT_LENS[67] = { 22, 46, 35, 35, 17, 30, 17, 35, 35, 35, 35, 35, 35, 22, 35, 35, 30, 26, 30, 35, 44, 35, 35, 35, 37, 30, 30, 35, 26, 26, 35, 12, 35, 30, 19, 30, 26, 26, 26, 26, 26, 26, 31, 26, 26, 7, 35, 22, 30, 35, 54, 35, 30, 35, 25, 35, 35, 35, 13, 4, 35, 35, 17, 17, 35, 30, 25 }; static const const char* EVENTS[67] = { "push,workflow_dispatch", "schedule,pull_request_target,workflow_dispatch", "push,pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "workflow_dispatch", "pull_request,workflow_dispatch", "pull_request,push", "pull_request,push,workflow_dispatch", "push,pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "push,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,workflow_dispatch", "schedule,workflow_dispatch", "pull_request,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch,schedule", "push,pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request_target,workflow_dispatch", "pull_request,workflow_dispatch", "pull_request,workflow_dispatch", "pull_request,push,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request", "push,pull_request,workflow_dispatch", "pull_request,workflow_dispatch", "pull_request_target", "workflow_dispatch,pull_request", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "push,schedule,workflow_dispatch", "schedule,workflow_dispatch", "schedule,workflow_dispatch", "release", "push,pull_request,workflow_dispatch", "push,workflow_dispatch", "push,release,workflow_dispatch", "pull_request,push,workflow_dispatch", "branch_protection_rule,schedule,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "release,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "workflow_call", "push", "pull_request,push,workflow_dispatch", "pull_request,push,workflow_dispatch", "workflow_dispatch", "push,pull_request", "pull_request,push,workflow_dispatch", "workflow_dispatch,pull_request", "release,workflow_dispatch" }; #define P_OK 0 #define P_SPEC_ONLY 1 @@ -53,7 +54,7 @@ uint8_t class_of(const char* name, size_t name_len); bool is_blocking(const char* name, size_t name_len); const char* events_of(const char* name, size_t name_len); uint32_t count_class(uint8_t c); -bool rows_filled(const char* names[static 67], const char* events[static 67]); +bool rows_filled(size_t name_lens[static 67], size_t event_lens[static 67]); bool every_row_filled(void); bool names_unique_in(const char* names[static 67], size_t lens[static 67]); bool all_names_unique(void); @@ -107,12 +108,12 @@ uint32_t count_class(uint8_t c) { return n; } -bool rows_filled(const char* names[static 67], const char* events[static 67]) { +bool rows_filled(size_t name_lens[static 67], size_t event_lens[static 67]) { for (size_t i = 0; i < 67; i++) { - if ((names[i] == "")) { + if ((name_lens[i] == 0)) { return false; } - if ((events[i] == "")) { + if ((event_lens[i] == 0)) { return false; } } @@ -120,7 +121,7 @@ bool rows_filled(const char* names[static 67], const char* events[static 67]) { } bool every_row_filled(void) { - return rows_filled(NAMES, EVENTS); + return rows_filled(NAME_LENS, EVENT_LENS); } bool names_unique_in(const char* names[static 67], size_t lens[static 67]) { @@ -604,19 +605,21 @@ void test_coverage_report_lines_are_exact(void) { } void test_a_hole_in_either_column_fails_the_filled_check(void) { - assert((rows_filled(NAMES, EVENTS) == true)); - const char* n[67] = {0}; + assert((rows_filled(NAME_LENS, EVENT_LENS) == true)); + size_t n[67] = {0}; for (size_t i = 0; i < 67; i++) { - n[i] = NAMES[i]; + n[i] = NAME_LENS[i]; } - n[66] = ""; - assert((rows_filled(n, EVENTS) == false)); - const char* e[67] = {0}; + n[66] = 0; + assert((rows_filled(n, EVENT_LENS) == false)); + size_t e[67] = {0}; for (size_t i = 0; i < 67; i++) { - e[i] = EVENTS[i]; + e[i] = EVENT_LENS[i]; } - e[0] = ""; - assert((rows_filled(NAMES, e) == false)); + e[0] = 0; + assert((rows_filled(NAME_LENS, e) == false)); + e[0] = 1; + assert((rows_filled(NAME_LENS, e) == true)); } void test_a_repeated_name_is_caught_wherever_it_sits(void) { diff --git a/specs/claw/gates.t27 b/specs/claw/gates.t27 index 1ede4a9be4..21945b9738 100644 --- a/specs/claw/gates.t27 +++ b/specs/claw/gates.t27 @@ -98,6 +98,25 @@ pub const CLASSES : [67]u8 = [ 0, 0, ]; +/// Length of EVENTS[i], parallel row, for the same reason as NAME_LENS: gen-c carries no .len. +/// specs/claw/gates_pins.t27 pins each row to EVENTS[i].len. +pub const EVENT_LENS : [67]usize = [ + 22, 46, 35, 35, 17, + 30, 17, 35, 35, + 35, 35, 35, 35, 22, + 35, 35, 30, 26, 30, + 35, 44, 35, 35, 35, + 37, 30, 30, 35, 26, + 26, 35, 12, 35, 30, + 19, 30, 26, 26, 26, 26, + 26, 26, 31, 26, 26, + 7, 35, 22, 30, 35, + 54, 35, 30, 35, 25, + 35, 35, 35, 13, 4, + 35, 35, 17, 17, 35, + 30, 25, +]; + /// Trigger keys of row i, comma-joined, as measured 2026-10-12 (see header). pub const EVENTS : [67]str = [ "push,workflow_dispatch", "schedule,pull_request_target,workflow_dispatch", "push,pull_request,workflow_dispatch", "push,pull_request,workflow_dispatch", "workflow_dispatch", @@ -151,18 +170,20 @@ pub fn count_class(c: u8) -> u32 { /// Every row of a table shaped like this one has a name and a recorded trigger set. The /// columns are parameters so a test can hand in a copy with one hole: a check that only reads -/// the constant table can never fail, and no mutant of it can die (#10686). -pub fn rows_filled(names: [67]str, events: [67]str) -> bool { +/// the constant table can never fail, and no mutant of it can die (#10686). It reads the length +/// columns, not the strings: gen-c lowers `s == ""` to a C pointer comparison, so in the +/// committed gates.c an empty-string test compared addresses, not contents. +pub fn rows_filled(name_lens: [67]usize, event_lens: [67]usize) -> bool { for i in 0..67 { - if names[i] == "" { return false; } - if events[i] == "" { return false; } + if name_lens[i] == 0 { return false; } + if event_lens[i] == 0 { return false; } } return true; } /// Every row of the inventory has a name and a recorded trigger set. pub fn every_row_filled() -> bool { - return rows_filled(NAMES, EVENTS); + return rows_filled(NAME_LENS, EVENT_LENS); } /// No name appears twice in a name column (with its length column). @@ -575,7 +596,7 @@ test coverage_report_carries_every_class { // The length-table pins live in specs/claw/gates_pins.t27: they read .len on // strings, which the zig runner executes and the gen-c backend cannot lower, // so they sit in a companion module that is never gen-c'd. A wrong number in -// NAME_LENS/PREFIX_LENS/SUFFIX_LENS/*_LEN fails there, not silently here. +// NAME_LENS/EVENT_LENS/PREFIX_LENS/SUFFIX_LENS/*_LEN fails there, not silently here. test audit_tail_line_matches_the_count { // The runner prints the report; the tail must say what the count says. @@ -616,15 +637,18 @@ test coverage_report_lines_are_exact { } test a_hole_in_either_column_fails_the_filled_check { - assert rows_filled(NAMES, EVENTS) == true; - var n : [67]str = undefined; - for i in 0..67 { n[i] = NAMES[i]; } - n[66] = ""; - assert rows_filled(n, EVENTS) == false; - var e : [67]str = undefined; - for i in 0..67 { e[i] = EVENTS[i]; } - e[0] = ""; - assert rows_filled(NAMES, e) == false; + assert rows_filled(NAME_LENS, EVENT_LENS) == true; + var n : [67]usize = undefined; + for i in 0..67 { n[i] = NAME_LENS[i]; } + n[66] = 0; + assert rows_filled(n, EVENT_LENS) == false; + var e : [67]usize = undefined; + for i in 0..67 { e[i] = EVENT_LENS[i]; } + e[0] = 0; + assert rows_filled(NAME_LENS, e) == false; + // One byte is enough: the check asks "empty or not", never "how long". + e[0] = 1; + assert rows_filled(NAME_LENS, e) == true; } test a_repeated_name_is_caught_wherever_it_sits { diff --git a/specs/claw/gates_pins.t27 b/specs/claw/gates_pins.t27 index 9295e05657..24a50374ba 100644 --- a/specs/claw/gates_pins.t27 +++ b/specs/claw/gates_pins.t27 @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 ; specs/claw/gates_pins.t27 -- the length-table pins for specs/claw/gates.t27. -; gates.t27 carries every string length explicitly (NAME_LENS, PREFIX_LENS, +; gates.t27 carries every string length explicitly (NAME_LENS, EVENT_LENS, PREFIX_LENS, ; SUFFIX_LENS, HEAD_LEN, OK_TAIL_LEN, DRIFT_TAIL_LEN) because the gen-c backend ; lowers str to const char* and cannot express .len; those tables are the one ; hand-generated input to that idiom, and a wrong number there would miscompare @@ -22,6 +22,14 @@ test name_lens_pin_every_row_to_the_bytes { } } +test event_lens_pin_every_row_to_the_bytes { + // every_row_filled reads EVENT_LENS, not EVENTS: a zero here for a filled row, or a + // nonzero length for an emptied one, would make the filled check lie. + for i in 0..67 { + assert gates::EVENT_LENS[i] == gates::EVENTS[i].len; + } +} + test report_lens_pin_their_strings { for k in 0..3 { assert gates::PREFIX_LENS[k] == gates::LINE_PREFIX[k].len;