Skip to content

PR #8599 — qualify Windows file identity and bind backup evidence - #8599

Merged
huangruiteng merged 5 commits into
loopx-project:mainfrom
xiaobaifly7:fix/decision-context-windows-ctime
Nov 12, 2026
Merged

huangruiteng merged 5 commits into
loopx-project:mainfrom
xiaobaifly7:fix/decision-context-windows-ctime

Conversation

@xiaobaifly7

@xiaobaifly7 xiaobaifly7 commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Scope and approach

Address the latest CHANGES_REQUESTED review on 8c46abc3ea199a44d7191838c0d09f77754eee7e.

  • The material reader omits ctime only when all three observations have nonzero st_dev AND st_ino.
  • Cold-backup _same_file applies the same rule to both observations. Incomplete identity keeps ctime checked.
  • Complete-identity stable Windows ctime skew still succeeds; POSIX keeps ctime checks. Existing size, mtime, identity and read bounds remain.
  • The private compressed archive copy still supplies both the verified archive digest and scanned members. The previous real prepare-import swap/restore regression still rejects mismatched source evidence.
  • Required native first-link validation exposed existing host-dependent tar-path normalization. posixpath.normpath now preserves tar's POSIX names on Windows; a valid first link succeeds, while unsafe descendants and cycles remain rejected.

Existing shared readers retain their callers and ownership. No new helper module, schema, dependency, configuration, install or broad refactor was needed. The adjacent refactoring pass found no further necessary change.

Branch and isolation

The first Git operation was git fetch origin main. Fetched target: 9ce3a46bfe525aa2167de6699fc676ce8ef60247.
git merge-tree --write-tree HEAD origin/main succeeded before changes: no rebase was needed and all four existing commits were preserved.

All writes and disposable state stayed in the specified worktree. The existing Windows .venv (CPython 3.12.13) and WSL .local/review-venv-wsl (CPython 3.12.3) were reused directly; no uv install/sync/tool operation ran. PowerShell used a non-login, no-profile shell. WSL validation used bash --noprofile --norc -c. HOME, USERPROFILE, LOOPX_HOME, temporary directories and application/cache paths were redirected inside the worktree; PYTHONUTF8=1 and LOOPX_USAGE_PING=0.

The user-specified initial GitHub read used wsl -e bash -lc to retrieve all review and inline-comment bodies. No GitHub write was made.

Proving tests: native Windows red then green

The material test retargets a real directory junction after the second descriptor observation while the original file remains open. Replacement bytes have equal size and mtime. Unknown volume identity, colliding indexes and ctime are injected only at the stat boundary; this machine did not physically yield the unknown-volume/index-collision combination.

./.venv/Scripts/python.exe -m pytest -q tests/capabilities/test_decision_context_profile.py -k 'same_metadata_replacement or ctime_skew' --basetemp=.local/p2-red --tb=short
./.venv/Scripts/python.exe -m pytest -q tests/capabilities/test_decision_context_profile.py -k 'same_metadata_replacement or ctime_skew' --basetemp=.local/p2-green --tb=short

Before: 1 failed, 6 passed, 24 deselected; only the st_dev=0 case failed to raise during scan. After: 7 passed, 24 deselected. Zero-index and complete-identity replacement controls and all four stable ctime-skew cases passed. The final suite also ran the strengthened assertion that the real junction path contains replacement bytes.

Cold-backup tests use real native gzip/tar/SQLite I/O and inject missing identity/ctime only at lstat/fstat:

& .venv/Scripts/python.exe -m pytest -q tests/control_plane/test_cold_source_backup_scope.py -k archive_identity_change_policy --basetemp=.local/p2-cold/red -o cache_dir=.local/p2-cold/cache/pytest
& .venv/Scripts/python.exe -m pytest -q tests/control_plane/test_cold_source_backup_scope.py -k archive_identity_change_policy --basetemp=.local/p2-cold/green -o cache_dir=.local/p2-cold/cache/pytest

Before: 2 failed, 28 passed, 12 deselected, accepting ctime-only changes with unknown volume or index. After: 30 passed, 12 deselected.

