Repository navigation
fix(runtime): reject nested archive destinations - #6206
huangruiteng merged 4 commits into
Conversation
archive-runtime accepted an archive root inside the source Goal directory. shutil.move then copied the source into itself until the path length limit, while dry-run reported would-move. Reject resolved nested destinations before preview succeeds, and recheck under the archive locks before moving. Cover source, direct-child, and deeper-child roots in both modes. Signed-off-by: Duang777 <duangjl007@gmail.com>
|
@loopx-agent review |
A source-child symlink to an external archive could pass the resolved-path guard. The move succeeded, but archive_path still used the old source route and became unreadable after the source moved. Reject destinations whose lexical ancestors resolve to the source, including aliased source routes. Cover direct and aliased symlink roots in dry-run and execute modes. Signed-off-by: Duang777 <duangjl007@gmail.com>
|
@loopx-agent review |
…rchive-nested-root-20261011 Signed-off-by: Duang777 <duangjl007@gmail.com>
…rchive-nested-root-20261011 Signed-off-by: Duang777 <duangjl007@gmail.com>
|
@loopx-agent review |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=xhigh
APPROVE;未发现本批阻塞问题。评审精确 head:086b296956c633f1ff0f207a1df8e417fc49f1d6。
动机
清理过时运行目录的维护者把自定义归档位置放进了被移动的目录。以前预览仍显示可执行,真实移动可能递归复制,或移动后返回已经失效的路径;现在预览和执行都先拒绝这种位置。
真实 CLI 在目录本身、子目录以及源目录内指向外部的符号链接路径上返回稳定错误,源文件保持原样且归档位置没有写入;合法外部位置的预览和真实移动仍成功,归档文件可以读回。
本批只补归档位置的安全检查和诊断说明,不改变 registered Goal 的授权、锁顺序或归档成功回执,也不授权清理在用 Goal。
改动思路
在既有 runtime 文件移动 owner 内增加一个本地前置条件,预览和锁内执行共用;同时检查物理路径和词法祖先,因为仅 resolve 会漏掉源目录里的外链移动后失效。此检查默认强制执行,Python 在这里承担文件系统 IO,没有另造控制面决策源。
当前 PR 交付安全预览、锁内执行拒绝、合法外部归档和诊断参考;保留现有注册、锁、命名与回执契约,不加入新的能力或权限。 已比较不修复、只改文字/单点校验以及当前方案:前两者不能消除上述已复现的问题;当前修改在既有 owner 内一起覆盖拒绝、恢复与回读。已检查相邻 #6205 的完整项目卸载改动:它选择只移动状态文件,runtime 归档则必须保留运行目录整体移动并拒绝自包含目标;两者生命周期与回执不同,适合各自最近的 owner。
具体改动
独立规格为 docs/status-data-contract.md,spec_revision:2510aeb7b89f25c84f244f4c3ceea4abdfde5caa,使用变更前的完整不可变文本;本 PR 新写的说明只用于披露,不用于自证。
Attention Queue:implemented;archive-runtime defaults to dry-run and requires --execute before moving the runtime directory under the archive destination. 由上述实际入口和回读验证。
关键代码讲解
_validate_archive_destination同时检查目标的物理包含关系与词法祖先。源目录内的外链即使 resolve 到外部,也会随源目录移动而失去原路径,因此仍须拒绝;真正位于源目录外的别名继续允许。archive_runtime_goal在预览前调用检查,并在既有 source/maintenance/registry 锁内重新选择目标、重新检查后才 mkdir 与 move,保留注册 Goal 的显式授权和新鲜回读。- 注册 IO manifest 只同步行号,focused tests 覆盖 dry-run/execute、根/子/深路径及别名;self-repair 参考增加对应诊断,未新建共享状态词汇。
对主干的风险
实际运行 runtime archive、并发、repair pattern 与 registry IO census 的 40 项测试;Ruff 与 diff check 通过。冻结的真实 CLI 反例在 immutable base 上 7 项非法位置仍被接受,3 项合法对照通过;head 与独立 wheel 均 10 项通过,检查源文件未损坏、错误前无写入,以及成功归档路径确实可读。
本次原生文件系统反例在 macOS 上运行,未声称验证 Windows junction 或对抗性符号链接竞态。既有锁保护协作写入,不把这个检查扩称为任意进程的文件系统隔离;合法外部归档、注册门禁与并发测试已实际运行。 初次验证中的错误路径、解释器 cwd、测试请求或压缩视图 shape 问题已定位并修正;不将这些无效运行计作通过。CI 按当前配置没有查询、轮询或等待,结论来自上述本地独立覆盖。
语义与 CI 对齐
先运行 changed-diff advisory,再运行完整 tracked semantic-vocabulary/registry IO smoke;均通过,但完整检查仍明确保留 45 个 unresolved producer sites,不据此声称所有语义已证明。路径判断和错误模式保持在本地文件系统 owner;不新增共享生命周期或授权词汇。
我的整体评价
long_horizon 与 user_experience 均 improved:本轮验证覆盖从拒绝到合法恢复及随后有用结果,而非仅生成诊断。在既有 runtime 文件移动 owner 内增加一个本地前置条件,预览和锁内执行共用;同时检查物理路径和词法祖先,因为仅 resolve 会漏掉源目录里的外链移动后失效。此检查默认强制执行,Python 在这里承担文件系统 IO,没有另造控制面决策源。 当前 PR 交付安全预览、锁内执行拒绝、合法外部归档和诊断参考;保留现有注册、锁、命名与回执契约,不加入新的能力或权限。 没有 opt-in/default-off 声明;不把默认强制的正确性检查称为可选 guidance。相关未来维护整理复用本地前置条件即可,无需扩成跨生命周期框架,整体成本与风险相称。批准仅针对上述 head 和已验证边界,平台汇总、旧 review closeout 与合并授权另外回读。
English verdict: APPROVE - exact head 086b296. No blocking finding in the complete reviewed slice. Unsafe nested and lexical-symlink destinations reject without effects; legal external archive readback, concurrency and installed-wheel validation passed. Filesystem probes ran on macOS; Windows junctions and hostile symlink races remain unqualified.
|
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=xhigh |
Problem
archive-runtimeaccepted an--archive-rootinside the runtime Goal directory. Dry-run returnedwould-move, while execute recursively copied the source into itself until the path length limit and left nested partial state.A source-child symlink to an external archive exposed a second form. The move succeeded, but the reported
archive_pathused the old source route and disappeared after the move. Source path aliases could bypass a direct lexical comparison.Change
shutil.move.The existing runtime lifecycle owner remains sufficient; no adjacent refactor is needed.
Validation
40 passed: runtime archive, archive concurrency, repair-pattern lookup, and project-registry I/O census.