From 8fe7511753727b80c21961c40353dfe49f0563a8 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Mon, 19 Oct 2026 06:13:04 +0700 Subject: [PATCH] test(claw): kill the three text.t27 mutation survivors A mutation sweep of specs/claw/text.t27 left 3 of 44 single-operator mutants alive: - put_count's clip `w + k < cap` changed to `<=` - has_prefix's length guard `s_len < p_len` changed to `<=` - has_prefix's byte-loop reject changed to return true New tests: - has_prefix_rejects_a_mismatch_that_fits: a first-byte mismatch, a last-byte mismatch, and a string exactly equal to the prefix. - put_count_clipped_write_leaves_the_byte_at_cap_alone: cap 3 for a 4-digit count; the byte at index cap stays untouched. Sweep: 44/44 caught. text 9/9 in t27c and t27b. The committed gen-c output regenerates byte-identically. The claw_ClawText seal is resaved, and 32/32 seals verify. Closes #10713 Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/claw_ClawText.json | 20 ++++++++++---------- specs/claw/text.t27 | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/.trinity/seals/claw_ClawText.json b/.trinity/seals/claw_ClawText.json index 65ddec148c..bd3ff45377 100644 --- a/.trinity/seals/claw_ClawText.json +++ b/.trinity/seals/claw_ClawText.json @@ -1,28 +1,28 @@ { - "built_by": "t27c-bootstrap@0.5.2+4ab200073", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:91762b4b1d04fca688d249cd452eace91ca586e70aee0551c770f84b5da67300", - "gen_hash_rust": "sha256:3c2ab4d541e80a7b7ecb335a3bce0ebaac46c1e0e64c67c39468509c98aa9da4", - "gen_hash_verilog": "sha256:bad1d4ab44c3cb0be36ce57227762d216b5aa30538d9a9457cfe10b731fdd7d4", - "gen_hash_zig": "sha256:d208b808b576f1dbe7b7cc721653deaf2ddcc605a9ef0b82970c19e000f7d0c6", + "gen_hash_c": "sha256:b59cbd98a2c2f3973ce97cf39abc9b992a590055a34394a0547a8d0a7ff76758", + "gen_hash_rust": "sha256:7c1f327640c4418baa19d847e23ec9d3ac96707b3d8a5ccea0b8f9d860af3492", + "gen_hash_verilog": "sha256:1166cfb46959e156cc1d9a03b4994fef8cb7b5b8071528c1793642867a3d3e68", + "gen_hash_zig": "sha256:98adafb0eac8bba62c82365c19d1f9d6a718c327917bfc2da761b2a02b7b433b", "module": "ClawText", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:41:18Z", + "sealed_at": "2026-10-18T23:12:27Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:b65da69dff231c61a6d3a48558af9e17af42e1acbe3f4763348f1f0c2f118f21", + "spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad", "spec_path": "specs/claw/text.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 7, - "total": 7, + "passed": 9, + "total": 9, "vacuous": 0 }, "toolchain": { - "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10", "zig": "0.16.0" } } \ No newline at end of file diff --git a/specs/claw/text.t27 b/specs/claw/text.t27 index 564d87f9b9..8520eb3954 100644 --- a/specs/claw/text.t27 +++ b/specs/claw/text.t27 @@ -175,3 +175,24 @@ test has_prefix_matches_and_rejects { assert has_prefix("", 0, "claw-v", 6) == false; assert has_prefix("anything", 8, "", 0) == true; } + +test has_prefix_rejects_a_mismatch_that_fits { + // Every reject above is a string shorter than the prefix, so the byte loop's reject was never + // reached: a loop that answered true on a mismatch passed (mutation sweep, #10713). These + // fit and differ in the first byte, then the last one. + assert has_prefix("xlaw-v0.1", 9, "claw-v", 6) == false; + assert has_prefix("claw-x0.1", 9, "claw-v", 6) == false; + // A string that is exactly the prefix is a prefix: `s_len < p_len` must not become `<=`. + assert has_prefix("claw-v", 6, "claw-v", 6) == true; +} + +test put_count_clipped_write_leaves_the_byte_at_cap_alone { + // The clip is `w + k < cap`. With `<=` the last digit lands one byte past cap. Only a test + // that looks at the byte at cap can tell; the earlier tests never hand in a short cap. + var out : [8]u8 = undefined; + for i in 0..8 { out[i] = 0; } + var w : usize = put_count(&out, 3, 0, 1050); + assert w == 4; + assert buf_has(&out, 3, "105", 3) == true; + assert out[3] == 0; +}