From 4ddad0d8293873ab64ef5cd81f85110cb7bae626 Mon Sep 17 00:00:00 2001 From: Dmitrii Vasilev Date: Mon, 19 Oct 2026 06:55:39 +0700 Subject: [PATCH] test(claw): kill the real refresh.t27 and sarif_feed.t27 mutation survivors A mutation sweep of refresh.t27 left 12 of 159 mutants alive; two are real. A sweep of sarif_feed.t27 left 14 of 34 alive; seven are real. Eight new tests kill all nine. They cover: - a 0 inside a line:col position - a column that needs a line number and a colon - a blank line between records - a two-field record - CRLF record lists - a finding list of exactly TSV_CAP bytes, and one byte over - a refresh record cut after its number reusing the previous record's field offsets Production code is unchanged. The re-sweep of the survivors catches all nine real ones. refresh 55/55 and sarif_feed 19/19 pass in t27c and t27b, with 0 vacuous passes. gen/c/claw/refresh.c and sarif_feed.c are regenerated: the diff is only the new tests and the test count. The other five committed gen-c files are byte-identical. Both seals are resaved; 32/32 seals verify. Closes #10721 Co-Authored-By: Claude Opus 5.5 --- .trinity/seals/claw_ClawRefresh.json | 20 ++--- .trinity/seals/claw_ClawSarifFeed.json | 22 ++--- gen/c/claw/refresh.c | 15 +++- gen/c/claw/sarif_feed.c | 108 ++++++++++++++++++++++++- specs/claw/refresh.t27 | 14 ++++ specs/claw/sarif_feed.t27 | 102 +++++++++++++++++++++++ 6 files changed, 258 insertions(+), 23 deletions(-) diff --git a/.trinity/seals/claw_ClawRefresh.json b/.trinity/seals/claw_ClawRefresh.json index 7e83f9802e..f888967af1 100644 --- a/.trinity/seals/claw_ClawRefresh.json +++ b/.trinity/seals/claw_ClawRefresh.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+cd19e1370", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/claw/sarif.t27", @@ -7,27 +7,27 @@ }, { "spec": "specs/claw/text.t27", - "spec_hash": "sha256:b65da69dff231c61a6d3a48558af9e17af42e1acbe3f4763348f1f0c2f118f21" + "spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad" } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:72a325030bde8ec8d9e8f93dc4369bbda169c8cf5a0ee8574f8c45b458402cd6", - "gen_hash_rust": "sha256:be392415c5fc220525e579f6f3d356af59cfe33261b855a341caa2876600d011", - "gen_hash_verilog": "sha256:e1c484b82ebaaa7c1cd80fa93a556b525a9a8eb1872a96a572335fcf1aa2234d", - "gen_hash_zig": "sha256:2f3ea1e66fd00ef18cacdb8e43609d51ce82ef3606a07a71913a252141501a1f", + "gen_hash_c": "sha256:1c383df74b33e54e94083a0fdf69f881c2e66dfbd4782eaf25c802cc9d34a923", + "gen_hash_rust": "sha256:ae3dd9bb91c8a7002b475e93675f594d463322bc1ad093e58db773c9de471ea5", + "gen_hash_verilog": "sha256:bc289ef977021141eaa77abbaa2541d0c366c58a6bfcc8d9b0b3cde82b78bde9", + "gen_hash_zig": "sha256:ee64c31aec4013292b28c005e1264d6ee1e7da3345a796d82222bcd3b5413786", "module": "ClawRefresh", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T17:02:21Z", + "sealed_at": "2026-10-18T23:55:20Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:9cbda0935680c5bf4dd24d9b68931b99d5e184339b3438399a647710eebb3cef", + "spec_hash": "sha256:6813191699e5c1bb152bb28126a34e87cf317fcfaf3c60c33c387ecd63af1df7", "spec_path": "specs/claw/refresh.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 54, - "total": 54, + "passed": 55, + "total": 55, "vacuous": 0 }, "toolchain": { diff --git a/.trinity/seals/claw_ClawSarifFeed.json b/.trinity/seals/claw_ClawSarifFeed.json index 7aa99c918c..5d1acf738f 100644 --- a/.trinity/seals/claw_ClawSarifFeed.json +++ b/.trinity/seals/claw_ClawSarifFeed.json @@ -1,5 +1,5 @@ { - "built_by": "t27c-bootstrap@0.5.2+4ab200073", + "built_by": "t27c-bootstrap@0.5.2+9448ab4be", "closure": [ { "spec": "specs/claw/sarif.t27", @@ -7,31 +7,31 @@ }, { "spec": "specs/claw/text.t27", - "spec_hash": "sha256:b65da69dff231c61a6d3a48558af9e17af42e1acbe3f4763348f1f0c2f118f21" + "spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad" } ], "config": "gen=c,rust,verilog,zig;tests=zig", - "gen_hash_c": "sha256:1d4af00634286fc1380b1e42f5c805040d2785db994fd2d77e5a842744b10fd2", - "gen_hash_rust": "sha256:b7d492bad65148117a534639a4fe56b6b5b9b1b5adb9dab191e8ecbf9e39b1de", - "gen_hash_verilog": "sha256:947693a5fcd68aa5d61033b4f5460cce578b7e4ac60e0e3dc747ffad75179e2e", - "gen_hash_zig": "sha256:84f5ee66b2e95897241550198889a8ea3e01e5bed950ec1deab818e8189a6be7", + "gen_hash_c": "sha256:519ae870ac2a06707590b61675d0c6907b54afde85d89f54e5edd32a9200b5a7", + "gen_hash_rust": "sha256:a0564073dd5e4f7c68b65d706d89e6950f74527c5070b1397ede9ef614a1ef28", + "gen_hash_verilog": "sha256:27f30f271abf0e5869a5ff6048d0c46c5e523811ddf0fceee8987d6ea398ac43", + "gen_hash_zig": "sha256:f71caa0d4b08846bc721e79bb5ad629bf7ac3f94ec563daaf1f26d56d5918cd7", "module": "ClawSarifFeed", "ring": 12, "seal_schema": 2, - "sealed_at": "2026-10-18T09:41:16Z", + "sealed_at": "2026-10-18T23:55:21Z", "sealed_by": "t27c-bootstrap@0.5.2", - "spec_hash": "sha256:da2503a08f35668d71ca7e8ed37862f4f0d09e1c7d2b30df80e3027cbc2bf5b6", + "spec_hash": "sha256:9b45e8bb4080261ff781aed5434b5f0bf0509e0f6a86d8516e8bfe9cb361e59a", "spec_path": "specs/claw/sarif_feed.t27", "tests": { "failed": 0, "failing": [], "forced": false, - "passed": 12, - "total": 12, + "passed": 19, + "total": 19, "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/refresh.c b/gen/c/claw/refresh.c index 79a15b0aee..e0ab12bedf 100644 --- a/gen/c/claw/refresh.c +++ b/gen/c/claw/refresh.c @@ -1474,6 +1474,18 @@ void test_the_second_digits_decide_the_order(void) { assert((out[47] == '3')); } +void test_a_record_cut_after_its_number_does_not_borrow_the_previous_fields(void) { + uint8_t r[512] = {0}; + size_t n = t_rec(&r, 512, 0, 4217, 600, false, 0, false, false, 0, 0, 3, 1); + n = put_str(&r, 512, n, "8\n", 2); + uint8_t out[4096] = {0}; + size_t d = refresh_plan(&r, n, &out, 4096, 0); + assert((t_lines(&out, d, 'R') == 1)); + assert((buf_has(&out, d, "R\t8\t", 4) == false)); + assert((buf_has(&out, d, "M\tclaw-refresh: 1 to update, ", 29) == true)); + assert((buf_has(&out, d, " 1 unreadable\n", 14) == true)); +} + /* ------------------------------------------------------- Test runner (compile with -DT27_TEST_MAIN to execute) @@ -1536,7 +1548,8 @@ int main(void) { test_the_513th_record_is_counted_as_unreadable_and_not_stored(); test_the_hour_digits_decide_the_order(); test_the_second_digits_decide_the_order(); - printf("All %d tests passed.\n", 54); + test_a_record_cut_after_its_number_does_not_borrow_the_previous_fields(); + printf("All %d tests passed.\n", 55); return 0; } #endif /* T27_TEST_MAIN */ diff --git a/gen/c/claw/sarif_feed.c b/gen/c/claw/sarif_feed.c index 1701e8f953..b71ec79b69 100644 --- a/gen/c/claw/sarif_feed.c +++ b/gen/c/claw/sarif_feed.c @@ -51,6 +51,7 @@ size_t put_noparse(uint8_t* dst, size_t cap, size_t w, uint8_t* raw, size_t ps, size_t put_unwritten(uint8_t* dst, size_t cap, size_t w, uint8_t* raw, size_t ps, size_t pe); size_t feed_tsv(uint8_t* raw, size_t n, uint8_t* out, size_t cap); size_t feed_sarif(uint8_t* raw, size_t n, uint8_t* out, size_t out_cap); +size_t t_unwritten_lines(uint8_t* dst, size_t cap, uint32_t count, size_t plen, size_t last); int32_t digit_val(uint8_t b); size_t field_end(uint8_t* text, size_t e, size_t s); bool field_eq(uint8_t* text, size_t s, size_t e, const char* name, size_t n); @@ -187,6 +188,26 @@ size_t feed_sarif(uint8_t* raw, size_t n, uint8_t* out, size_t out_cap) { return sarif_render(&tsv, tn, DEFAULT_MAX_RESULTS, out, out_cap); } +size_t t_unwritten_lines(uint8_t* dst, size_t cap, uint32_t count, size_t plen, size_t last) { + size_t x = 0; + uint32_t c = 0; + while ((c < count)) { + size_t k = 0; + while ((k < plen)) { + x = put_byte(dst, cap, x, 'p'); + k += 1; + } + x = put_str(dst, cap, x, "\tUNWRITTEN\t\n", 12); + c += 1; + } + size_t j = 0; + while ((j < last)) { + x = put_byte(dst, cap, x, 'q'); + j += 1; + } + return put_str(dst, cap, x, "\tUNWRITTEN\t\n", 12); +} + int32_t digit_val(uint8_t b) { if ((b == '0')) { return 0; @@ -814,6 +835,84 @@ void test_a_message_with_a_quote_or_a_tab_stays_one_valid_finding(void) { assert((buf_has(&out, d, "\"executionSuccessful\":true", 26) == true)); } +void test_a_zero_inside_a_position_is_a_digit(void) { + uint8_t r[128] = {0}; + size_t n = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line 10:20\n", 30); + uint8_t out[8192] = {0}; + size_t d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"startLine\":10,\"startColumn\":20", 31) == true)); +} + +void test_a_column_needs_a_line_number_and_a_colon_right_after_it(void) { + uint8_t r[128] = {0}; + uint8_t out[8192] = {0}; + size_t n = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line :5\n", 27); + size_t d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"startLine\":1,\"startColumn\":1", 29) == true)); + n = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line 3-5\n", 28); + d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"startLine\":3,\"startColumn\":1", 29) == true)); +} + +void test_a_blank_line_between_records_is_skipped_not_refused(void) { + uint8_t r[128] = {0}; + size_t n = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\t\n\nb.t27\tUNWRITTEN\t\n", 35); + uint8_t out[8192] = {0}; + size_t d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"uri\":\"a.t27\"", 13) == true)); + assert((buf_has(&out, d, "\"uri\":\"b.t27\"", 13) == true)); + assert((buf_has(&out, d, "\"executionSuccessful\":true", 26) == true)); +} + +void test_a_two_field_record_is_refused_even_with_a_known_status(void) { + uint8_t r[128] = {0}; + size_t n = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\n", 16); + uint8_t out[8192] = {0}; + size_t d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"results\":[]", 12) == true)); + assert((buf_has(&out, d, "\"executionSuccessful\":false", 27) == true)); +} + +void test_crlf_records_are_all_read(void) { + uint8_t r[128] = {0}; + size_t n = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\t", 16); + n = put_byte(&r, 128, n, 13); + n = put_byte(&r, 128, n, '\n'); + n = put_str(&r, 128, n, "b.t27\tUNWRITTEN\t", 16); + n = put_byte(&r, 128, n, 13); + n = put_byte(&r, 128, n, '\n'); + assert((n == 36)); + assert((r[16] == 13)); + uint8_t out[8192] = {0}; + size_t d = feed_sarif(&r, n, &out, 8192); + assert((buf_has(&out, d, "\"uri\":\"a.t27\"", 13) == true)); + assert((buf_has(&out, d, "\"uri\":\"b.t27\"", 13) == true)); + assert((buf_has(&out, d, "\"executionSuccessful\":true", 26) == true)); +} + +void test_a_finding_list_of_exactly_tsv_cap_bytes_is_kept(void) { + uint8_t r[40000] = {0}; + size_t n = t_unwritten_lines(&r, 40000, 339, 100, 16); + uint8_t tsv[65536] = {0}; + assert((feed_tsv(&r, n, &tsv, TSV_CAP) == TSV_CAP)); + uint8_t out[262144] = {0}; + size_t d = feed_sarif(&r, n, &out, 262144); + assert((sarif_fits(d, 262144) == true)); + assert((buf_has(&out, d, "\"uri\":\"qqqqqqqqqqqqqqqq\"", 24) == true)); + assert((buf_has(&out, d, "\"executionSuccessful\":true", 26) == true)); +} + +void test_a_finding_list_one_byte_over_tsv_cap_is_refused_whole(void) { + uint8_t r[40000] = {0}; + size_t n = t_unwritten_lines(&r, 40000, 339, 100, 17); + uint8_t tsv[65536] = {0}; + assert((feed_tsv(&r, n, &tsv, TSV_CAP) == (TSV_CAP + 1))); + uint8_t out[262144] = {0}; + size_t d = feed_sarif(&r, n, &out, 262144); + assert((buf_has(&out, d, "\"results\":[]", 12) == true)); + assert((buf_has(&out, d, "\"executionSuccessful\":false", 27) == true)); +} + /* ------------------------------------------------------- Test runner (compile with -DT27_TEST_MAIN to execute) @@ -834,7 +933,14 @@ int main(void) { test_several_files_make_several_results_in_order(); test_empty_input_is_a_valid_empty_run(); test_a_message_with_a_quote_or_a_tab_stays_one_valid_finding(); - printf("All %d tests passed.\n", 12); + test_a_zero_inside_a_position_is_a_digit(); + test_a_column_needs_a_line_number_and_a_colon_right_after_it(); + test_a_blank_line_between_records_is_skipped_not_refused(); + test_a_two_field_record_is_refused_even_with_a_known_status(); + test_crlf_records_are_all_read(); + test_a_finding_list_of_exactly_tsv_cap_bytes_is_kept(); + test_a_finding_list_one_byte_over_tsv_cap_is_refused_whole(); + printf("All %d tests passed.\n", 19); return 0; } #endif /* T27_TEST_MAIN */ diff --git a/specs/claw/refresh.t27 b/specs/claw/refresh.t27 index 7470a6e89d..5e45054075 100644 --- a/specs/claw/refresh.t27 +++ b/specs/claw/refresh.t27 @@ -1215,3 +1215,17 @@ test the_second_digits_decide_the_order { assert out[2] == '9'; assert out[47] == '3'; } + +// The test below was written against a mutation sweep of this file (#10721). + +test a_record_cut_after_its_number_does_not_borrow_the_previous_fields { + var r : [512]u8 = undefined; + var n : usize = t_rec(&r, 512, 0, 4217, 600, false, 0, false, false, 0, 0, 3, 1); + n = put_str(&r, 512, n, "8\n", 2); + var out : [4096]u8 = undefined; + const d : usize = refresh_plan(&r, n, &out, 4096, 0); + assert t_lines(&out, d, 'R') == 1; + assert buf_has(&out, d, "R\t8\t", 4) == false; + assert buf_has(&out, d, "M\tclaw-refresh: 1 to update, ", 29) == true; + assert buf_has(&out, d, " 1 unreadable\n", 14) == true; +} diff --git a/specs/claw/sarif_feed.t27 b/specs/claw/sarif_feed.t27 index 8e845f3385..eee95463a4 100644 --- a/specs/claw/sarif_feed.t27 +++ b/specs/claw/sarif_feed.t27 @@ -258,3 +258,105 @@ test a_message_with_a_quote_or_a_tab_stays_one_valid_finding { assert buf_has(&out, d, "got \\\"x\\\" then y", 16) == true; assert buf_has(&out, d, "\"executionSuccessful\":true", 26) == true; } + +// The tests below were written against a mutation sweep of this file (#10721). + +test a_zero_inside_a_position_is_a_digit { + var r : [128]u8 = undefined; + const n : usize = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line 10:20\n", 30); + var out : [8192]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"startLine\":10,\"startColumn\":20", 31) == true; +} + +test a_column_needs_a_line_number_and_a_colon_right_after_it { + var r : [128]u8 = undefined; + var out : [8192]u8 = undefined; + var n : usize = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line :5\n", 27); + var d : usize = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"startLine\":1,\"startColumn\":1", 29) == true; + n = put_str(&r, 128, 0, "a.t27\tNOPARSE\te at line 3-5\n", 28); + d = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"startLine\":3,\"startColumn\":1", 29) == true; +} + +test a_blank_line_between_records_is_skipped_not_refused { + var r : [128]u8 = undefined; + const n : usize = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\t\n\nb.t27\tUNWRITTEN\t\n", 35); + var out : [8192]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"uri\":\"a.t27\"", 13) == true; + assert buf_has(&out, d, "\"uri\":\"b.t27\"", 13) == true; + assert buf_has(&out, d, "\"executionSuccessful\":true", 26) == true; +} + +test a_two_field_record_is_refused_even_with_a_known_status { + var r : [128]u8 = undefined; + const n : usize = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\n", 16); + var out : [8192]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"results\":[]", 12) == true; + assert buf_has(&out, d, "\"executionSuccessful\":false", 27) == true; +} + +test crlf_records_are_all_read { + // the carriage return is written as 13: "\r" in a literal is two bytes, not one + var r : [128]u8 = undefined; + var n : usize = put_str(&r, 128, 0, "a.t27\tUNWRITTEN\t", 16); + n = put_byte(&r, 128, n, 13); + n = put_byte(&r, 128, n, '\n'); + n = put_str(&r, 128, n, "b.t27\tUNWRITTEN\t", 16); + n = put_byte(&r, 128, n, 13); + n = put_byte(&r, 128, n, '\n'); + assert n == 36; + assert r[16] == 13; + var out : [8192]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 8192); + assert buf_has(&out, d, "\"uri\":\"a.t27\"", 13) == true; + assert buf_has(&out, d, "\"uri\":\"b.t27\"", 13) == true; + assert buf_has(&out, d, "\"executionSuccessful\":true", 26) == true; +} + +/// count UNWRITTEN records whose path is plen bytes of 'p', then one whose path is last bytes of 'q'. +fn t_unwritten_lines(dst : []u8, cap : usize, count : u32, plen : usize, last : usize) -> usize { + var x : usize = 0; + var c : u32 = 0; + while (c < count) { + var k : usize = 0; + while (k < plen) { + x = put_byte(dst, cap, x, 'p'); + k += 1; + } + x = put_str(dst, cap, x, "\tUNWRITTEN\t\n", 12); + c += 1; + } + var j : usize = 0; + while (j < last) { + x = put_byte(dst, cap, x, 'q'); + j += 1; + } + return put_str(dst, cap, x, "\tUNWRITTEN\t\n", 12); +} + +test a_finding_list_of_exactly_tsv_cap_bytes_is_kept { + var r : [40000]u8 = undefined; + const n : usize = t_unwritten_lines(&r, 40000, 339, 100, 16); + var tsv : [65536]u8 = undefined; + assert feed_tsv(&r, n, &tsv, TSV_CAP) == TSV_CAP; + var out : [262144]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 262144); + assert sarif_fits(d, 262144) == true; + assert buf_has(&out, d, "\"uri\":\"qqqqqqqqqqqqqqqq\"", 24) == true; + assert buf_has(&out, d, "\"executionSuccessful\":true", 26) == true; +} + +test a_finding_list_one_byte_over_tsv_cap_is_refused_whole { + var r : [40000]u8 = undefined; + const n : usize = t_unwritten_lines(&r, 40000, 339, 100, 17); + var tsv : [65536]u8 = undefined; + assert feed_tsv(&r, n, &tsv, TSV_CAP) == TSV_CAP + 1; + var out : [262144]u8 = undefined; + const d : usize = feed_sarif(&r, n, &out, 262144); + assert buf_has(&out, d, "\"results\":[]", 12) == true; + assert buf_has(&out, d, "\"executionSuccessful\":false", 27) == true; +}