From 242a359f21c0105fe30a3722b373b9292cce4d07 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 5 Oct 2026 11:06:52 +0000 Subject: [PATCH 1/2] Manual git R0 fixture: request git's default -z records the decoders model; surface typed decode refusals; RFM row Co-Authored-By: Claude Opus 5.5 (1M context) --- ...argv_drifted_from_its_decoder_contract.dag | 19 +++++ .../git_upstream_model_execution_test.dag | 69 ++++++++++++++++--- 2 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 dag/gunbc/recurring_failure_mode/out_of_gate_fixture_argv_drifted_from_its_decoder_contract.dag diff --git a/dag/gunbc/recurring_failure_mode/out_of_gate_fixture_argv_drifted_from_its_decoder_contract.dag b/dag/gunbc/recurring_failure_mode/out_of_gate_fixture_argv_drifted_from_its_decoder_contract.dag new file mode 100644 index 00000000000..abd4022a31c --- /dev/null +++ b/dag/gunbc/recurring_failure_mode/out_of_gate_fixture_argv_drifted_from_its_decoder_contract.dag @@ -0,0 +1,19 @@ +module gunbc.recurring_failure_mode.out_of_gate_fixture_argv_drifted_from_its_decoder_contract + +import std.types { NonEmptyStr } +import std.decl_ref { DeclarationRef, WholeDeclaration } +import gunbc.recurring_failure_mode { RecurringFailureMode } + +data out_of_gate_fixture_argv_drifted_from_its_decoder_contract: RecurringFailureMode = RecurringFailureMode { + identity: "out_of_gate_fixture_argv_drifted_from_its_decoder_contract" as NonEmptyStr, + receipts: [ + "INVALID STATE: an execution fixture hand-writes the argv of a real producer and asks it for a wire shape the decoder it feeds does not model, and the fixture sits outside the required gate, so the refusal is red with no reader. Compounded when the fixture matches the decoder's refusal as cause: _ and reports only a bare string: the red is anonymous.", + "RECEIPT: test.manual.git_upstream_model_execution git_r0_typed_execution_read_back asked git for `ls-tree -z --format=%(objectmode)%x00%(objecttype)%x00%(objectname)%x00%(path)` and `ls-files -z --format=...%x00...`; git emits a real NUL for %x00 (git-ls-tree / git-ls-files FIELD NAMES: %xx interpolates a hex byte), so each record arrives as four NUL-terminated chunks, while extdeps.git.object_store git_decode_ls_tree_z / git_decode_ls_files_stage_z model git's DEFAULT -z record ` SP SP TAB NUL`. The first chunk `100644` has no SP, so the split refused GitLsTreeZFramingRefused { GitNulQuartetIncompleteRecord { field_count: 0 } } -- red on main, unrostered, the cause discarded. Reproduced on git 2.47.3. Not a string-carrier loss: NUL survives the String + utf8_encode_bytes route. Fixed by requesting the default records (`ls-tree -z`, `ls-files -z --stage`) and rendering every refusal arm into the diagnostic; the fixture then reads back verified.", + "HARM: a real-path inhabitance claim (DESIGN section 3: the claim that the real producer emits the supplied shape) silently stops executing, so the supplied claim witnesses keep passing over a boundary no executing claim exercises. RUNG FOUND AT: mitigatable (manual probe). CEILING: structurally impossible -- the argv is derived from the decoder's declared wire format, so a fixture cannot request a shape its decoder does not read. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: the git listing argv derived from the decoder's declared wire-format row (one authority for 'which git invocation produces this record shape'), SUFFICIENT FOR every caller of git_decode_ls_tree_z and git_decode_ls_files_stage_z to obtain its argv from it; and, separately, the manual execution module enrolled in an executing lane so its red has a reader.", + ], + evidence: [ + DeclarationRef { module_path: "test.manual.git_upstream_model_execution", decl_name: "git_r0_typed_execution_read_back", field: WholeDeclaration }, + DeclarationRef { module_path: "extdeps.git.object_store", decl_name: "git_decode_ls_tree_z", field: WholeDeclaration }, + DeclarationRef { module_path: "extdeps.git.object_store", decl_name: "git_decode_ls_files_stage_z", field: WholeDeclaration }, + ], +} diff --git a/dag/test/manual/git_upstream_model_execution_test.dag b/dag/test/manual/git_upstream_model_execution_test.dag index c74ace11189..fa7ef7024ce 100644 --- a/dag/test/manual/git_upstream_model_execution_test.dag +++ b/dag/test/manual/git_upstream_model_execution_test.dag @@ -7,6 +7,12 @@ import extdeps.filesystem.filesystem_io import extdeps.gunbc import std.content_hash { Sha1Digest, Sha1DigestHex } import extdeps.git.object_store { + GitLsTreeZRefusal, GitLsTreeZFramingRefused, GitLsTreeZHeaderNonAscii, GitLsTreeZObjectIdRefused, GitLsTreeZEntryRefused, + GitLsFilesStageZRefusal, GitLsFilesStageZFramingRefused, GitLsFilesStageZHeaderNonAscii, GitLsFilesStageZModeRefused, + GitLsFilesStageZObjectIdRefused, GitLsFilesStageZStageRefused, GitLsFilesStageZPathRefused, GitPathComponentRefused, + GitNulQuartetRefusal, GitNulQuartetMissingTerminator, GitNulQuartetEmptyField, GitNulQuartetIncompleteRecord, + GitObjectIdTextRefusal, GitObjectIdTextWrongLength, GitObjectIdTextNonHexadecimal, GitObjectIdTextNonCanonicalUppercase, + GitTreeEntryNameDecodeRefusal, GitTreeEntryNameEmpty, GitTreeEntryNameForbiddenOctet, GitTreeModeObjectMismatch, GitTreeEntryNameRefused, GitObjectId, GitSha1ObjectId, GitObjectFormatSha1, @@ -99,6 +105,56 @@ fn complete_fixture_repository() -> GitRepositoryState { } } +// THE REFUSAL KEEPS ITS CAUSE. A decode refusal reaches the diagnostic as its typed arm, rendered +// totally, so a red here names what refused and where instead of collapsing to an anonymous false. +fn nul_quartet_refusal_text(cause: GitNulQuartetRefusal) -> String { + match cause { + GitNulQuartetMissingTerminator => "NulQuartetMissingTerminator" + GitNulQuartetEmptyField => "NulQuartetEmptyField" + GitNulQuartetIncompleteRecord { field_count } => concat("NulQuartetIncompleteRecord field_count=", to_string(field_count)) + } +} + +fn object_id_text_refusal_text(cause: GitObjectIdTextRefusal) -> String { + match cause { + GitObjectIdTextWrongLength { format: _, observed } => concat("ObjectIdTextWrongLength observed=", to_string(observed)) + GitObjectIdTextNonHexadecimal => "ObjectIdTextNonHexadecimal" + GitObjectIdTextNonCanonicalUppercase => "ObjectIdTextNonCanonicalUppercase" + } +} + +fn entry_name_refusal_text(cause: GitTreeEntryNameDecodeRefusal) -> String { + match cause { + GitTreeEntryNameEmpty => "EntryNameEmpty" + GitTreeEntryNameForbiddenOctet { octet } => concat("EntryNameForbiddenOctet octet=", to_string(octet)) + } +} + +fn ls_tree_z_refusal_text(cause: GitLsTreeZRefusal) -> String { + match cause { + GitLsTreeZFramingRefused { cause: c } => concat("Framing/", nul_quartet_refusal_text(cause: c)) + GitLsTreeZHeaderNonAscii { field } => concat("HeaderNonAscii field=", field) + GitLsTreeZObjectIdRefused { cause: c } => concat("ObjectId/", object_id_text_refusal_text(cause: c)) + GitLsTreeZEntryRefused { cause: c } => + match c { + GitTreeModeObjectMismatch { mode, object_type, name: _ } => concat("Entry/ModeObjectMismatch mode=", concat(mode, concat(" type=", object_type))) + GitTreeEntryNameRefused { name: _, cause: n } => concat("Entry/NameRefused/", entry_name_refusal_text(cause: n)) + } + } +} + +fn ls_files_stage_z_refusal_text(cause: GitLsFilesStageZRefusal) -> String { + match cause { + GitLsFilesStageZFramingRefused { cause: c } => concat("Framing/", nul_quartet_refusal_text(cause: c)) + GitLsFilesStageZHeaderNonAscii { field } => concat("HeaderNonAscii field=", field) + GitLsFilesStageZModeRefused { mode } => concat("ModeRefused mode=", mode) + GitLsFilesStageZObjectIdRefused { cause: c } => concat("ObjectId/", object_id_text_refusal_text(cause: c)) + GitLsFilesStageZStageRefused { stage } => concat("StageRefused stage=", stage) + GitLsFilesStageZPathRefused { cause: GitPathComponentRefused { component_index, cause: n } } => + concat("PathRefused component=", concat(to_string(component_index), concat(" ", entry_name_refusal_text(cause: n)))) + } +} + fn git_r0_typed_execution_read_back() -> GitR0LiveFixtureOutcome { let fixture = shell.Mktemp.Dir() if !fixture.success { @@ -398,11 +454,8 @@ fn git_r0_typed_execution_read_back() -> GitR0LiveFixtureOutcome { workdir: fixture.path, bin_path: "git", args: [ - "-c", - "core.quotePath=false", "ls-tree", "-z", - "--format=%(objectmode)%x00%(objecttype)%x00%(objectname)%x00%(path)", trim(s: root_tree.stdout), ], expect: ExpectSuccess, @@ -435,7 +488,7 @@ fn git_r0_typed_execution_read_back() -> GitR0LiveFixtureOutcome { args: [ "ls-files", "-z", - "--format=%(objectmode)%x00%(objectname)%x00%(stage)%x00%(path)", + "--stage", ], expect: ExpectSuccess, ) @@ -550,18 +603,18 @@ fn git_r0_typed_execution_read_back() -> GitR0LiveFixtureOutcome { payload: utf8_encode_bytes(s: tree_wire.stdout), format: GitObjectFormatSha1, ) { - GitLsTreeZRefused { cause: _ } => + GitLsTreeZRefused { cause } => GitR0LiveFixtureExecutionRefused { - diagnostic: "git-ls-tree-z-decode-refused", + diagnostic: concat("git-ls-tree-z-decode-refused: ", ls_tree_z_refusal_text(cause: cause)), } GitLsTreeZDecoded { entries: observed_tree_entries } => match git_decode_ls_files_stage_z( payload: utf8_encode_bytes(s: index.stdout), format: GitObjectFormatSha1, ) { - GitLsFilesStageZRefused { cause: _ } => + GitLsFilesStageZRefused { cause } => GitR0LiveFixtureExecutionRefused { - diagnostic: "git-ls-files-stage-z-decode-refused", + diagnostic: concat("git-ls-files-stage-z-decode-refused: ", ls_files_stage_z_refusal_text(cause: cause)), } GitLsFilesStageZDecoded { entries: observed_index_entries } => match git_model_update_ref_exact( From cc17e0756f05e169690e0397381cf17eec6c0320 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 5 Oct 2026 16:21:40 +0000 Subject: [PATCH 2/2] RFM non_utf8_path: trigger names the octet carrier at every host crossing (filesystem path AND process argv/stdout) Co-Authored-By: Claude Opus 5.5 (1M context) --- ..._utf8_path_fixture_spelled_through_a_string_path_carrier.dag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dag/gunbc/recurring_failure_mode/non_utf8_path_fixture_spelled_through_a_string_path_carrier.dag b/dag/gunbc/recurring_failure_mode/non_utf8_path_fixture_spelled_through_a_string_path_carrier.dag index c5168c2a300..364eb8b4712 100644 --- a/dag/gunbc/recurring_failure_mode/non_utf8_path_fixture_spelled_through_a_string_path_carrier.dag +++ b/dag/gunbc/recurring_failure_mode/non_utf8_path_fixture_spelled_through_a_string_path_carrier.dag @@ -9,7 +9,7 @@ data non_utf8_path_fixture_spelled_through_a_string_path_carrier: RecurringFailu receipts: [ "INVALID STATE: a fixture claims to exercise a non-UTF-8 filesystem path but builds the name as host text (a String) and hands it to a String-typed path carrier, so the octets that reach the disk are the UTF-8 encoding of the text -- valid UTF-8 by construction. The claimed property is falsified by the fixture's own construction, and the test stays green. Git pathnames are uninterpreted NUL-free octet strings upstream (git Documentation/gitformat-index 'Entry path name ... NUL-terminated'; core.quotePath: no encoding is assumed), so a non-UTF-8 path is a real input the model must preserve.", "RECEIPT: test.manual.git_upstream_model_execution git_r0_typed_execution_read_back spelled its fixture as concat(from_code_point(255), \".dag\") (a 'raw' name) and wrote it through extdeps.filesystem Filesystem.Write(path: String): on disk the name was C3 BF 2E 64 61 67. The XL-2 octet-as-char migration renamed it honestly (non_ascii_name, char_text(c: 255)). Non-UTF-8 octets ARE held at the decode interface by test.claim.git_upstream_model_witness witness_git_ls_tree_z_preserves_non_utf8_path_octets, which supplies 0xFF through std.bytes octets_bytes.", - "HARM: no executing path proves a real non-UTF-8 path survives the filesystem -> git -> read-back round trip; under-asserted coverage hidden behind a name that said otherwise (DESIGN section 4d). RUNG FOUND AT: mitigatable (review). CEILING: structurally impossible -- a path whose octets may be non-UTF-8 is carried as octets, so a text spelling cannot stand in for it. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: a filesystem octet-path carrier (extdeps.filesystem write/read/list over a path held as octets, never as String), SUFFICIENT FOR the manual execution fixture to create, git-add and read back a name containing octet 0xFF and assert the octets git reports.", + "HARM: no executing path proves a real non-UTF-8 path survives the filesystem -> git -> read-back round trip; under-asserted coverage hidden behind a name that said otherwise (DESIGN section 4d). RUNG FOUND AT: mitigatable (review). CEILING: structurally impossible -- a path whose octets may be non-UTF-8 is carried as octets, so a text spelling cannot stand in for it. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: an octet-path carrier at EVERY host crossing the round trip makes -- extdeps.filesystem write/read/list over a path held as octets, AND process argv and stdout held as octets (the gunbc.WitnessBin / git invocation that passes the name to `git add` and returns `ls-tree -z` / `ls-files -z` output), never as String -- SUFFICIENT FOR the manual execution fixture to create, git-add and read back a name containing octet 0xFF and assert the octets git reports. A filesystem-only carrier does not satisfy it: the name would still cross into git as String argv and back as String stdout.", ], evidence: [ DeclarationRef { module_path: "test.manual.git_upstream_model_execution", decl_name: "git_r0_typed_execution_read_back", field: WholeDeclaration },