feat(chv): 架构/可维护性/前端只读侧推进——生产实验分离、配置片段化、VM 只读展示
架构:WarmPool 从 cloud/chv/pool.py 移到 experimental_pool.py, 生产残留清理彻底分文件到 cloud/chv/orphans.py(facade 直接读 registry 文件清理,不构造池、不碰 prewarm/acquire/release); cloud/chv 与 cloud/sandbox 不再导出 WarmPool,旧路径一律 ImportError(CHV 未合并、无生产用户,兼容保留已无保留理由); worker 改走 orphans facade,不再持有 _warm_pool;#215 对齐从 接口形状推进到 REPLACEMENT_POINTS 替换清单(R1/R2 可机械替换、 R3 永不替换,#215 模块当前不存在由测试钉住)。 可维护性:build_chv_config 拆成 base/ssh/network/quota/disk/ timeout 六片段(组装只做 dict 合并,键冲突即报错;38 字段集 与取值不变,单项非法报错文案逐字一致);ADR-12 模块职责图 与禁 import 清单(AST 钉住);cloud/chv/ 公开 API 全量类型 标注、无 Any 逃逸,并修正三处旧标注错误;死代码扫一遍 (删实验池已无调用的 _quarantine 委托与未用 _LOGGER)。 前端(只读侧,不做控制按钮):chv.ts 新增纯逻辑谓词与文案 (执行器精确匹配、附件守卫、VM 状态文案、列表徽标);列表 行新增 VM 已报告死亡徽标;详情对全部 CHV 任务显示 VM 行 (已报告死亡/未报告死亡,不猜 live);WorkersSection 与成本 卡沿用已有数据,不新开池管理/成本页;服务端未新增第二个 生命周期字段(持久化事实只有三项,chv_vm_dead 已是完整派生), 只把派生抽成 _chv_vm_dead_from_row 并补 goal 回落形态测试。
This commit is contained in:
1 parent
42de20da68
commit
df8c64bd64
30 files changed
+1263
-331
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# Cloud Hypervisor 执行器架构决策记录(ADR)
|
||||
|
||||
范围:cloud/chv/ 执行器链(#216 → #221 → #230 → #232 → #234 → #239 → #246 → 本轨)。
|
||||
范围:cloud/chv/ 执行器链(#216 → #221 → #230 → #232 → #234 → #239 → #246 → #252 → #254 → 本轨 feat-chv-arch-maint-fe)。
|
||||
本文件只记录已落代码的决策,不记录未验证为已验证;真机、压测、动态安全
|
||||
仍见 docs/chv-production-readiness.md §11。
|
||||
|
||||
@@ -97,6 +97,15 @@
|
||||
import 路径),新代码不得经类入口进实验接口。
|
||||
- 测试钉住:facade 测试断言 acquire/prewarm 绝不被调;
|
||||
executor 不 import pool 由模块依赖检查覆盖。
|
||||
- 本轨更新(feat-chv-arch-maint-fe,取代上文“保留兼容”
|
||||
部分):CHV 尚未合并、尚无生产用户,“怕断 import”
|
||||
不是保留理由,兼容保留已删除。WarmPool 从 pool.py
|
||||
移到 experimental_pool.py,cloud/chv/__init__ 与
|
||||
cloud/sandbox.py 不再导出它,生产残留清理彻底分文件
|
||||
到 cloud/chv/orphans.py(facade 不再构造 WarmPool,
|
||||
直接读 registry 文件做清理)。旧 import 路径一律
|
||||
ImportError,见 ADR-12;合并前即生效的破环性清理,
|
||||
合并时须按 PR 描述的清单检查调用方。
|
||||
|
||||
## ADR-9 审计失败取舍:记日志 + 计数,不中断任务
|
||||
|
||||
@@ -125,6 +134,93 @@
|
||||
三个标记);_unix_socket_api 的读满语义仍由四个 helper
|
||||
共同保证,改任一 helper 须重跑截断/超时测试。
|
||||
|
||||
## ADR-12 模块职责图与禁 import 清单(本轨)
|
||||
|
||||
依赖方向(箭头 = 可以 import,叶子在下):
|
||||
- worker.py → orphans.py(生产残留清理,方法内 import)
|
||||
→ 标准库;worker 不 import experimental_pool。
|
||||
- executor.py → config/disk/hardening/hostkeys/
|
||||
ssh_transport/api_client/errors(方法内按需 import
|
||||
sandbox 共享 helper 除外,顶层绝不 import sandbox)。
|
||||
- experimental_pool.py → orphans.py(只借 registry 文件
|
||||
IO 与损坏语义,方向是实验 → 生产,绝不反向)。
|
||||
- orphans/config/compat215/errors → 只依赖标准库
|
||||
(叶子模块,测试用 AST 钉住)。
|
||||
- __init__.py / sandbox.py → 只 re-export 生产接口
|
||||
(CloudHypervisorExecutor、ChvFailure、
|
||||
reconcile_orphans_for_executor),不导出 WarmPool。
|
||||
- config.py → executor.py(executor 只经 build_chv_config
|
||||
取配置,不直接读 env 做二次解析)。
|
||||
|
||||
禁 import 清单(测试用 AST 逐项钉住,文档提及不算):
|
||||
- orphans/executor/worker/__init__/sandbox 一律不得
|
||||
import experimental_pool 或已删除的 cloud.chv.pool;
|
||||
- executor 一律不得 import orphans(执行器本体不做
|
||||
残留清理,那是 worker 启动/关闭的职责);
|
||||
- 任何生产模块不得 import cloud.gates /
|
||||
cloud.sandbox_policy / cloud.timeouts / cloud.quota
|
||||
(#215 未合并,见 compat215 REPLACEMENT_POINTS)。
|
||||
|
||||
## ADR-13 配置组装片段化(本轨,行为不变)
|
||||
|
||||
- build_chv_config 拆成六个片段:base(身份/资源基底)、
|
||||
ssh(密钥/用户/端口/host key 模式/客内路径/命令行)、
|
||||
network(net/net_json/ssh_host/ssh_forward/egress)、
|
||||
quota(max_vms/warm_pool_size)、disk(磁盘模式/大小/
|
||||
reuse 实验/快照上限与 URL)、timeout(任务/API/就绪
|
||||
超时)。组装只做 dict 合并,键冲突即 ValueError,
|
||||
绝不静默覆盖。
|
||||
- 移动说明(字段集合与取值不变,测试以 38 字段集钉住):
|
||||
egress 从旧 quota 片段移到 network(它是出口策略,
|
||||
不是 VM 配额);snapshot_url 从旧超时片段移到 disk;
|
||||
warm_pool_size 从旧超时片段移到 quota。唯一可观测
|
||||
的校验顺序变化:warm_pool_size 非法与磁盘非法同时
|
||||
出现时先报前者;单项非法时报错文案逐字一致。
|
||||
- 类型:cloud/chv/ 公开 API(非下划线函数 + 公开类
|
||||
__init__)全量标注,无 Any 逃逸;本轨顺手修正三处
|
||||
旧标注错误(record_snapshot 应为 tuple、host_key_paths
|
||||
应为 dict、build_seed_disk 应为 str)。私有 helper
|
||||
不在“公开 API”口径内,不硬标。
|
||||
|
||||
## ADR-14 前端只读侧扩展与验证方式(本轨)
|
||||
|
||||
- 本轨前端只做只读侧,不做控制按钮:后端无 VM 控制
|
||||
端点且安全审计 No-Go,绝不发明控制接口。
|
||||
- 列表行:此前 chv_vm_dead 只在详情展示,本轨列表行
|
||||
增加“VM 已报告死亡”徽标(字段已由同一 serializer
|
||||
返回,列表此前只是没渲染);无徽标时不代表 VM 活着。
|
||||
- 详情:此前只有 chv_vm_dead 时才出现 VM 行,本轨对
|
||||
所有 CHV 任务都显示 VM 行——已报告死亡给死亡文案,
|
||||
否则给“未报告 VM 死亡(后端无 live 状态字段,不代表
|
||||
VM 活着)”。非 CHV 任务不显示 VM 行;死亡文案同样
|
||||
先过执行器门,防止非 CHV 行误带字段时误显示。
|
||||
- 池管理与成本页:不新开页面。已有数据继续在已有
|
||||
位置展示:WorkersSection 的 CHV worker 在线数/共计、
|
||||
详情成本卡(token/LLM 请求数/美元明细,来自
|
||||
GET /tasks/{id}/cost)。没有数据的页面绝不新开。
|
||||
- 后端字段:本轨未新增第二个生命周期字段,理由写清——
|
||||
server 持久化的 CHV 生命周期事实只有 executor /
|
||||
status / interrupted_reason 三项,chv_vm_dead 已是其
|
||||
完整派生;再编一个字段要么是 interrupted_reason 的
|
||||
复制,要么是猜 live 状态,两者都不做。本轨后端改动
|
||||
是把派生抽成 _chv_vm_dead_from_row(行为逐字一致)
|
||||
并补 goal 回落形态(纯文本“VM 中途死亡”)的测试。
|
||||
- 前端测试:纯逻辑全覆盖——执行器选择谓词(精确值,
|
||||
不宽松匹配)、可用性(上一轨)、附件守卫谓词(CHV +
|
||||
带附件 → 后端 400,前端提示口径,后端是最终权威;
|
||||
派发页提交拦截已接该谓词)、只读状态文案与列表徽标。
|
||||
组件渲染不在覆盖内(无 testing-library 依赖,不临时
|
||||
加依赖冒充覆盖)。
|
||||
- 验证方式(仓库浏览器任务拒绝回环地址是已知限制,
|
||||
本轨绝不声称已做真机点击):① tsc + vite 构建通过;
|
||||
② npm run build:console 产物 console.html 经 grep 含
|
||||
新文案;③ Vitest 全过;④ 用户侧 live browser 手动
|
||||
检查清单(见 PR 描述):本地起 vite preview 或直接
|
||||
打开部署后的控制台,建一个 CHV 任务(无附件)进详情
|
||||
看 VM 行文案、带附件提交看拦截文案、列表行对已报告
|
||||
死亡任务看徽标;真机点击结果由用户侧回填,不在本轨
|
||||
回执里预填。
|
||||
|
||||
## ADR-11 只读 VM 字段边界:chv_vm_dead 不是 live 状态
|
||||
|
||||
- 决策:server 任务序列化只在 CHV 任务且 worker 已把
|
||||
|
||||
Reference in new issue
Block a user