The requested valid first-link assertion also failed before the POSIX-path fix:

& .venv/Scripts/python.exe -m pytest -q tests/control_plane/test_cold_source_backup_scope.py::test_streaming_witness_rejects_symlink_ancestor_and_cycle --basetemp=.local/p2-cold/first-link -o cache_dir=.local/p2-cold/cache/pytest

Before: 1 failed, rejecting the valid first link as cold_import_backup_member_unsafe. After: the entire test passes in the final suite, including unsafe-descendant and cycle rejection.

Final focused validation

./.venv/Scripts/python.exe -m pytest -q tests/capabilities/test_decision_context_profile.py tests/capabilities/test_bm25_context_provider.py tests/control_plane/test_cold_source_backup_scope.py tests/capabilities/test_decision_context_capture.py::test_capture_cli_and_status_are_public_safe tests/control_plane/test_cold_source_import_cli.py::test_prepare_rejects_archive_swap_and_restore_during_member_scan -k 'not replacement_after_open' --basetemp=.local/p2-final --tb=short

81 passed, 1 skipped, 1 deselected on native Windows. Includes all 42 cold-backup scope cases, stable Windows scan/exact-read, ordinary regular-file capture through the real CLI, valid first link, unsafe links/cycles and the previous real prepare-import archive swap/restore regression. The platform skip is FIFO; the deselected old direct-open-file replacement fixture cannot replace an open file under native Windows sharing.

WSL supported material/BM25 validation, from the worktree with isolated environment variables:

.local/review-venv-wsl/bin/python -m pytest -q tests/capabilities/test_decision_context_profile.py tests/capabilities/test_bm25_context_provider.py -k "not replaced_by_fifo" --basetemp=.local/p2-supported-wsl --tb=short

38 passed, 1 deselected. The old direct-open-file replacement fixture passes here; the mount's unsupported FIFO case is deselected.

Other runs and limitations

Each pytest selection below used -q and --tb=short.

Selection Result
Native: tests/capabilities/test_decision_context_profile.py tests/capabilities/test_bm25_context_provider.py --basetemp=.local/p2-focus 37 passed, 1 failed, 1 skipped. Existing direct-open-file replacement fixture raises WinError 5.
WSL: same files, --basetemp=.local/p2-focus-wsl 38 passed, 1 failed. os.mkfifo raises Errno 95 on this Windows-backed mount.
Native: tests/capabilities/test_decision_context_capture.py tests/control_plane/test_cold_source_import_cli.py::test_prepare_rejects_archive_swap_and_restore_during_member_scan --basetemp=.local/p2-journey 17 passed, 1 failed. POSIX 0600 spool-mode assertion is unsupported on Windows; capture had succeeded. Real capture CLI and archive rejection passed.
Native cold scope before tar-path fix: tests/control_plane/test_cold_source_backup_scope.py --basetemp=.local/p2-cold/scope -o cache_dir=.local/p2-cold/cache/pytest 41 passed, 1 failed. Native backslashes prevented the intended cycle check. Fixed; all 42 pass in the final suite.

Static checks

./.venv/Scripts/python.exe -m ruff check loopx/materials.py loopx/control_plane/coordination/cold_source_backup.py tests/capabilities/test_decision_context_profile.py tests/control_plane/test_cold_source_backup_scope.py

Passed.

.local/review-venv-wsl/bin/python -m mypy --cache-dir=.local/p2-mypy-wsl

Configured kernel typecheck: passed, 17 source files, on WSL. The native configured check initially reported 14 unrelated POSIX-only attribute errors plus the material reader's fixed-tuple inference error. Both touched identity-field tuples now have tuple[str, ...] types.

An extra explicit strict check is not fully green:

./.venv/Scripts/python.exe -m mypy --follow-imports=silent --cache-dir=.local/p2-mypy-touched-final loopx/materials.py loopx/control_plane/coordination/cold_source_backup.py

