Files
codex-app-server/docs/chv-muse-p8-gap.md
T
host 8d4771bce3 feat(chv): align Muse P8 background work (crons/swarm/presentation/per-task browser)
- crons: pause/resume, exponential-backoff retry (cap 1h), retry claim
  single-winner reusing quota+task build, run_cron_tick cap 5/project
- swarm: per-agent task id + isolated workspace (resolve_inside gate),
  tool register + invocation audit (no execution in swarm layer)
- presentation: worth-presenting rules (needs_input/failed/new
  content only) + notification ledger dedup 1h per (task, reason)
- browser_tasks: one BrowserTransport instance per browser task,
  single-use (reuse after destroy refused), shots dir per instance
- automations: paused status + retry columns (max_retries,
  retry_backoff_seconds, consecutive_failures, next_retry_at)
- gap table docs/chv-muse-p8-gap.md; self-defined values listed there
  (not Meta official): tick cap 5, swarm max 32/default 8, retry
  base 60s cap 3600s, ledger window 3600s, snapshot trunc 200/64KB
- tests: 49 new in cloud/tests/test_chv_muse_p8.py (incl. negatives:
  cron unauthorized trigger, cross-workspace access, no-content
  silence, dedup); full cloud suite 1916 OK (skipped=8)
2026-11-06 22:42:31 +00:00

