Artifact 36dd76e86a86be036ed5350dcfb439d8791665360bed0a051fbcaf03e00c52c7:
- File
src/container_test.zig
— part of check-in
[76a2905055]
at
2026-08-06 16:37:19
on branch sub-manifest
— citations: 126 repairs, most of them impossible to propose before
Every earlier pass asked only for a line re-key WITHIN the cited section. A citation whose claim lived in a different section could therefore only come back "unresolved" -- even when the agent had already found the right answer and written it into its reason field. Four rounds of that read as "these need a human", when what it actually showed was that the prompt never permitted the fix.
This pass let each repair choose its own kind. Of 126 confirmed: 63 changed the SECTION, 41 re-keyed a range, and 22 rewrote a claim the drafts no longer make. 104 of those were structurally unproposable before. Unresolved fell from 67 to 5.
The claim rewrites are the ones worth reading. reply_body_cap was documented as an RFC-mandated 512 MiB ceiling; section 4 L830-833 states the opposite, that Fossil imposes no such entity limit, so it is now documented as a zit-local cap -- the same repair the 65535-byte line bound got earlier. A verbatim quotation attributed to the draft, "The card MUST consist of exactly two whitespace-separated tokens", does not appear in it; section 10.2 L2118 says "Exactly two visible tokens are required."
42 review verdicts were refused and are not applied. Two refute agents died mid-run; their proposals were left unapplied rather than taken on trust, and one refute agent lost to a stalled stream cost 14 repairs that the completed run later recovered.
Broken 172 to 42, 96 percent of citations resolving, 0 unresolvable sections. test 3500/3500, fmt. Issue #18. (user: dmestas, size: 6936) [annotate] [blame] [check-ins using] [more...]
//! Public-surface unit tests for the §4.1 zlib container codec //! (`container.zig`). The oracle is draft-fossil-sync-protocol-00 §4.1; every //! expected value is transcribed from the spec text and its RFC1950 references, //! never captured from a running Fossil. const std = @import("std"); const container = @import("container.zig"); /// A generous decode capacity for the round-trip tests; the codec's `max_output` /// bound is exercised directly by the "over max_output" test below. Sync passes /// its `reply_body_cap` here in production; the codec itself is cap-agnostic. const cap: usize = 1 << 24; test "container §4.1 r18: the container is BE32 length then a zlib stream (worked example)" { const encoded = try container.encode(std.testing.allocator, "abc", .default); defer std.testing.allocator.free(encoded); // BE32 uncompressed length (r18). try std.testing.expectEqualSlices(u8, &[_]u8{ 0, 0, 0, 3 }, encoded[0..4]); // RFC1950 §2.2 MUST: CM (low nibble of CMF) is 8 (deflate). try std.testing.expectEqual(@as(u8, 8), encoded[4] & 0x0f); // RFC1950 §2.2 MUST: (CMF*256 + FLG) % 31 == 0 (FCHECK). const cmf_flg = @as(u16, encoded[4]) * 256 + @as(u16, encoded[5]); try std.testing.expectEqual(@as(u16, 0), cmf_flg % 31); // FDICT must be 0 — no preset dictionary. try std.testing.expectEqual(@as(u8, 0), encoded[5] & 0x20); // RFC1950 §9 Adler-32 of "abc": s1=1+97+98+99=295=0x0127, // s2=0+98+196+295=589=0x024D, stored MSB-first as the trailer. try std.testing.expectEqualSlices(u8, &[_]u8{ 0x02, 0x4D, 0x01, 0x27 }, encoded[encoded.len - 4 ..]); } test "container §4.1 r19: the ordinary single-input path uses the zlib default level" { const encoded = try container.encode(std.testing.allocator, "hello fossil sync", .default); defer std.testing.allocator.free(encoded); const decoded = try container.decode(std.testing.allocator, encoded, cap); defer std.testing.allocator.free(decoded); try std.testing.expectEqualStrings("hello fossil sync", decoded); } test "container §4.1 r20: an inline-login prepend compresses the concatenation at level 9" { const login = "login foo bar baz\n"; const body = "gimme 0123456789012345678901234567890123456789\n"; const combined = login ++ body; const encoded = try container.encode(std.testing.allocator, combined, .best); defer std.testing.allocator.free(encoded); try std.testing.expectEqual(@as(u32, combined.len), std.mem.readInt(u32, encoded[0..4], .big)); const decoded = try container.decode(std.testing.allocator, encoded, cap); defer std.testing.allocator.free(decoded); try std.testing.expectEqualStrings(combined, decoded); } test "container §4.1 r21: decoding does not depend on the compression level" { const input = "the quick brown fox jumps over the lazy dog"; const enc_default = try container.encode(std.testing.allocator, input, .default); defer std.testing.allocator.free(enc_default); const enc_best = try container.encode(std.testing.allocator, input, .best); defer std.testing.allocator.free(enc_best); const dec_default = try container.decode(std.testing.allocator, enc_default, cap); defer std.testing.allocator.free(dec_default); const dec_best = try container.decode(std.testing.allocator, enc_best, cap); defer std.testing.allocator.free(dec_best); try std.testing.expectEqualStrings(input, dec_default); try std.testing.expectEqualStrings(input, dec_best); } test "container §4.1: the empty input round-trips" { const encoded = try container.encode(std.testing.allocator, "", .default); defer std.testing.allocator.free(encoded); try std.testing.expectEqualSlices(u8, &[_]u8{ 0, 0, 0, 0 }, encoded[0..4]); const decoded = try container.decode(std.testing.allocator, encoded, cap); defer std.testing.allocator.free(decoded); try std.testing.expectEqual(@as(usize, 0), decoded.len); } test "container §4.1: a truncated container header is rejected" { try std.testing.expectError(error.TruncatedHeader, container.decode(std.testing.allocator, "\x00\x00", cap)); } test "container §4.1: a decode that fits within declared capacity is accepted" { // §4.1 L905-910: the length field is an output-capacity // value, not an exact length — a decode that succeeds within capacity is // accepted. Declared 99, decoded 11 <= 99, so the shorter stream is // accepted as-is and the actual bytes are returned. const encoded = try container.encode(std.testing.allocator, "mismatch me", .default); defer std.testing.allocator.free(encoded); var lied: [64]u8 = undefined; @memcpy(lied[0..encoded.len], encoded); std.mem.writeInt(u32, lied[0..4], 99, .big); // declares 99 (capacity), stream carries 11 const decoded = try container.decode(std.testing.allocator, lied[0..encoded.len], cap); defer std.testing.allocator.free(decoded); try std.testing.expectEqualStrings("mismatch me", decoded); } test "container §4.1: output exceeding declared capacity is rejected" { // §4.1 L901-910: reject when the decoder cannot fit its output within the // declared capacity — declared 5, actual 11 > 5. const encoded = try container.encode(std.testing.allocator, "mismatch me", .default); defer std.testing.allocator.free(encoded); var lied: [64]u8 = undefined; @memcpy(lied[0..encoded.len], encoded); std.mem.writeInt(u32, lied[0..4], 5, .big); // declares capacity 5, stream carries 11 try std.testing.expectError(error.OutputTooLarge, container.decode(std.testing.allocator, lied[0..encoded.len], cap)); } test "container §4.1: a declared length over max_output is rejected" { const encoded = try container.encode(std.testing.allocator, "capped", .default); defer std.testing.allocator.free(encoded); try std.testing.expectError(error.OutputTooLarge, container.decode(std.testing.allocator, encoded, 2)); } test "container §4.1: garbage after the length prefix is rejected" { const garbage = [_]u8{ 0, 0, 0, 5, 0xff, 0xff, 0xff, 0xff, 0xff }; try std.testing.expectError(error.InvalidStream, container.decode(std.testing.allocator, &garbage, cap)); } fn encodeNoLeak(gpa: std.mem.Allocator) !void { const out = try container.encode(gpa, "allocation failure probe", .default); gpa.free(out); } test "container §4.1: encode survives allocation failure" { try std.testing.checkAllAllocationFailures(std.testing.allocator, encodeNoLeak, .{}); } fn decodeNoLeak(gpa: std.mem.Allocator) !void { const encoded = try container.encode(gpa, "allocation failure probe", .default); defer gpa.free(encoded); const out = try container.decode(gpa, encoded, cap); gpa.free(out); } test "container §4.1: decode survives allocation failure" { try std.testing.checkAllAllocationFailures(std.testing.allocator, decodeNoLeak, .{}); }