4 pre-existing errors remain in cold archive scanning: TarFile.members in the stub and a digest variable reused as string/hash. The reviewed HEAD sources, checked through --shadow-file, reported 6 errors: those four plus the two fixed-length identity-tuple assignments. No new type error was introduced; unrelated archive typing remains unchanged.

git diff --check and git diff --cached --check passed. The staged gate passed:

./.venv/Scripts/python.exe scripts/check_rfc_bilingual.py --base origin/main --staged

The final committed diff also passes git show --format= --check HEAD.

Risks and unverified boundaries

A stable Windows file with incomplete identity and differing ctime may now be refused: the requested fail-closed fallback. Complete-identity skew remains accepted. The archive snapshot's existing scratch-space/copy cost is unchanged.

No full-repository suite, hosted CI, real SMB/unknown-volume hardware condition or spontaneous NTFS ctime-skew condition was qualified. Prior broad integration limitations were not re-run. Metadata and race timing were injected at OS boundaries around real native I/O.

New DCO-signed commit: 72167ad714f6da77b09f74080682153979a20e73 (four product/test files, +75/-22). Its parent is the unchanged reviewed head. Author, committer and sign-off match the requested identity; Git configuration was not changed. Final merge-tree against the fetched origin/main passed.

🤖 Generated with Claude Code

Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
@xiaobaifly7 xiaobaifly7 changed the title fix(materials): ignore Windows ctime-only skew fix(io): ignore Windows ctime-only skew in material reads and cold backup Nov 11, 2026

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max

本次评审对应提交 6ac8672c9b2667426e5adbce5b728c2df8e11d7c。

[P2] 把冷备份成员绑定到实际验过的归档。 相同大小、inode 和 mtime 的归档在校验整包 SHA-256 后可短暂换入另一组成员,扫描结束再还原原归档。在 Windows 元数据分支中,prepare-import 同时接受原归档摘要和另一版成员,返回 coordination_source_backup_verified=true。 归档读回

动机 / Motivation

从本地文件取得可追溯的 Decision Context、Goal 方向或 BM25 证据,以及准备冷迁移的操作者。两个读者会因 Windows 的 ctime 观测差异拒绝稳定文件。补丁可读回稳定文件,在其他身份字段有值且变化时仍拒绝,并保留 POSIX 检查。补丁可读回稳定文件,在其他身份字段有值且变化时仍拒绝,并保留 POSIX 检查。实际在 macOS 使用真实文件、tar 读取、SQLite 索引和公开 CLI;只在接口边界注入 Windows 元数据与竞争时序。Windows 内核、NTFS/SMB 可达性与托管 CI 未独立复跑。相同大小、inode 和 mtime 的归档在校验整包 SHA-256 后可短暂换入另一组成员,扫描结束再还原原归档。在 Windows 元数据分支中,prepare-import 同时接受原归档摘要和另一版成员,返回 coordination_source_backup_verified=true。Windows 文件索引不可用时,两个 st_ino=0 不能证明是同一文件。用相同大小、mtime 的不同文件替换路径后,读者在新提交返回旧描述符的内容和摘要,却将它归到已变更的路径。基线在 ctime 不同的对照中拒绝。

改动思路 / Approach

保留现有两个文件读者和冷迁移 owner。两者需要分别验证物理路径身份和归档字节。继续接收稳定文件的时间偏差,并验证被替换的材料或归档仍不能生成错误凭证。 沿两个已有读者保留 Windows 稳定文件的修复。材料需要关联打开的描述符和当前路径。冷备份需要让归档摘要与成员校验读取同一批字节。

具体改动 / Changes

关键代码讲解

按本地材料合同及备份来源约定核对。STABLE-WINDOWS-READ 通过,PATH-REPLACEMENT-IDENTITY 与 BACKUP-MEMBER-INTEGRITY 有反例。材料 对三份 stat 取相等字段。冷备份先读整包摘要,再读成员,最后用 stat 判断是否同一输入。采用同一进程内实际文件替换和真实导入入口验证两处边界,保留原有作用域与预算。冷迁移的 TypeScript owner 还会重读归档摘要,并按已扫描的成员表检查当前源。两种检查各自通过时,仍须证明使用的是同一份归档。

