Skip to content

Commit 91ceb0f

Browse files
committed
fix(review-evidence): pin attribute case policy
1 parent 143c8de commit 91ceb0f

10 files changed

Lines changed: 335 additions & 12 deletions

File tree

‎docs/plans/review-evidence-packaging/execution-ledger.md‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,45 @@ Exact-current-source locked CI and independent repair review remain pending; the
179179
plan is not Accepted. Final structural/generator checks and artifact reconstruction
180180
are retained with the delivery after record/manifest finalization. No source push
181181
or user configuration edit is made by this task.
182+
183+
## Residual F4 case-policy repair — 2026-09-28
184+
185+
The user authorized the remaining repair under this existing plan. Admission is
186+
`verify` from Verifying: the repair stays inside P2's P1-boundary repair allowance.
187+
The source baseline is `143c8de1706ccf4b82b5c78aeed644c071ed999a`, confirmed as main;
188+
its Actions source archive and tree were verified in an isolated task checkout.
189+
No user working tree, production configuration or remote ref is a write target.
190+
191+
Exact write set: `tools/repository_git/repository_git/repository.py`, its existing
192+
`tests/test_exact_patch.py` and README; the direct builder's existing
193+
`tools/review_evidence/tests/test_repair_boundaries.py` and README; this plan's
194+
plan/issues/ledger plus `reports/attribute-case-verification.md`; and the owning
195+
generated suite-input manifest. No other production owner or public type changes.
196+
197+
The deciding regression uses committed `*.TXT -diff`, a nonmatching `data.txt` and
198+
an exact-matching `MATCH.TXT`, with the same revision pair under each local case
199+
setting. Literal text-hunk and binary-marker oracles complement equality of the
200+
actual CLI's complete packet bytes. Each invocation must preserve source, index,
201+
refs, request and repository configuration. Both tests are first run against the
202+
unmodified production method. Required supported-runtime CI and independent review
203+
remain distinct from local evidence; no broader test-hardening slice is admitted.
204+
205+
### F4 case-policy local verification
206+
207+
The two final baseline regressions failed exactly where a lowercase path became
208+
binary under `core.ignoreCase=true`; they passed after the command-local override.
209+
The complete builder/Git/metadata selections and shared Engine selection total
210+
161 passes and one permission-dependent skip (162 run), with no failures. Both
211+
source-preservation assertions and positive exact-case binary behavior passed.
212+
The real routing packet is byte-identical to the prior inspected output, including
213+
its manifest and two material gaps. A separate stdlib recipient verified all 98
214+
members, hashes/modes and 96 links without source access or extraction.
215+
216+
The production change remains one Git setting plus its docstring. No normal Git
217+
behavior, user configuration, Engine interface, packet schema or earlier safety
218+
repair changed. Final records and generated inputs receive their own freshness and
219+
structural checks. Supported locked CI, independent narrow review and acceptance
220+
owner disposition remain P2 gates; source is not marked Accepted. Detailed evidence
221+
and the initial test-draft failures are preserved in the case-policy report and
222+
delivery logs. The task-owned branch/workspace is retained for delivery, not pushed
223+
or represented as a production source commit.

‎docs/plans/review-evidence-packaging/issues.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,18 @@ F4 direct-consumer completion: `cli.py` now exposes only the new Git owner's fix
6464
arbitrary Git stderr private. The actual CLI test verifies the useful rejection,
6565
unchanged source configuration and no output creation. This narrow consumer repair
6666
and its added regression are included in the final 48-test builder pass.
67+
68+
## Residual F4-C1 — committed attribute case matching
69+
70+
The follow-up review of `143c8de1` found that `*.TXT -diff` changes the patch for
71+
`data.txt` when the same repository is configured with `core.ignoreCase=true`.
72+
The scoped repair fixes case-sensitive matching in the existing opt-in
73+
`revision_patch` command, without rewriting configuration, renaming paths, or
74+
changing ordinary capture/publication. Exact-case matching still selects binary
75+
patches. The original F1–F3 repairs are unchanged.
76+
77+
Two new real-Git/CLI tests first failed at the intended textual-hunk assertion on
78+
the unchanged production baseline; the repaired candidate rerun, package checks
79+
and packet comparison are recorded in [case-policy verification](reports/attribute-case-verification.md).
80+
F4-C1 is implemented; candidate CI and independent review/owner disposition remain
81+
required before the packaging slice is Accepted. This adds no new API or mode.

‎docs/plans/review-evidence-packaging/plan.md‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**Plan status:** `Verifying`
44

5-
**Current phase:** P1 repairs implemented and locally verified; P2 CI/review acceptance pending
5+
**Current phase:** P1 repairs including F4 case policy locally verified; P2 CI/review acceptance pending
66

