round-12: migrate P8 registries + P12 audit to AppStateStore
- app_state.py: host_state_db_path() (host-level DB, distinct from per-VM state_db_path); kv_get/kv_put/kv_delete on meta (namespaced keys; kv_put skips the no-secrets guard by design — registry docs hold user prompts, documented); audit_trail table (P12 record shape + hash chain, seq explicit); counts()/backup() gain audit_trail. - swarm.py / presentation.py / browser_tasks.py: JSON-file backends replaced by KV rows (p8-swarm / p8-ledger / p8-browser-tasks); legacy JSON imported once on first load (renamed .migrated); corrupt row / unreadable store returns empty (fail-safe, same semantics as before; next successful save self-heals). - audit_trail.py: StoreAuditTrail (same record shape, hash chain, filters, export as JSONL version, backed by audit_trail table); migrate_jsonl_to_store() moves a chain verbatim (broken chain refused, divergent seq refused, re-run idempotent). JSONL class kept for reading old files. - P12 dict contracts now run against real P3/P5 code (ApprovalQueue.record -> build_approval_card -> card_matches_channel; CapabilityIssuer.issue -> describe -> PermissionRegistry.record_grant). - P6->P3 local protocol test: real PrivsepClient + real worker server + real git status; worker git argv carries the real P3 helper + useHttpPath; no token in argv/env/audit. runuser + HTTP pull stay real-machine-only (see gap docs). - Gap docs updated: P8 migration done, guest-side browser follow-up explicitly left for the real-machine track (no task_id in the browser protocol yet; lifecycle needs a real VM to verify); P6 wiring + P12 migration marked done; production-readiness.md gains §20 (round-12 integration). - Tests: new cloud/tests/test_chv_muse_round12.py, 24/24 OK; test_chv_muse_p8.py ledger corrupt test rewritten for the KV backend (+ legacy-import test). P7+P8: 95+1 tests OK.
This commit is contained in:
1 parent
466cf7eae7
commit
d4cef29cdb
11 files changed
+1147
-63
No files matched your search
@@ -76,14 +76,20 @@
|
||||
字段;任务简报允许二选一。
|
||||
- 审计持久化先用独立 JSONL 文件(`audit_trail.jsonl`,0600),
|
||||
待 P7 状态库就绪后迁移,迁移接口是 `from_legacy_row()` 同款
|
||||
转换(本文件行 → P7 记录)。
|
||||
转换(本文件行 → P7 记录)。**迁移已完成(round-12)**:
|
||||
`StoreAuditTrail` 走宿主级 AppStateStore 的 `audit_trail` 表,
|
||||
与 JSONL 版同一记录形状与哈希链;`migrate_jsonl_to_store()`
|
||||
原样搬链(坏链拒绝、分叉拒绝、重跑幂等);JSONL 版保留读旧
|
||||
文件,新写一律走 Store 版。测试钉在
|
||||
`cloud/tests/test_chv_muse_round12.py`。
|
||||
- project_id 强制:`list()`/`export()` 必须传 project_id,只返
|
||||
回该项目记录;跨项目读取返回空,不抛错(与现有 `list_audit`
|
||||
行为一致,不泄露“存在别的项目记录”这一事实)。
|
||||
|
||||
## 6. 真机待验证清单(未做,排队在 round-11 之后)
|
||||
|
||||
1. 审计 JSONL 在真实 VM 生命周期(wake/pause/resume/shutdown)
|
||||
1. 审计轨迹(round-12 起走 StoreAuditTrail / SQLite,不再是
|
||||
JSONL)在真实 VM 生命周期(wake/pause/resume/shutdown)
|
||||
下的追加与 `verify()` 表现。
|
||||
2. 活动摘要与真实任务派发/完成事件的对应(正在做是否及时变
|
||||
更、计划状态流转是否与 worker 终态一致)。
|
||||
@@ -91,5 +97,5 @@
|
||||
(签发→使用→过期→撤销全程)。
|
||||
4. 审批卡数据与 P5 对话外通道在真机上的端到端一致(卡上点的
|
||||
接受/拒绝与通道答复同一 pending_id)。
|
||||
5. 审计文件落盘权限(0600)与多进程追加(worker + host.py)
|
||||
下的完整性。
|
||||
5. 审计库落盘权限(0600)与多进程追加(worker + host.py)
|
||||
下的完整性(SQLite WAL + 30 秒 busy 超时)。
|
||||
@@ -129,6 +129,12 @@ Base64、零宽字符)、藏在图片/附件/二进制里的指令、需要理
|
||||
authd socket 路径、Sentinel 评估发生在 authd 放凭证前)。本轨
|
||||
测试用替身实现同一协议;与 P3 代码的真正接通发生在合入时,
|
||||
须由集成轨跑通 worker→helper→authd→git 的全链路。
|
||||
**已接通(round-12,本地部分)**:`cloud/tests/
|
||||
test_chv_muse_round12.py`(WorkerProtocolTest)用真
|
||||
PrivsepClient + 真 worker server + 真 git status 跑通,worker
|
||||
的 git argv 含真实 P3 helper 与 useHttpPath、argv/env/审计
|
||||
均不含 token;runuser 包装与 HTTP 拉取(需真实 gitea.tose.top
|
||||
+ Sentinel 放行)留给真机轨。
|
||||
2. **worker 跑在客内 root**:worker 守护进程以 root 身份跑在单元外
|
||||
(与 P3 authd 同款选择),git 子进程再以 chv 身份跑。root worker
|
||||
本身不受单元隔离保护——它的隔离来自 systemd 沙箱 + socket 白名单
|
||||
|
||||
+28
-13
@@ -50,16 +50,19 @@ VM 观察,未见于官方页面原文,本轨不把它当官方术语用;
|
||||
| `cloud/chv/browser_tasks.py`(新) | 每浏览器任务一个实例:建/绑/毁生命周期、单实例单任务(复用即错、毁后复用即错)、每实例独立状态目录;transport 接口注入(测试用 fake) | 本轨 |
|
||||
| `cloud/automations.py`(改) | 只加重试/停用所需的列与抢单入口(`max_retries`、`retry_backoff_seconds`、`consecutive_failures`、`next_retry_at`、`paused` 状态);host.py run-due **不动**(host 侧唯一执行器,见该模块 docstring) | 本轨 |
|
||||
|
||||
**P7 状态落点(更新 2026-11-07 06:39):** P7 已完成并提交(分支
|
||||
`feat-chv-muse-p7`,提交 `29fa0c8`:每 VM 一个 SQLite 状态库
|
||||
AppStateStore,0600 WAL,tasks/goals/sessions/只追加 audit/meta)。
|
||||
本轨仍先用 `state_dir` 下的原子 JSON 文件(复用
|
||||
`cloud/chv/atomic_file.py`),模块 docstring 与本表明确标注“待迁移到
|
||||
P7 状态存储”;不重复造一套状态库。集成轨(round-12)把
|
||||
`swarms.json` / `notification-ledger.json` / `browser-tasks.json`
|
||||
迁到 AppStateStore,接口(load/save/原子写)已按同一模式写好,迁移
|
||||
只是换后端。crons 与 swarm 的状态复用 `automations` 表与 swarm 登记
|
||||
文件(同款原子写),同样标注待迁移。
|
||||
**P7 状态落点(更新 2026-11-07 06:39;迁移已完成,round-12 更新):**
|
||||
P7 已完成并提交(分支 `feat-chv-muse-p7`,提交 `29fa0c8`:每 VM
|
||||
一个 SQLite 状态库 AppStateStore,0600 WAL,
|
||||
tasks/goals/sessions/只追加 audit/meta)。**round-12 已把三处登记
|
||||
迁到 AppStateStore**(分支 `feat-chv-muse-round12`):宿主级库
|
||||
`state_dir/app-state.sqlite`(`host_state_db_path`,与 per-VM 库
|
||||
同库不同文件),命名空间 `p8-swarm` / `p8-ledger` /
|
||||
`p8-browser-tasks`,一行存整份登记文档;旧 JSON 文件首次加载时
|
||||
自动导入并改名 `.migrated`;KV 行损坏/库打不开时回空结构
|
||||
(fail-safe,下次成功保存即覆盖自愈)。测试钉在
|
||||
`cloud/tests/test_chv_muse_round12.py`(P8MigrationTest)与
|
||||
`test_chv_muse_p8.py`(损坏行恢复 + 旧文件导入)。crons 的状态
|
||||
仍在 `automations` 表,未动。
|
||||
|
||||
**客机侧跟进(本轨只写规约、不改 P2 的文件):** 每任务浏览器实例的客机
|
||||
进程拉起/销毁在 P2 的 `chv-guest/chv-broker.py`(`browser` 操作固定转发到
|
||||
@@ -67,6 +70,17 @@ P7 状态存储”;不重复造一套状态库。集成轨(round-12)把
|
||||
socket),`close` 后杀掉进程。P2 的文件不在本分支基线里,本轨不复制、不
|
||||
分叉,规约写进本表 §6,留给 round-12 集成时落在 P2 分支上。
|
||||
|
||||
**客机侧跟进(round-12 决定:未做,留给真机轨):** round-12 核实后未做,
|
||||
原因三条:① `chv-browser.py` 的请求协议里没有任务 id 字段(只有
|
||||
open/snapshot/screenshot/close/ping),broker 分不清请求属于哪个浏览器任
|
||||
务,改 broker 之前须先改协议 + 调 broker 的调用方;② 进程拉起/销毁涉
|
||||
及以 chv-browser 身份起进程、socket 就绪等待、close 后杀进程与僵尸回收、
|
||||
broker 重启后的残留清理,在没有真机验证的情况下盲改,坏了就是每任务浏览
|
||||
器全断;③ 本地只能用假浏览器进程测生命周期,真 Playwright + 真
|
||||
chromium-headless-shell 的起停只能在真机上验。留给真机轨:先在真机上改
|
||||
协议(请求加 task_id)→ broker 按任务拉起/杀进程 → 连续两任务端到端
|
||||
(§6 第 4 项)。**不许写成已做。**
|
||||
|
||||
## 4. 自定数值清单(全部是本项目自定,非 Meta 官方值)
|
||||
|
||||
| 数值 | 本项目自定值 | 说明 |
|
||||
@@ -104,6 +118,7 @@ VM/单元里(P1 常驻池 + P2 单元是底座)。“子代理构建自己
|
||||
3. 回访通知端到端:后台任务完成后有新内容才通知、无新内容不通知、同一原因
|
||||
1 小时内不重复通知。
|
||||
4. 每任务浏览器实例端到端:连续两个浏览器任务各起全新实例、第二个看不到
|
||||
第一个的截图与快照状态(需 §3 客机侧跟进先落地)。
|
||||
5. 账本迁移:P7 存储已落地(AppStateStore,`feat-chv-muse-p7`
|
||||
提交 `29fa0c8`),集成轨把通知账本从 JSON 文件迁过去、去重语义不变。
|
||||
第一个的截图与快照状态(需 §3 客机侧跟进先落地;round-12 未做,见 §3)。
|
||||
5. 账本迁移:**已完成(round-12)**——通知账本与另两处登记已迁到宿主级
|
||||
AppStateStore(见 §3 更新),去重语义不变,测试钉住;真机上只需确认
|
||||
升级后旧 JSON 文件一次导入、不丢去重状态。
|
||||
@@ -1040,3 +1040,46 @@ auditd 审计、与 P3 authd/Sentinel 的真接线)。
|
||||
- 真机待验证:真实 token 回传下的月度累计与 402、真实多任务下的并发门、
|
||||
真实 worktree 下的存储门、提醒只发一次、账本并发写不断链。
|
||||
|
||||
## 20. 对齐 Muse round-12 集成:P4~P12 合入(分支 feat-chv-muse-round12)
|
||||
|
||||
- 合入顺序与提交:P4 c24cc0b → P5 d1c9a8e → P6 b0b9f5e → P7 320cd36 →
|
||||
P8 240949e → P9 90c42f6 → P10 b55b49b(acf98f8 的 cherry-pick,只含
|
||||
P10 自有 diff,基线已含的 P3/P5 未重复合)→ P11 77743e7 → P12
|
||||
466cf7e。基线 round-11 HEAD 29d3a5a。
|
||||
- 冲突处理(逐项):① executor.py:P9 的 `_inference_gate` 插到 P1
|
||||
分发器 `_run_with_vm` 之前,gate 调用为分发器第一条语句(deny/ask
|
||||
在常驻 resume 与冷启动 wake 之前 fail-closed);P9 自己的旧版本
|
||||
`_run_with_vm` 丢弃——其本体与 P1 `_run_cold` 逐字节相同(P1 的
|
||||
verbatim 搬运),合入时一度误删 `_run_cold` 体致 dispatch 回 None,
|
||||
已从 HEAD 原样恢复并由测试钉住;sentinel.py 取 P9 超集版。
|
||||
② build.sh/buildinfo.py:按 hunk 合,authd 三件套 + P2 三件套 +
|
||||
P4 三文件 + P7 chv-memory 全在 contents 里,GT 哈希仍为已批准的
|
||||
49ffe090…。③ docs §15 撞号:P4→§16、P6→§17、P7→§18、P11→§19,
|
||||
顺序顺延,无覆盖。④ P4 弄坏的 P2 测试改走假 CDP broker,断言不变。
|
||||
- AppStateStore 迁移(本轨做完):P8 三处登记(swarms.json /
|
||||
notification-ledger.json / browser-tasks.json)迁到宿主级库
|
||||
`state_dir/app-state.sqlite`(`host_state_db_path`,与 per-VM 库
|
||||
同库不同文件),命名空间 `p8-swarm` / `p8-ledger` /
|
||||
`p8-browser-tasks`,一行存整份文档;旧 JSON 首次加载自动导入并改名
|
||||
`.migrated`;KV 行损坏回空 fail-safe。P12 审计 JSONL 迁到
|
||||
`audit_trail` 表(`StoreAuditTrail`,同一记录形状与哈希链),
|
||||
`migrate_jsonl_to_store()` 原样搬链(坏链拒绝、分叉拒绝、重跑幂
|
||||
等);JSONL 版保留读旧文件,新写一律走 Store 版。`kv_put` 不过
|
||||
无凭证守卫(登记文档含用户 prompt,见 app_state.py 注释)。
|
||||
- 接线验证(本轨,本地):P6 worker→P3 helper/authd→git 跑通真
|
||||
PrivsepClient + 真 worker server + 真 git status(argv 含真实
|
||||
helper 与 useHttpPath,argv/env/审计不含 token;runuser 与 HTTP
|
||||
拉取留给真机);P12 审批卡吃真实 P3 `ApprovalQueue.record()`、
|
||||
权限登记吃真实 P5 `ScopedCapability.describe()`,均已用真实代码
|
||||
跑通,不再用替身。
|
||||
- 未决与留给真机轨:① P11 冲突原样保留(档位门只做准入、USD 路径
|
||||
不动,等用户裁决,见 `docs/chv-muse-p11-gap.md` §5)。② P8 客机
|
||||
侧跟进未做(`chv-browser.py` 请求协议无任务 id 字段、进程拉起/
|
||||
销毁须真机验证,见 `docs/chv-muse-p8-gap.md` §3)。③ 真机验证排
|
||||
在 round-11 之后:P1 常驻/balloon/vsock、P2 §5 九项否定测试、
|
||||
P3 §3.6 五项、P4/P5/P6/P7/P8/P9/P10/P11/P12 各自差距表 §6 清单、
|
||||
以及本轨新增的迁移后真机表现(旧 JSON 一次导入、Store 审计链
|
||||
在 VM 生命周期下的追加)。
|
||||
- 测试:新增 `cloud/tests/test_chv_muse_round12.py` 24 项全过;
|
||||
全量 cloud 套件见合入提交说明(每次合入后跑相关测试,最终全量
|
||||
一次跑通才算完)。
|
||||
Reference in new issue
Block a user