对主干的风险 / Risks

相同大小、inode 和 mtime 的归档在校验整包 SHA-256 后可短暂换入另一组成员,扫描结束再还原原归档。在 Windows 元数据分支中,prepare-import 同时接受原归档摘要和另一版成员,返回 coordination_source_backup_verified=true。 真实 CLI 的基线退出 1,新提交返回 prepared、backup verified,执行 authority 仍是 false。Windows 文件索引不可用时,两个 st_ino=0 不能证明是同一文件。用相同大小、mtime 的不同文件替换路径后,读者在新提交返回旧描述符的内容和摘要,却将它归到已变更的路径。基线在 ctime 不同的对照中拒绝。 Python 只对非零文件索引给出文件身份保证。 Python stat 文档

语义与 CI 对齐

58 项材料、BM25 与归档检查以及 32 项 Goal direction 检查在 macOS 通过,Ruff、DCO、diff 与双语检查通过。旧版和新版跑同一独立反例。文件内容和归档均实际改动,Windows stat 结果和发生时序在边界注入。两条反例未在真实 Windows 上独立复跑,也未执行 apply-import。

我的整体评价 / Verdict

请求保留稳定文件的修复,同时让实际扫描成员和通过校验的归档使用同一批字节,并在缺少文件身份时拒绝歧义。请用当前失败的相同路径和真实归档反例验证。 变更影响 CLI 与文件读回。 当前证据来自注入 Windows 元数据的本机真实 I/O。

English verdict: REQUEST_CHANGES. Stable ctime skew is handled, but paired real I/O under injected Windows metadata admits ambiguous material replacement and produces a false cold-backup coverage claim. Bind member hashes to the verified archive and qualify missing file identity.

def _same_file(before: os.stat_result, after: os.stat_result) -> bool:
identity_fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns")
# Windows ctime alone does not reliably identify a file change.
if os.name != "nt":

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 校验归档与成员的同一组字节。 在真实 prepare-import 中先校验归档 A,扫描时同一个文件短暂变为同大小、同 mtime 的 B,随后恢复 A。注入 Windows ctime 差异后,基线拒绝。当前已准备的结果带有 A 的归档摘要、B 的成员证据和 coordination_source_backup_verified=true,即使 A 不含当前源。请从同一份经校验的输入提取成员,并保留稳定 ctime 偏差用例。

Comment thread loopx/materials.py Outdated
identity_fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns", "st_ctime_ns")
identity_fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns")
# Windows ctime alone does not reliably identify a file change.
if os.name != "nt":

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 文件索引不可用时拒绝歧义。 实际替换为同大小、同 mtime 的另一文件,模拟 Windows 返回 st_ino=0。当前读取给出旧描述符内容和原路径,路径已经指向新字节。有效非零 inode 的相同对照仍拒绝。请保留可靠身份核对或让未知身份显式失败。 Python stat 文档

Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
@xiaobaifly7 xiaobaifly7 changed the title fix(io): ignore Windows ctime-only skew in material reads and cold backup PR #8599 — qualify Windows file identity and bind backup evidence Nov 11, 2026
@xiaobaifly7

Copy link
Copy Markdown
Contributor Author

Addressed both P2 findings in separate new DCO-signed commits:

  • Unknown material file identity — a611c850953c: Windows ctime-only tolerance now requires non-zero st_ino on all three compared stat observations; otherwise ctime remains checked. test_local_file_same_metadata_replacement_has_no_verified_read uses real same-size/same-mtime replacement with injected zero indexes and a non-zero-index control. Together with the four unchanged test_local_file_ctime_skew cases: 1 failed, 5 passed before → 6 passed after (WSL).

  • Archive/member binding — 8c46abc3ea19: the adapter streams a private compressed archive copy into its existing scratch workspace, verifies that copy's SHA-256/size, and scans its members. Stable Windows ctime tolerance and the TypeScript owner's artifact/source-coverage checks remain. test_prepare_rejects_archive_swap_and_restore_during_member_scan swaps real same-size/same-inode/same-mtime tar.gz bytes at the scan boundary and restores A afterward. The native Windows prepare-import CLI previously accepted the evidence; it now rejects B's source against A's members with cold_import_backup_source_missing_or_changed: 1 failed before → 1 passed after.