77
**Next slice:** **P2 — Offline recipient example and acceptance**
88

@@ -16,9 +16,11 @@
1616

1717
**Admission:** priority **4** in the user's selected **2 → 4 → 3** sequence.
1818
Routing-fact ergonomics is Accepted; the earlier six-slice refactor is closed.
19-
This new plan does not reopen either acceptance. The user has authorized repair of the four demonstrated review findings at this
20-
exact plan path. The admitted `start` is implemented; `verify` continues its P2 qualification; it does not
21-
reopen prior acceptance or admit priority 3. This candidate is based on `6be1d7a0`.
19+
This new plan does not reopen either acceptance. The user authorized the original four repairs and the follow-up F4 case-policy
20+
correction at this exact plan path. The admitted `start` is implemented; `verify`
21+
continues P2 qualification without reopening prior acceptance or admitting priority 3.
22+
The case-policy repair is based on integrated source `143c8de1`; earlier repair
23+
evidence remains in its original records. See [case-policy verification](reports/attribute-case-verification.md).
2224

2325
## Implementation scope amendment
2426

@@ -158,7 +160,10 @@ commit-to-commit arguments and stable raw/NUL path output. Do not run `git archi
158160
as the byte oracle because export attributes may omit or rewrite blobs. Never
159161
fall back to checkout bytes, shallow diffs, text-only excerpts or permission guesses.
160162
Pin patch attribute lookup to the candidate commit so dirty worktree attributes
161-
cannot change the representation of the selected committed patch. Disable global,
163+
cannot change the representation of the selected committed patch. Match those
164+
patterns case-sensitively over exact committed paths with a command-local
165+
`core.ignoreCase=false`; preserve the repository's filesystem configuration and
166+
all ordinary Git operations. Disable global,
162167
system and configured attributes; reject info attributes and local custom diff
163168
semantics that would override committed input. Fix ordinary diff formatting at the
164169
existing Git owner and observe stable configuration before/after the command.
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Attribute case-policy repair verification
2+
3+
**Status: locally verified; exact-candidate locked CI and independent review/owner
4+
acceptance remain pending.** This is residual F4-C1 within the existing packaging
5+
plan, not a new implementation sequence.
6+
7+
## Baseline, owner and change
8+
9+
The connected repository reports main at
10+
`143c8de1706ccf4b82b5c78aeed644c071ed999a`, tree
11+
`bb2876f0251243b1d7d38b7ee1026c080394a08e`. Its mounted Actions source artifact
12+
`11003765805` was verified against archive SHA-256
13+
`509e9b6b38904ae388c121326acf4e2040d4e88b91fe50730f55518584f5b6ba` and checked out
14+
on a task-owned repair branch. The user authorized this remaining repair from the
15+
follow-up source review. No later or unrelated user working-tree content was used.
16+
17+
Production change is confined to `GitRepository.revision_patch`: add the command-
18+
local setting `core.ignoreCase=false` and document its meaning. The existing Git
19+
owner now matches candidate-committed attribute patterns case-sensitively over
20+
exact Git paths. Neither the repository's filesystem-compatibility setting nor
21+
ordinary reads, worktree operations, capture or publication defaults are changed.
22+
23+
The complete patch still supports binary data, exact modes and committed attribute
24+
choices. Case-sensitive matching does not mean disabling attributes: `*.TXT -diff`
25+
continues to select a binary patch for `MATCH.TXT`, but not for `data.txt`.
26+
Existing local-only execution, custom-driver rejection, info-attribute admission,
27+
output bounds and command lifetime remain intact. The prior directory-handle,
28+
common-Git-root and portable-component repairs were not modified.
29+
30+
No Engine interface, packet format, public signature, schema, metadata key, CLI
31+
flag, migration or additional abstraction is introduced. Engine interface 45 and
32+
packet format 1 remain unchanged. There is no source/evidence/provider network
33+
operation added to the builder.
34+
35+
## Deciding evidence
36+
37+
Two regression methods were added at the existing owners:
38+
39+
- `test_exact_patch.ExactPatchTests.test_attribute_case_policy_is_fixed_without_reconfiguring_repository`
40+
invokes the original public Git adapter using real commits under repository
41+
settings false and true. It compares the lowercase path's hunk to a literal
42+
expectation built from independently observed blob IDs and exact file bytes,
43+
and requires the exact-case file's binary patch marker. It checks unchanged
44+
source, Git index, refs, HEAD and configuration after each operation.
45+
- `test_repair_boundaries.ReviewRepairTests.test_cli_packet_case_policy_preserves_material_and_repository_configuration`
46+
invokes the actual CLI in replacement processes with the same request and
47+
selected commits under both settings. It checks successful outcomes, exact
48+
baseline/candidate source members, literal text and positive binary-policy
49+
oracles, identical complete ZIP and manifest bytes, no leftover staging files,
50+
and unchanged request/source/index/refs/configuration.
51+
52+
Both final regression definitions first failed on the unmodified production code
53+
at the intended text-versus-binary assertion (two failures, no errors), then passed
54+
with the one-setting correction. An earlier test draft also emitted secondary list-
55+
index errors after a failed subtest; the draft was corrected before the final
56+
baseline rerun. Both original logs remain in the delivery evidence and are not
57+
counted as successful verification. The existing command-environment test also
58+
asserts that the case policy is passed only on the owned patch invocation.
59+
60+
An initial task-routing probe supplied an undeclared `console` profile and was
61+
correctly rejected; it was corrected to the registered `library` profile before
62+
implementation. The executed Router then selected 21 standards with no unanswered
63+
facts. This was task setup, not a production failure or acceptance test.
64+
65+
## Executed checks
66+
67+
| Selection | Observed result |
68+
| --- | --- |
69+
| Complete review-evidence package | 49 passed |
70+
| Complete Repository Git package | 40 passed; one permission-dependent skip (41 run) |
71+
| Complete metadata package | 43 passed |
72+
| Engine capture-handoff, replacement-stdio and generated-contract selections | 29 passed |
73+
| Total selected executions | 161 passed, one skipped, no failures (162 run) |
74+
| New regression methods | Two; included in the totals above |
75+
| Complete structural checkpoint | 73 suites / 121 checks passed |
76+
| Generated projection freshness | Passed |
77+
| Separate offline recipient comparison | All members byte-identical to the previously inspected example |
78+
79+
The full Engine and other supporting-package suites were not rerun. The production
80+
change is an opt-in patch setting with one builder consumer; the complete affected
81+
Git/builder packages and existing shared capture/contract cases are the selected
82+
regression scope. New tests are not added to totals a second time when rerun.
83+
After final documentation and manifest regeneration, the new regressions, command-
84+
environment check, freshness and structural checks are repeated; exact final
85+
outcomes are preserved in `DELIVERY/evidence/final-checks.json`.
86+
87+
## Actual review packet
88+
89+
The committed routing example was rebuilt through the CLI. A separate standard-
90+
library-only recipient process inspected the ZIP without importing the builder,
91+
reading the source checkout or extracting files. It checked all inventory member
92+
names, regular inert modes, lengths, hashes and index targets, and compared every
93+
member byte with the prior inspected packet.
94+
95+
The result has 98 members, 96 resolving index links, 49 primary changed paths,
96+
54 selected paths, 5,704,505 payload bytes and the complete 1,083,975-byte primary
97+
patch. Its manifest is unchanged:
98+
`sha256:30c2834feb20fa7c3d4efa16b12dae823a4341de4b41aff40fe6a672fef11ff3`.
99+
The CLI returns `built-with-gaps` and exit 1 as intended: raw CI log missing, CI URL
100+
referenced. Those gaps were not filled with fabricated results. This compares a
101+
real packet; it does not reopen routing-fact acceptance or assert CI execution.
102+
103+
The unchanged packet manifest's implementation digest remains explicitly a digest
104+
of `packet.py`, not of its Git dependency or the whole builder. No stronger origin
105+
or implementation-authentication claim is made by this comparison.
106+
107+
## Scope, limitations and integration
108+
109+
Only `repository.py` changes production code. The two direct test files, two
110+
READMEs, plan/ledger/issues, this report and generated suite-input manifest form
111+
the coordinated delivery. All Engine contracts/runtime, packet schema/source,
112+
existing normative guidance, dependency locks and CI configuration remain unchanged.
113+
Fresh-baseline reconstruction checks the entire resulting tracked tree, individual
114+
file hashes and modes; ZIP integrity and reconstruction results are in DELIVERY.
115+
116+
Handoff execution used Linux x86-64, CPython 3.13.5, Git 2.47.3, jsonschema 4.26.0
117+
and rpds-py 2026.5.1. No supported Python 3.12 hash-locked environment was installed there.
118+
The skipped case requires unprivileged POSIX permissions; no case-insensitive
119+
filesystem or additional operating system was exercised. The fixed policy concerns
120+
committed-path interpretation, not reconfiguration of filesystem compatibility.
121+
The tests establish these configured cases, not harmlessness of every Git setting.
122+
The existing requirement that configuration remain stable during observation and
123+
the documented local-directory threat limits are unchanged.
124+
125+
Apply the scoped patch after its read-only baseline check, preserving unrelated
126+
work. No registration or repository Git configuration changes are needed. Fresh
127+
builder invocations load the corrected code. Keep historical packets and reports
128+
unchanged. The plan remains Verifying: obtain supported locked-runtime CI for the
129+
actual integrated candidate, narrow independent repair review and acceptance-owner
130+
disposition. No remote push, production commit, standards publication, host update,
131+
provider request or independent external review was performed during handoff preparation.
132+
133+
After integration on the named base, the repository's Python 3.12.3 environment
134+
passed 49 Review Evidence tests, 41 Repository Git tests, 43 Standards Metadata
135+
tests and the 29 selected Engine tests. Ruff lint on changed Python, the complete
136+
structural check and authoring-purpose repository verification (121 checks across
137+
73 suites) also passed. A separate ZIP inspection found 98 members, 96 resolving
138+
links, the complete 1,083,975-byte patch, and the same two declared evidence gaps;
139+
the manifest digest remained `sha256:30c2834feb20fa7c3d4efa16b12dae823a4341de4b41aff40fe6a672fef11ff3`.
140+
These local results do not replace hosted CI or acceptance-owner disposition.
141+
142+
## Corroborating dependency contract
143+
144+
Git documents command-local configuration precedence and identifies `core.ignoreCase`
145+
as a filesystem-compatibility setting. The operation-local override intentionally
146+
does not edit that stored value. Official reference:
147+
https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreignoreCase

‎evaluation/standards-effectiveness/generated/suite-inputs.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6578,7 +6578,7 @@
65786578
]
65796579
},
65806580
{
6581-
"digest": "sha256:4ef1153a4609ba5c1f50d9b2039291b76fafe8b16ca9147ced03eb550a0aac86",
6581+
"digest": "sha256:95f201111583e2c57988f0cf705b2fdf8ed1e4508b674329adde674494aa9c10",
65826582
"path": "tools/repository_git/repository_git/repository.py",
65836583
"state": "present",
65846584
"uses": [
@@ -13838,7 +13838,7 @@
1383813838
"path": "evaluation/standards-effectiveness/suite-registry.toml"
1383913839
},
1384013840
"repository_index": {
13841-
"digest": "sha256:0b1e103a4ea4291c6d86d0e0c7cde7a5feace5de5032dc255016455f371176b7",
13841+
"digest": "sha256:2d9c15d4bb3d841ab46ab68c45edaf0cac663725aa24231f464ecb1c7393756e",
1384213842
"uses": [
1384313843
{
1384413844
"check": "python-package-contract",

‎tools/repository_git/README.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ The patch policy fixes algorithm (Myers with indent heuristic), three context
119119
lines, zero inter-hunk context, `a/`/`b/` prefixes, no line prefix, default line
120120
indicators, byte-path quoting, raw file ordering, short submodule format and the
121121
512 MiB Git binary-detection threshold (above the object safety bound). It preserves
122-
committed attribute choices; it does not replace binary patches with text excerpts.
122+
committed attribute choices with case-sensitive matching over exact Git paths.
123+
The owned patch command sets `core.ignoreCase=false` only for that invocation;
124+
repository filesystem settings remain untouched. Thus `*.TXT -diff` does not match
125+
`data.txt` but still selects a binary patch for `MATCH.TXT`, regardless of the
126+
repository's `core.ignoreCase` value. It does not replace binary patches with text
127+
excerpts or change ordinary reads, worktree operations or publication behavior.
123128
Different Git implementations may produce different binary encodings; byte identity
124129
is qualified within the recorded implementation/environment, not across versions.

‎tools/repository_git/repository_git/repository.py‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,10 @@ def revision_patch(
386386
info/attributes higher precedence than GIT_ATTR_SOURCE, so that override
387387
is explicitly unsupported rather than silently trusted or edited.
388388
Custom local diff-driver semantics are likewise rejected; external and
389-
textconv commands are disabled and never invoked. Admission is repeated
390-
after the command; configuration must remain stable for the observation.
389+
textconv commands are disabled and never invoked. Attribute matching is
390+
case-sensitive over committed paths, independent of filesystem case
391+
settings. Admission is repeated after the command; configuration must
392+
remain stable for the observation.
391393
"""
392394
if type(max_output_bytes) is not int or max_output_bytes < 1:
393395
raise invalid("REPOSITORY_GIT.INVALID_BOUND", "patch bound must be positive")
@@ -420,7 +422,7 @@ def admit_configuration() -> None:
420422
"GIT_ATTR_NOSYSTEM": "1", "GIT_ATTR_SOURCE": candidate.oid})
421423
settings = (
422424
"core.attributesFile=" + os.devnull, "core.quotePath=true",
423-
"core.bigFileThreshold=512m", "core.fsmonitor=false",
425+
"core.bigFileThreshold=512m", "core.fsmonitor=false", "core.ignoreCase=false",
424426
"diff.suppressBlankEmpty=false",
425427
)
426428
configuration = tuple(part for setting in settings for part in ("-c", setting))

0 commit comments

Comments
 (0)