agent-exec transport 99605f17561d82dabbbf47596ef94de8/b1dcdad669fd
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# 独立 Review:容器化存储 U1(环境与数据归属合同)
|
||||
|
||||
- 日期:2026-10-22
|
||||
- 审阅对象:`feature/container-storage-plan-u1` 分支 HEAD
|
||||
- base:`955a32de2bb49171348bad5f566cce935df19212`
|
||||
- head:`e1f08650a12656611f27438f23fddbfab6a96299`(分支尖端;实施内容经 agent-exec transport 提交 `2d75d101a04ce1d1c9fa1d66d9567894222399d5`,另有路由调整 transport 提交 `0c8bea37` 与任务卡记录提交)
|
||||
- 送审 diff:`/tmp/container-storage-u1-review.diff`(已核对与 `git diff 955a32de..HEAD` 的代码部分逐字一致;仅 `.task/**` 任务卡不在 diff 内,属 host 直写豁免区)
|
||||
- 方案依据:`docs/superpowers/plans/2026-10-22-container-storage-plan.md` U1 小节、KTD1—KTD4
|
||||
- 审阅方式:全新会话独立审阅(非实施者);实际读代码核对绑定解析、拒绝路径与身份保留逻辑;未实施任何修复。
|
||||
|
||||
## 总体判定:REVIEW PASS
|
||||
|
||||
无阻塞项。U1 验收场景(旧配置升级保留身份、错库/错根/foreign marker 拒绝、同名项目或冲突端口修改前失败、另一 checkout 定位同一资源、缺必需绑定不静默新建空库)均有实现且被测试覆盖;KTD3 单一权威合同成立;无秘密入仓;测试 80/80 通过(1 项真实 PG 专项显式 NOT_RUN)。下列非阻塞项建议在 U2 及最终交付前处理。
|
||||
|
||||
## 阻塞项
|
||||
|
||||
无。
|
||||
|
||||
## 非阻塞项
|
||||
|
||||
| # | 级别 | 位置 | 发现 | 建议 |
|
||||
|---|---|---|---|---|
|
||||
| N1 | 建议 | `scripts/svc.sh` `svc_set_key`/`svc_del_key`(4674/4691 行起) | manifest `set` 因绑定校验或冲突被拒(exit 2/3/7)时,回退路径仍把该键写入派生视图 `svc.env`,整体操作"成功"返回。权威 manifest 未被污染(`resolve_storage_bindings` 只读 manifest),且两种漂移方向在启动时均 fail-closed(`svc.env=container`/`manifest=legacy` → `verify --require-storage` 触发 `完整存储合同要求 storage_mode=container` 拒启;反向漂移由 record_state 重建自愈),但"冲突在修改前失败"的语义被弱化为"权威拒绝+视图静默写入"。当前无任何调用方经 `svc_set_key` 写存储键(调用点仅 autostart/exec/dbref/dsn/conffile/addr/tags),风险处于潜伏状态。 | 存储键(STORAGE_KEYS 集合)在 manifest set 失败时硬失败,不走 legacy 单键回退。 |
|
||||
| N2 | 建议 | `scripts/svc.sh` `svc_manifest_verify`(1302 行) | container 分支门控用 `svc_get storage_mode`(读派生 `svc.env`)而非 manifest identity。manifest=container 而 svc.env 过期(manifest 与 svc.env 两次原子写之间的崩溃窗口,或绕过 svc 手改 manifest)时,该次启动跳过存储校验;下次 record_state 经 bulk-set 重新派生后自愈。窗口窄且可自愈,但与"manifest 为权威"的门控意图不一致。 | 门控改为读 manifest identity 的 `storage_mode`(或在检测到两处不一致时拒绝并提示重建派生视图)。 |
|
||||
| N3 | 建议 | `deploy/data-ownership.md`(持久文件根行) | 声明"禁止他实例共用同一根",但 `check_conflicts` 只扫描 compose 项目名与端口,不检测跨实例 files_root 重叠/嵌套;测试夹具(precheck `test_compose_project_conflict_refused`)中 b 的根位于 a 的根之下,同样未拦截。无 U1 验收场景要求此项,属文档强于实现。 | 收紧措辞为"登记层不拦截,容器挂载层(U2)负责隔离",或在 U2 增加跨实例根重叠预检。 |
|
||||
| N4 | 记录 | `scripts/svc_manifest.py` `check_conflicts` | 冲突扫描范围限定同一 runtime 目录(`RUNTIME="$ROOT/runtime"`,`--runtime` 显式传入)。同机跨 checkout 的多个 runtime 目录之间的 compose 项目名/端口冲突在 U1 登记层不可见,实际碰撞推迟到 U2 容器启动时由端口占用/compose 报错暴露。实现注释与文档均按"同一 runtime"表述,范围自洽;U2 场景"prod/test/verify 同时运行互不冲突"已承接此项。 | U2 落地容器驱动时复核跨 runtime 同机冲突的最终防线。 |
|
||||
| N5 | 建议 | `tests/` | 两个覆盖缺口:(a) 无 container 模式实例完整 start/stop 生命周期测试——`preserve_storage_keys`(record_state → bulk-set 写回时保住存储键)与 svc.sh 传 `--runtime` 的改动未被端到端 exercised,若该逻辑回归,绑定会在一次生命周期写回后被静默清掉;(b) `test_CS_U1_missing_binding_rejected` 只覆盖"全部缺失",未覆盖"三库中任一缺失"(如 base/rdm 齐备仅 kb 缺失)的逐槽拒绝。 | 各补一条测试:container 实例启停后锚点与 kv 绑定不变;逐槽缺失各断言一次。 |
|
||||
| N6 | 记录 | `AGENT-EXECUTION.md`(implementation 角色顺序) | 不在 U1 单元 allowed_paths 内,属越界文件变更;但它是独立登记的路由单元(任务卡行 `container-storage-routing-promote-antigravity`,transport `0c8bea37`,收据 `/tmp/container-storage-routing-receipt2.json`),披露完整,且变更注释自述"临时调整,交付前回退"。 | 按其自述在 U1 合入/交付前回退;不阻塞 U1 评审结论。 |
|
||||
| N7 | 记录 | `scripts/svc_manifest.py` | `slot_port_of` 只校验 `isdigit()`,接受 `0` 与超范围数值,未限 1—65535。 | 顺手项,U2 接真实容器端口发布前收紧即可。 |
|
||||
| N8 | 记录 | `scripts/svc_manifest.py` `cmd_verify` | container 启动路径把 `resolve_storage_bindings`(源自 manifest)的值回传给 `verify` 比对,本质是 identity↔kv 自一致性检查(可拦手改 manifest 的不一致),并非运行时"连到外宾库"检测;后者按方案属 U2(启动顺序真实认证/身份检查)与 U3(库内身份)范围。U1 的"错库拒绝"在绑定锚点层面成立(`base 库绑定漂移` 路径有测试),范围声明准确。 | 无需改动;U2 接线时保留本检查作为快速失败层。 |
|
||||
|
||||
## 核对点(实际读代码/跑测试核对)
|
||||
|
||||
1. **旧配置升级保留身份**:`build()` 对已带 storage 键的 kv 只做形态校验(`require_complete=(mode==container)`),不重建 instance_id;`test_CS_U1_legacy_upgrade_keeps_identity` 断言升级后 `instance_id`/`data_root` 不变、锚点落 identity。✅
|
||||
2. **身份保留/重锚**:`reanchor(write=False)` 预览仅用于冲突扫描、不落 marker;`mutate` 顺序为"校验 → 冲突扫描 → 重锚 → 落盘",冲突时不落盘;`slot_ref_of` 冲突(dbref 与 dsn_ref 同设)、相对路径 `*_dsn_ref`/`*_role_ref`/`files_root` 均拒绝;legacy→container 升级基座可回落既有 `dbref=` 专键,明文 `dsn=` 不进锚点(I5)。✅
|
||||
3. **拒绝路径**:container 缺任一必需绑定在 set(`validate_storage_kv` exit 3)与 verify(`--require-storage` + `require_complete=True`)双端拒绝;错文件根/错库绑定漂移 exit 6(测试断言"文件根"/"base 库绑定漂移");foreign marker 沿用 base 逻辑(T5b);compose 项目名/端口冲突 exit 7 且发生在落盘前(`check_conflicts` 在 `save` 之前)。✅
|
||||
4. **不静默新建空库**:U1 层无任何默认绑定生成;`resolve_storage_bindings` 缺绑定 exit 3 → svc.sh 拒绝;manifest 缺失时 verify exit 4、marker 缺失/损坏 exit 5,均阻塞启动。未发现静默回退空库路径。✅
|
||||
5. **另一 checkout 定位同一资源**:`files_root` 强制绝对路径并 normpath,锚点/解析不依赖 cwd 与仓库根;`test_CS_U1_other_checkout_keeps_absolute_files_root` 与 T6 从外部 cwd 调用验证。✅
|
||||
6. **调用方环境污染**:`env_config` 重置存储全局并 `unset AGENT_SYSTEM_FILES_ROOT/ENV_CLASS/COMPOSE_PROJECT/BASE_DB_REF/RDM_DB_REF/KB_DB_REF`;`test_caller_storage_env_does_not_reach_serve` 检查 serve 进程 environ 与 serve.env;三条棘轮测试守卫 env_config。✅
|
||||
7. **KTD3 单一权威**:`resolve_storage_bindings` 内嵌 python 直读 `manifest.json`(不读 svc.env、不读调用方 env);U1 未引入 compose 文件/第二份卷或 DSN 权威;凭据仅存受保护文件路径引用。`svc.env` 仍是派生只读视图(record_state 不产出存储键,`preserve_storage_keys` 自 manifest 旧 kv 保留)。✅
|
||||
8. **归属清单与契约文档**:`deploy/data-ownership.md` 覆盖基座/RDM/KB/文件根/环境身份/实例身份/Compose 项目七类所有者,含引用形式与唯一写者;体量/源版本/表清单明示"需另行授权访问后补全"(与方案"生产盘点需先获得对应访问授权"及诚实出口一致);无秘密值。`docs/svc.md` §10.1 键表与 `PROJECT.md` 指针已同步;链接目标 `docs/recovery/u1-data-ownership.md`、`docs/recovery/u1-identity-manifest.md` 均存在。✅
|
||||
9. **测试充分性**:三测试文件合计覆盖全部五条 U1 验收场景 + 调用方隔离 + 原子写崩溃窗口;缺口仅 N5 两项(均非验收场景直接要求)。`PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc_identity tests.test_svc_lifecycle_isolation tests.test_svc_precheck` → **80 tests, OK (skipped=1)**,唯一 skip 为真实 PG 专项显式 NOT_RUN(诚实标注)。✅
|
||||
10. **秘密与越界**:diff 无明文口令/DSN/token(示例 env 仅受保护路径,测试仅 fixture 值 `ref-only`/`x`);changed files 中除 `AGENT-EXECUTION.md`(见 N6,已另行登记)外全部落在 U1 主要文件/allowed_paths 内;`.task/**` 为 host 直写豁免。✅
|
||||
|
||||
## 复现命令
|
||||
|
||||
```bash
|
||||
# 1) 送审 diff 范围与实际 HEAD diff 一致(代码部分逐字相同)
|
||||
git diff 955a32de2bb49171348bad5f566cce935df19212 HEAD \
|
||||
-- AGENT-EXECUTION.md PROJECT.md deploy docs/superpowers/plans docs/svc.md scripts tests \
|
||||
| diff - /tmp/container-storage-u1-review.diff && echo IDENTICAL
|
||||
|
||||
# 2) 单元测试(本机实测:Ran 80 tests, OK (skipped=1),约 64s)
|
||||
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest \
|
||||
tests.test_svc_identity tests.test_svc_lifecycle_isolation tests.test_svc_precheck
|
||||
|
||||
# 3) 对象 SHA
|
||||
git rev-parse HEAD # e1f08650a12656611f27438f23fddbfab6a96299
|
||||
git rev-parse 955a32de # 955a32de2bb49171348bad5f566cce935df19212
|
||||
```
|
||||
|
||||
## 结论
|
||||
|
||||
U1 单元按方案完成且质量合格:绑定/身份权威唯一、拒绝路径完整且 fail-closed、验收场景全部落地并有测试背书。上述 N1—N8 均不阻塞本单元交付;N1/N2/N5 建议随 U2 或合入前收口,N6 的路由临时调整须按其自述在交付前回退。
|
||||
Reference in New Issue
Block a user