Ruff, whitespace and DCO checks pass; WSL TypeScript cold-import tests pass 16/16. WSL material/BM25/backup tests have 59 passed, with one existing FIFO fixture unsupported by the mount. Broader native validation is not green (SQLite long paths, file/link limitations and CRLF assertions); the WSL integration follow-up also encountered registration/temp-file cleanup failures and was stopped.

The copy adds approximately one compressed archive of scratch disk usage, covered by existing accounting/capacity/cleanup handling. Native zero-index replacement, spontaneous NTFS ctime skew and SMB remain unqualified; metadata and timing were injected around real I/O.

origin/main was fetched and the final branch merges cleanly; no rebase was needed. Nothing was pushed or commented on GitHub.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max

本次评审对应提交 8c46abc3ea199a44d7191838c0d09f77754eee7e。

[P2] 卷身份缺失时保留替换检查。 模拟 Windows 文件索引存在、卷标识不可用的情况。实际路径在读取中切到另一文件,大小、mtime 和索引相同,ctime 不同。基线拒绝,当前 scan 返回 completed,将旧文件摘要挂到新路径,随后 exact_read 才拒绝。

动机 / Motivation

通过 Decision Context、本地材料提供器和冷源恢复读取有身份约束证据的使用者与维护者。原基线比较 ctime,完整身份的稳定 Windows 文件会因 ctime 偏差被拒。上个评审头还接受了归档 A/B 短暂替换和索引缺失的文件替换。当前保留完整 Windows 身份的稳定偏差支持。原先两个 P2 用例已独立复测,缺少索引的路径替换被拒,实际 prepare-import 拒绝从归档 A 证明 B 的成员。当前保留完整 Windows 身份的稳定偏差支持。原先两个 P2 用例已独立复测,缺少索引的路径替换被拒,实际 prepare-import 拒绝从归档 A 证明 B 的成员。独立反例在 macOS 上用真实文件、tar.gz、CLI 和 TypeScript owner,只注入 Windows 元数据。原生 Windows 文件系统上该部分身份组合的可达性未验证。模拟 Windows 文件索引存在、卷标识不可用的情况。实际路径在读取中切到另一文件,大小、mtime 和索引相同,ctime 不同。基线拒绝,当前 scan 返回 completed,将旧文件摘要挂到新路径,随后 exact_read 才拒绝。

改动思路 / Approach

路径身份与归档覆盖已有对应 owner,修复最小边界可以保留既有稳定读和恢复流程。冷备快照已解决归档成员混合;剩余改动只需保护共享材料身份例外。 冷备读取器把压缩包流式复制进原来的私有临时工作区,从同一副本取得 SHA-256 和成员信息。材料读取器需要同时核对卷与文件索引,才有依据区分稳定的 Windows creation time 偏差和实际替换。

具体改动 / Changes

关键代码讲解

5 个文件,+266/−15,比较基线 23bc2e0ed8dc8233620b3e349d686a55941dfc41。从有界材料与冷源覆盖契约核对三项。 Decision Context 冷源恢复

STABLE-WINDOWS-READ 通过完整身份、单独 ctime 偏差的实文件对照。BACKUP-MEMBER-INTEGRITY 用同一真实 CLI 测试复跑上一个评审头 6ac8672c9b2667426e5adbce5b728c2df8e11d7c 和当前头。此前返回 prepared,现在以 cold_import_backup_source_missing_or_changed 拒绝,且未创建 writer fence。 归档快照

PATH-REPLACEMENT-IDENTITY 已拒绝上一轮 st_ino=0 且 ctime 改变的替换。新用例在第二次 fstat 后重定向实际目录链接,通过受限读取器取得旧描述符内容,并由 exact_read 独立核对最终路径。 文件比较

对主干的风险 / Risks

