Document identity-bound commit file comparison

Add a tested, bounded commit.files normalization recipe for rework preflight while preserving existing admission and retry guards.
This commit is contained in:
2026-10-14 05:30:54 +00:00
parent 8cd24fed2a
commit 7067f1325b
2 changed files with 225 additions and 0 deletions
@@ -271,6 +271,62 @@ pytest를 이미 사용하는 프로젝트의 evidence command에만 적용한
완료 조건: final local HEAD, clean state, finding별 해결 evidence와 단일 검증 기록이 일치하며, 필요한 Contract Preservation Inventory는 `missing=0`, `ambiguous=0`이다.
#### commit.files 순서 비교 계약
`identity-bound-unordered-commit-file-collection`: 위 drift 확인과 아래 전달 직전 preflight에서 main-owned adapter가 PR commit collection을 비교할 때 적용한다. 보존된 native response에서 같은 commit SHA와 동일한 전체 file record가 `commit.files` 배열 순서만 다르게 반환된 사례가 있다. 이는 관찰된 응답의 근거이며 모든 provider/version의 배열 의미를 보증하지 않는다. 사용 전 exact endpoint/provider scope와 현재 readback의 의미를 확인한다.
- **별도 선행 gate:** authenticated identity, exact repository/PR/head, complete collection·pagination, truncation 부재와 필수 commit/file metadata를 기존 provider scope admission으로 먼저 검증한다. 아래 normalization **does not prove** collection completeness, authority 또는 metadata completeness이며 PASS receipt나 새 runtime gate가 아니다. 누락된 목록을 `[]`로 채우거나 count·pagination 불일치를 정렬로 해소하지 않는다.
- 원본 baseline/current response와 digest를 그대로 보존한다. 검증된 복사본에서 각 commit의 `files`만 exact `filename` 기준으로 정렬하며 전체 file record를 비교한다. filename/status 외의 추가 metadata도 삭제하거나 무시하지 않는다. commit SHA·message·parents·그 밖의 metadata와 바깥 commit 배열의 순서는 기존 exact 비교를 유지한다.
- 중복 commit SHA·filename과 malformed shape를 거부한다. `files=[]`는 앞선 admission이 확인한 실제 빈 목록일 때만 허용한다. filename·status는 비어 있지 않은 문자열 그대로 사용하며 strip, case-fold, path normalization 또는 identifier repair를 하지 않는다. 파일 경로를 읽거나 실행하는 예제가 아니다.
- 아래는 trusted adapter의 제한된 비교 예제다. Coordinator, publication wrapper 또는 모든 collection에 일괄 정렬을 추가하지 않는다. 정규화한 두 collection의 equality는 기존 보호 필드 검사 중 하나일 뿐이고 write authority를 부여하지 않는다. 실패한 preflight의 consumed authority·receipt를 보존하며, 이 규칙 때문에 자동 재시도하거나 새 coordinator로 같은 operation을 재실행하지 않는다. 별도 승인된 재개에도 fresh preflight가 필요하다.
<!-- commit-files-comparison-example:start -->
```python
import copy
import re
def normalize_commit_files(rows):
if type(rows) is not list:
raise ValueError("commit collection must be a list")
normalized = copy.deepcopy(rows)
commit_ids = set()
for commit in normalized:
if type(commit) is not dict:
raise ValueError("commit record must be an object")
sha = commit.get("sha")
if type(sha) is not str or re.fullmatch(r"[0-9a-f]{40}", sha) is None:
raise ValueError("full lowercase commit SHA required")
if sha in commit_ids:
raise ValueError("duplicate commit SHA")
commit_ids.add(sha)
files = commit.get("files")
if type(files) is not list:
raise ValueError("complete file list required")
filenames = set()
for file in files:
if type(file) is not dict:
raise ValueError("file record must be an object")
filename = file.get("filename")
status = file.get("status")
if type(filename) is not str or not filename:
raise ValueError("nonempty literal filename required")
if type(status) is not str or not status:
raise ValueError("nonempty file status required")
if filename in filenames:
raise ValueError("duplicate filename")
filenames.add(filename)
commit["files"] = sorted(files, key=lambda file: file["filename"])
return normalized
# Only after independent provider/collection admission:
# normalize_commit_files(current_commits) == normalize_commit_files(baseline_commits)
```
<!-- commit-files-comparison-example:end -->
`harness/tests/impl/test_impl_architecture_docs.py`는 이 정본 block 자체를 추출·실행하여 순서 차이만 허용되는지, 실제 metadata/identity 변화·중복·malformed input을 거부하거나 비동등으로 판정하는지, 원본과 nested value가 불변인지 검증한다. 테스트에 comparator를 복제하지 않는다. 이 실행 회귀는 비교 예제의 local contract 검증이며 live provider capability, collection admission 또는 실제 전달 성공을 대신하지 않는다.
### 7. 기존 PR branch 전달
각 mutation은 [operation API contract](../../../OPERATIONS.md)의 `execute_rework_operation`으로 처리한다. Exact 기존 comment 재사용은 `verify_rework_reuse`의 fresh read-only 경로다. 아래 기존 보호 계약과 각 실제 readback verifier는 그대로 적용하며 coordinator 결과만으로 handoff를 판정하지 않는다.