110 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 对齐 Muse P8 差距表:后台工作(crons / 子代理群 / 回访通知 / 每任务浏览器子代理)
> 先写表再动手。口径分层:= Meta 安全文(security.muse.ai 2026-09-08)与产品
> 设计文(introducing.muse.ai)原文;= 媒体/评测转述;=
> 二进制拆解与用户 VM 观察。凡是 Meta 未公开的数值(cron 调度粒度、数量上限、失败重试
> 策略),一律写清是**本项目自定**,不得写成 Meta 官方值。
## 1. Muse 官方要求(出处:研究报告 §2.5)
| # | 要求 | 来源 |
|---|---|---|
| B1 | 关应用后继续工作;按计划与相关事件推进 | 设计文 |
| B2 | 完成后台工作后评估是否“值得呈现”,只在真正有新内容或需要输入时通知用户 | 设计文 |
| B3 | 启动成群的子代理、构建自己的工具、编辑自身;VM 需要足够存储、CPU 与内存来做真正的工作——如编译代理写的代码、开发自定义 Skills、处理并发子代理与 crons | 安全文 |
| B4 | 每个浏览器任务由专门浏览器子代理完成 | 安全文 |
| B5 | 定时任务(crons)与并发子代理并存 | 安全文(只提存在) |
| B6 | cron 的具体调度粒度、数量上限、失败重试策略 | Meta **未公开**——本项目自定,见 §4 |
**不在本轨官方口径内的东西:** “目标工作器(objective workers)”一词只见于第三方
VM 观察,未见于官方页面原文,本轨不把它当官方术语用;长期目标的分派与通知步骤
用本轨的 swarm + presentation 实现,不挂这个名头。
## 2. 现状(基线 06c3e17,实测代码为准)
- **crons,两套现成的、都不完整:**
- `host.py run-due`:host state JSON(name/task/repo/interval/last_run),
`now - last_run >= interval` 到期即派发 host 任务,跑完才回写 last_run。
无重试、无失败计数、无启用/停用(只有删定义)。
- `cloud/automations.py`:控制面 automations 表(SQLite/Postgres),
`claim_due_automation` 条件 UPDATE 抢单(同一间隔只一个执行器拿到),
配额门、`automation_runs` 产出记录、分诊收件箱。无重试策略、无 paused
状态、无单项目上限。`MIN_INTERVAL_SECONDS=60`、`MAX_INTERVAL_SECONDS=30d` 已有。
- **子代理群:没有。** 只有模型层的子代理名(`cloud/harness2.py`
`subagent_names`,prompt 树里的名字),没有执行层的并行派发、没有隔离、
没有工具注册。
- **后台回访通知:没有“值得呈现”评估。** `cloud/push.py dispatch_event`
按订阅派发终态(completed/failed/goal-unmet 等);自动化模块 docstring
已写明“不新写通知代码”。无去重、无节流——同一终态可重复派发。
- **每任务浏览器子代理:没有。** P2 的 `chv-browser.py` 是常驻进程,
`close` 只关当前页、进程继续跑、等下一次 open;broker 固定转发到
`/run/chv/browser.sock`。状态跨任务复用。
## 3. 改什么(本轨四个新模块 + 一处扩展)
| 模块 | 内容 | 归属 |
|---|---|---|
| `cloud/chv/crons.py`(新) | 在 `cloud/automations.py` 之上加:启用/停用(paused 状态)、失败重试(指数退避 + 上限)、单项目并发上限与定义上限、tick 驱动(到期 + 重试到期统一认领) | 本轨 |
| `cloud/chv/swarm.py`(新) | 子代理群:建群/派代理/生命周期;每代理独立任务 id + 独立工作区(`resolve_inside` 门,越界拒绝);工具注册与审计(只登记与审计调用意图,执行在代理自己的 VM 里走执行器);上限可配 | 本轨 |
| `cloud/chv/presentation.py`(新) | “值得呈现”评估(需要输入/失败需决策/有实质新内容才通知,常规完成只记日志)+ 通知账本(每任务每原因节流去重) | 本轨 |
| `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 登记
文件(同款原子写),同样标注待迁移。
**客机侧跟进(本轨只写规约、不改 P2 的文件):** 每任务浏览器实例的客机
进程拉起/销毁在 P2 的 `chv-guest/chv-broker.py`(`browser` 操作固定转发到
单例 socket)里改:每浏览器任务起一个全新的 `chv-browser.py`(每任务
socket),`close` 后杀掉进程。P2 的文件不在本分支基线里,本轨不复制、不
分叉,规约写进本表 §6,留给 round-12 集成时落在 P2 分支上。
## 4. 自定数值清单(全部是本项目自定,非 Meta 官方值)
| 数值 | 本项目自定值 | 说明 |
|---|---|---|
| cron 最小间隔 | 60 秒(沿用现有 `MIN_INTERVAL_SECONDS`) | 已有,不新定 |
| cron 最大间隔 | 30 天(沿用现有 `MAX_INTERVAL_SECONDS`) | 已有,不新定 |
| 失败重试默认次数 | 3 次 | 超过即停,不再重试 |
| 重试退避 | 基数 60 秒 × 2^(n-1),上限 3600 秒 | n 为第几次重试 |
| 单项目并发 cron 执行 | 5 | tick 单轮最多认领 5 个 |
| 单项目自动化定义上限 | 100 | 超过建定义即 ValueError |
| 每群子代理上限 | 8 | 建群时可配,1–32 |
| 每项目群上限 | 10 | 超过建群即 ValueError |
| 通知节流窗口 | 同一任务同一原因 3600 秒内只通知一次 | 账本持久化 |
| 工具名长度上限 | 100 字符 | 与自动化名上限同款 |
## 5. 诚实边界
- B3 的“VM 需要足够资源”是容量要求,不是本轨能代码保证的:本轨只做上限与
隔离,宿主容量仍由部署方保障;群上限 8 是防炸宿主的默认值,不是性能承诺。
- swarm 层**不执行工具**:工具调用意图只登记与审计,真正执行在子代理自己的
VM/单元里(P1 常驻池 + P2 单元是底座)。“子代理构建自己的工具”在本轨指
注册进群内工具表、可被审计、可被别的代理复用调用名——不是沙箱外任意执行。
- “实质新内容”的判定是确定性规则(新产物/新改动文件/显式 notify 标志),
不是模型判断;模型觉得重要但规则判无新内容时,以规则为准、只记日志。
- cron 重试只针对 failed/interrupted 的执行;超配额跳过(skipped_quota)
不是失败,不进重试(沿用 automations 模块现有口径)。
- 通知账本先走原子 JSON 文件,P7 存储(`feat-chv-muse-p7` 提交
`29fa0c8` 的 AppStateStore)已落地,集成轨再迁移;迁移前账本丢了只
影响去重(可能重复通知一次),不影响任务执行本身。
## 6. 真机待验证清单(round-11 与 P4/P5/P6 之后,等通知)
1. cron 端到端:定义在测试机上按间隔触发、失败重试 3 次后停、停用后不再触发。
2. 群端到端:3 个子代理在各自 VM 里并行跑、互不可见对方工作区。
3. 回访通知端到端:后台任务完成后有新内容才通知、无新内容不通知、同一原因
1 小时内不重复通知。
4. 每任务浏览器实例端到端:连续两个浏览器任务各起全新实例、第二个看不到
第一个的截图与快照状态(需 §3 客机侧跟进先落地)。
5. 账本迁移:P7 存储已落地(AppStateStore,`feat-chv-muse-p7`
提交 `29fa0c8`),集成轨把通知账本从 JSON 文件迁过去、去重语义不变。