Windows 文件索引的作用域是卷。完整身份不足时,scan 的调用方可在精确读取前收到错误的路径及摘要。基线和新头在索引缺失且 ctime 也完全匹配时仍有同一已知边界。归档侧会增加约一份压缩包的临时空间,现有容量错误涵盖副本和 SQLite 工作区。 Windows 文件身份

语义与 CI 对齐

独立 macOS 精确基线 65 项、当前头 84 项 pytest 通过,16 项 TypeScript 测试通过。Ruff、DCO、双语差异及预检 6 项直接和 13 项选中检查通过。部分身份反例由 macOS 实文件和注入的 Windows 元数据重现,原生 Windows 或共享卷可达性未验证。作者报告的原生 Windows 和 WSL 广覆盖结果包含失败。

我的整体评价 / Verdict

请求修改共享读取器对部分身份的处理。卷不可确认时,请保留 ctime 检查或从句柄取得等效身份。两项原修复均可沿当前实现保留。本次评审覆盖现有宿主与 CLI 行为。独立反例在 macOS 上用真实文件、tar.gz、CLI 和 TypeScript owner,只注入 Windows 元数据。原生 Windows 文件系统上该部分身份组合的可达性未验证。

English verdict: REQUEST_CHANGES. The original archive and missing-index cases are fixed. A partial Windows identity can still bind the original bytes to a replacement path when the volume is unknown. Require a complete identity before omitting the creation-time check.

Comment thread loopx/materials.py Outdated
identity_fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns", "st_ctime_ns")
identity_fields = ("st_dev", "st_ino", "st_size", "st_mtime_ns")
# Tolerate Windows ctime skew only when every observation has a file index.
if os.name != "nt" or not all(observed.st_ino for observed in (before, after, current)):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 卷身份缺失时保留替换检查。 macOS 上用实际文件替换路径,并模拟 Windows 观察中的 st_dev=0、相同非零索引、size/mtime 相同且 ctime 不同。基线拒绝,当前 scan 返回旧摘要和新路径,exact_read 才拒绝。索引只在卷内标识文件。请在确认卷和索引后才跳过 ctime,或用打开句柄证明同一身份。 Windows 文件身份

Retain ctime checks when the volume or file index is unavailable in material and cold-backup observations. Exercise real Windows junction replacement with partial metadata and preserve complete-identity skew.

Keep tar link normalization independent of host path syntax so valid first links remain accepted on Windows.

Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
@xiaobaifly7

Copy link
Copy Markdown
Contributor Author

Addressed the latest partial-Windows-identity finding in DCO-signed commit 72167ad714f6da77b09f74080682153979a20e73.

  • Both readers now omit ctime only with a complete, nonzero volume/file identity on every compared observation: all three in the material reader and both in the cold-backup comparison. Otherwise ctime remains checked.
  • test_local_file_same_metadata_replacement_has_no_verified_read[st_dev] retargets a real native Windows directory junction after the descriptor read. The replacement has equal size/mtime and an injected matching nonzero file index with st_dev=0. Scan now rejects immediately. Native red/green: 1 failed, 6 passed -> 7 passed, including replacement and stable-ctime controls.
  • test_archive_identity_change_policy covers missing volume/index and complete identity: 2 failed, 28 passed -> 30 passed. Complete-identity Windows ctime skew remains accepted.
  • Native validation of the requested valid first link exposed host-dependent tar-path normalization. POSIX normalization now accepts that link while retaining unsafe-descendant and cycle rejection.
  • The prior private-archive snapshot and real prepare-import archive swap/restore regression remain intact.

Final native focused validation: 81 passed, 1 skipped, 1 deselected, including ordinary regular-file capture, valid first link, stable ctime skew and real archive-swap CLI rejection. WSL supported material/BM25 tests: 38 passed, 1 deselected. Ruff and the configured WSL kernel typecheck (17 files) pass. An extra strict two-reader check retains four existing archive-scanner type errors (six at the reviewed head); host-specific fixture and POSIX permission limits are recorded in the local PR draft.

File/tar/CLI I/O and junction redirection were real native Windows operations. Unknown volume identity, index collision and ctime/race observations were injected only at OS boundaries; physical unknown-volume/SMB reachability remains unverified.

Existing commits were preserved.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max

复审提交:72167ad714f6da77b09f74080682153979a20e73。
上一轮的两类误接受均已关闭。可批准当前提交;剩余验证边界见下。

动机 / Motivation

使用本地授权材料的操作者,以及用备份把旧 Goal 迁入新状态存储的操作者。 Windows 上一份授权文件在读取过程中被替换时,旧实现可能接受已经失效的内容;冷导入原先也能把一份备份的摘要和另一份内容拼成同一张证明。现在遇到这些输入会拒绝这次读取或准备。 在相同输入上复现了旧版本的两条误接受,当前提交均拒绝;正常文件、合法备份和原有读取入口仍通过。 我独立验证了 macOS 的真实文件与 CLI,并注入 Windows 的 stat 返回。未独立运行原生 Windows、SMB 或生产恢复,也未查询远端 CI。

完整恢复和原生 Windows 文件系统的独立覆盖仍需另行验证。 Decision Context 架构合同 要求来源变更时不出具可验证读取;本地权威与冷迁移合同 区分备份验证、准备和正式导入。 核验项:bound_source_has_no_evidence_when_replaced, witness_uses_verified_archive_bytes。

改动思路 / Approach

保留现有两个证据入口。材料只有拿到完整身份才放宽 Windows ctime;冷导入在已有临时目录内复制压缩包,先验摘要再扫描同一份副本。 这次只改变材料读取和冷导入证明的构造;保留原有调用、选择范围和 apply 前复验。 只补文件索引检查会遗漏跨卷碰撞;在可变源上先后读两遍也挡不住调包再复原。先验证快照摘要,再解释 tar,保持旧的先验后读顺序。对空间成本已有明确失败出口。

具体改动 / Changes

  • 有界材料读取:卷与文件索引在每次观察都可用时,才容忍 Windows ctime 差异。文件长度、mtime 和身份仍检查。文件索引需要和卷身份一起解释,见 Microsoft 文件身份说明。
  • 备份文件身份 与 归档快照:使用相同保守时间戳规则。SQLite 成员索引保持原工作区;tar link 解析改用 POSIX 规则,越界及循环仍拒绝。
  • 冷导入回放:旧提交 8c46abc 中 st_dev=0 的真实路径替换没有拒绝;旧提交 6ac8672 中 A/B/A 覆盖以退出码 0 返回 prepared。当前两个反例均通过拒绝断言。 精确提交 122 项:Decision Context 读取/捕获、备份范围与冷导入 CLI。另有基点和提交各 57 项共享入口检查、两条旧提交重放,以及单独的复制中 ENOSPC 注入。 PR 合并基点和本提交分别通过 BM25、Goal direction、关闭状态隔离同一组 57 项测试;没有新配置或 schema。

对主干的风险 / Risks

复制进行一部分后注入 ENOSPC,返回 workspace_capacity;原 manifest 和压缩包逐字节不变,临时目录为空。正常 witness 的空间估计含压缩副本。 可用磁盘须容纳额外的压缩副本和成员索引;未测吞吐。普通 POSIX 读、禁用态与原 scoped proof 校验通过。Ruff、DCO、差异检查、双语 RFC 检查和对 b7c9178 的合入模拟通过。

我的整体评价 / Verdict

同意此提交。身份比较保留保守回退,归档证据也经过同一份已校验的输入。 生产改动留在原有 I/O 归属,未新增配置、存储或执行权。需要继续保留原生 Windows/SMB 的验证边界及历史 review 状态。

English verdict: APPROVE. Head 72167ad. The exact-head replay rejects both the missing-volume replacement and the mixed-archive witness. Normal reads and cold import passed. Windows metadata was injected on macOS; native Windows and SMB were not independently exercised.

@huangruiteng
huangruiteng merged commit b21e739 into loopx-project:main Nov 12, 2026
34 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants