Tobatsu V11 · delivery evidence

V11 交付成果全量报告

这不是只写“完成了”的总结。V11 实际交付了 worker2、NAS 运行路径、Mai/Ignis 真实 workflow smoke、Ask/Continue 恢复、扩容到 30、Claude engine profile、Admin 切换能力、DB 锁修复、Claude home 上 NAS,以及关闭 memory scope 的边界说明。

new host
1
magi-worker2
worker target
30
mai-ignis 最终目标数
workflow smoke
4/4
FFmpeg / 字幕 / PIP / DH
engine smoke
2/2
Claude + Codex rollback
memory scope
0
用户取消,没有偷偷做

1. 交付总览

V11 最终不是单点修补,而是两条完成线:11A 把 worker2 作为真实可用的 NAS-backed worker 建起来;11B 把 Claude 作为正式 engine 接进系统并做 Admin 可切换。

交付完成

11A: worker2 可跑 Mai/Ignis

新机器 magi-worker2 接入,隔离队列 mai-ignis,NAS 路径、Codex context、task_inquiry、4 个 workflow smoke、扩容到 30 都完成。

交付完成

11B: Claude 引擎可切换

新增 claude-default engine profile,Admin 可保存 workflow override,新任务立即生效,旧任务冻结不受影响。

明确延期

11C: memory 不做

Cloud memory 是用户明确取消。V11 没有 memory 代码、表结构、部署、smoke 或生产改动。

2. 最终运行形态

核心变化是把 worker2 接成一台独立生产级 worker,先用 mai-ignis 隔离验证,避免抢 magi3 的现有业务队列。

Admin / API
Admin selector、workflow override、task create/readback。
Postgres
engine_profile_at_create、workflow_engine_overrides、task/run freeze。
magi-worker2
mai-ignis 30 workers + task_inquiry 1。
NAS CFS
workspaces、runs、managed-skills、Codex/Claude context。
Providers
Rendi、Fal、Claude、Codex、R2/CDN 输出。
!
magi3 边界:V11 后半段已经明确收紧为 magi3 no-touch。worker2 可以测试和改,magi3 不再随便 stop/restart/改 desired_count。

3. 11A: worker2 / NAS 具体交付

这部分是真正的机器建设,不是文档。挂载、重启、权限、appserver、worker、inquiry、smoke、扩容都做了。

交付项状态细节
magi-worker2完成新 SSH alias / host id,worker-only,不跑 Admin/API/Scheduler,不接 default/material/test。
NAS mount完成172.22.16.62:/uyuuvux6/ -> /mnt/tobatsu-cfs,NFSv3,vers=3,nolock,proto=tcp,noresvport,fstab + reboot 后验证。
runtime roots完成workspacesrunssharedmanaged-skillshosts/magi-worker2 按规则落到 NAS。
appserver完成worker2 本地 tobatsu-codex-appserver,监听 127.0.0.1:45992,readyz/healthz 200。
mai-ignis完成独立队列,最终 desired=30 / online=30,不抢 magi3 的 queue=mai
task_inquiry完成worker2 本地 inquiry supervisor,Ask/session 相关路径不再依赖 magi3。
alias cleanup完成4 个临时 *_ignis workflow 全部 soft-delete,源 workflow 保留。

4. 虚拟环境和依赖层:这部分是 V11 的主要工作量之一

这里不是“装了 Python 包”这么简单。任务进程、hook、provider client、agent home 分属不同层。V11 过程中出过真实失败,最后逐层补齐。

依赖层实际状态V11 里踩到/修掉的问题
repo .venv 位置是每台机器自己的 /home/ubuntu/workspace/fp/tobatsu/.venv。worker2 审计记录 Python 3.14.5。 这才是真任务 import provider 包的位置。它没有迁到 NAS,也不是系统 Python。
fal_client 最终在 worker2 装到 .venv/lib/python3.14/site-packages/fal_client 第一次装到 /home/ubuntu/.local/lib/python3.10/site-packages,DH 仍失败。因为 worker 用 Python 3.14 `.venv`。
subtitle /opt 从 magi3 只读复制到 worker2:/opt/tobatsu/venvs/subtitle-effect-renderer//opt/tobatsu/assets/subtitle-fonts/ 第一次字幕任务失败,原因是 worker2 没有这些 hook/font。补齐后通过。
managed-skills managed-skills/catalog 改成 worker 可写。 最初 root-only 导致 smoke 写 skill cache 失败。V11.0a 明确改规则:worker runtime materialization 需要写 catalog。
Node / pnpm / PM2 worker2 校验 Node 22.22.2、pnpm 10.33.4、PM2 7.0.1。 用于 Admin/Web build、脚本和 supervisor,不依赖系统默认。
Codex home CODEX_HOME=/mnt/tobatsu-cfs/tobatsu/hosts/magi-worker2/codex-home Ask/Continue session 可以走 NAS-backed per-host context,restart 后仍能 resume。
Claude home ~/.claude -> /mnt/tobatsu-cfs/tobatsu/shared/claude-home.claude.json 同步到 NAS。 Claude auth/context 能被 worker2 使用;直接 Claude NAS smoke 产生新 session 文件,证明写入走 NAS。
!
后续建议:.venvnode_modules 目前仍是每台机器本地环境。V11 把 worker2 补到可运行;长期要做依赖同步/镜像化,避免以后每台新机器手工补 Python 包、系统包、字体和 hook。
where are the venvs?
actual independent venvs on worker2 2 个:repo `.venv` + subtitle renderer venv
repo worker venv /home/ubuntu/workspace/fp/tobatsu/.venv (149M,每台机器本地,不在 NAS)
subtitle renderer venv /opt/tobatsu/venvs/subtitle-effect-renderer/ (17M,worker2 从 magi3 补齐)
not a venv /home/ubuntu/.local/lib/python3.10/site-packages/fal_client (user-site,第一次装错的位置)
correct Fal package location /home/ubuntu/workspace/fp/tobatsu/.venv/lib/python3.14/site-packages/fal_client (worker 实际使用)
why it looks like many `bin/`、`include/`、`lib/`、`site-packages/`、`pysubs2/`、`pip/` 是同一个 venv 里的子目录/包,不是新的 venv

5. 技能迁移:到底改了什么,没改什么

这块容易混。V11 迁移技能,核心不是重写 skill 业务逻辑,而是让同一套 skill 能在 worker2 + NAS 上被找到、解包、缓存、调用、产出。

对比项迁移前V11 后是否改业务逻辑
skill source 源 workflow / shared skill 仍按 repo 和 DB registry 管理。 worker2 使用同一批源,临时复制成 *_ignis alias 只为隔离测试。 没有
runtime cache 技能 materialize/cache 更偏本机路径。 worker2 走 NAS 的 /mnt/tobatsu-cfs/tobatsu/managed-skillscatalog 没有
catalog permission 最初按共享只读资产设计,worker 写不进去。 managed-skills/catalog 改成 worker 可写,因为运行时要下载/解包 skill。 没有
workflow alias 真实 workflow 直接在原 queue 上跑,比如 mai 测试用 alias 改到 mai-ignis,hidden/admin-only,测完 soft-delete。源 workflow 不动。 没有
host deps magi3 上已有字体、hook、provider 包。 worker2 补齐 subtitle /opt、字体、fal_client、ffmpeg、Node/pnpm/PM2。 没有
agent context Codex/Claude context 主要在机器本地。 worker2 的 Codex home 和 Claude home 迁到 NAS 路径。 没有
UA rule Mai delivery 外部 HTTP 请求没有统一浏览器 UA 规则。 v106 单独改了 mai-platform-delivery skill 文本并发布 DB skill v6。 有,属于 v106
承载改变

从“本机散落”到“NAS 可复用”

缓存、workspaces、runs、Codex/Claude context 往 NAS 靠,目标是新 worker 不再从零补一堆状态。

权限改变

catalog 必须能写

skill 不是只读文件。运行时会 materialize、下载、解包,所以 worker 要能写 catalog。

内容改变很少

业务规则基本没动

V11 没重写 FFmpeg、字幕、PIP、DH。真正改 skill 文本的是 v106 的外部 HTTP UA 规则。

我是怎么保证“不改技能”的做法
不直接改原 workflowgeneric_ffmpeg_rendisubtitle_burn_invideo_pip_composedigital_human_omnihuman 保留。
复制临时 alias只复制出 *_ignis,把 queue 指到 mai-ignis,并设成 hidden/admin-only。
保持 engine_profilealias 仍是 codex-default,不是借测试偷偷切 Claude。
测完清理4 个 *_ignis alias 全部 soft-delete;源 workflow readback 保持存在。
真正文本改动另算v106 的 UA 规则是单独 skill 文本改动:mai-platform-delivery v6。
migration summary
changed skill cache path, catalog write rule, alias queue, host dependencies, Codex/Claude context location
unchanged original workflow business prompt/body, provider choice, production template default engine
separate v106 UA rule changed mai-platform-delivery text and published DB skill v6

6. 后续规范:可以复制技能,但要在 NAS 上受控兼容

用户方向是对的:以后不要每台机器本地各攒一套。允许复制技能做兼容,但复制出来的东西要有位置、有名字、有生命周期,最后回到发布版本。

层级以后怎么放规则
skill source repo 仍是最终源头。 正式改动必须回 repo、走 review、发 revision。不能把 NAS 临时目录当长期源码。
compat staging 允许在 NAS 上建兼容区,比如 /mnt/tobatsu-cfs/tobatsu/skill-staging/<skill>/<date>/ 用于新机器兼容、补依赖、跑 smoke。必须记录来源 sha、操作者、用途、清理条件。
managed runtime managed-skills/catalog 继续作为运行时缓存。 worker 可以写 materialized cache,但不在这里手工开发业务逻辑。
dependencies 系统包、字体、/opt/tobatsu、provider 包用 bootstrap/sync 脚本补齐。 不能靠“这台机器我手动装过”当交付状态。
venv 短期每台机器本地建;长期可以评估 NAS wheelhouse / prebuilt venv tarball。 不直接共享 live `.venv` 给多台机器并发写。要共享也共享只读构建产物。
promotion 兼容通过后发布新 revision 或确认复用现有 revision。 worker 最终消费发布版本,不消费“某个临时拷贝目录”。
可以复制

复制是兼容手段

比如 subtitle 的 `/opt` runtime、字体、临时 skill staging,都可以先复制到 NAS 或 worker2 兼容。

不能漂移

复制不能变成野生版本

每个拷贝都要知道从哪个 sha 来、为什么拷、什么时候删、最终对应哪个发布 revision。

目标

以后新 worker 只做三步

挂 NAS,跑 bootstrap,同步/验证 skill staging,然后启动 worker smoke。

future standard
allowed copy skill/runtime to NAS staging for compatibility work
required source sha + manifest + smoke + cleanup/promotion rule
forbidden undocumented per-host manual edits that never return to repo/registry
goal new worker = mount NAS + run bootstrap + pass smoke, not hand-patch machine

7. 4 个 Mai/Ignis workflow 的真实验证

这四个不是只创建任务。每个都走 worker2、队列、engine_profile、provider/skill、输出、HEAD 或 callback 检查。

WorkflowTask / Run验证内容结果
generic_ffmpeg_rendi_ignis task 0de5716c
run 6c774773
Rendi 主路径、FFmpeg 输出、R2/CDN、mock callback update/result 200。 PASS
subtitle_burn_in_ignis task 7a9fcf1f
run 3c293dc1
subtitle-burn-rendi v14,Mode B,1080x1920,59.2s,视频/ASS/render bundle HEAD 200。 PASS
video_pip_compose_ignis task 48d790f0
run 7c8be735
pip-compose-rendi v5,1080x1920,59.21s,circle PIP 366x366,输出 HEAD 200。 PASS
digital_human_omnihuman_ignis task 728878a5
run 6cb71e94
fal.bytedance.omnihuman.v1.5,832x1120,10.12s,mp4 HEAD 200,4.75MB。 PASS

失败后修复的东西

  • e13b33b5 暴露 managed-skills catalog 写权限问题。
  • 9ddb25c5 暴露 worker2 缺 subtitle /opt/fonts。
  • e5215ae5 / b4cd3053 暴露 DH 依赖装错 Python 层。
  • 这些失败都保留为证据,没有直接抹掉。

每个 smoke 的共同验收

  • 都由 magi-worker2:mai-ignis claim。
  • 都有 engine_profile 五个关键字段。
  • 运行结果是 done/success/exit 0
  • 输出或回调路径有可核验证据。

8. Ask / Continue / Restart Recovery

这块专门验证“拿到 session 后能继续”,不是每次都 fork。验证对象是 worker2 的 NAS-backed Codex home。

场景关键证据结论
Ask turn 1fork_status=forked,source prefix 019e6c61,ask prefix 019e6c9c首次 fork 正常
Ask turn 2inquiry_mode=codex_cli_resumefork_status=resumed,ask prefix 仍是 019e6c9c没有 refork
Continuechild 09385502 / run d816d977resume_of_run_id=3c293dc1source preserved
PM2 restart 后 Ask turn 3appserver/worker/task_inquiry pids changed,Ask 仍 fork_status=resumed,prefix 仍 019e6c9crestart 后可恢复

9. 扩容到生产级 30

用户要求 mai-ignis 工作完成后可以加到生产级。最后不是一次拉满,而是 1→2→10→20→30,每步观察。

scale path 1 -> 2 -> 10 -> 20 -> 30
final magi-worker2:mai-ignis desired=30 online=30 busy=0 queued=0 running=0 capacity=ok fork=30/30
note runtime_pressure=true was accepted as capacity warning, not failure, because queue/backlog/capacity stayed clean
cleanup temporary aliases deleted after smoke; worker topology unchanged

10. 11B: Claude engine + Admin 切换能力

这个不是“把 agent.kind 改成 claude”。V11 把 Claude 接成 managed engine profile,并且把选择结果冻结到 task/run 上。

Claude smoke

task c026b9f6 / run 8e38229b

实际引擎 actual_engine=claude,版本 v11-engine-profile-1:claude-default,由 magi-worker2:mai-ignis claim。

Codex rollback smoke

task f79f6660 / run fa47e70f

切回 actual_engine=codex,版本 v10-engine-profile-1:codex-default,同样在 worker2 上成功。

机制结果
Admin 保存后生效workflow override 保存后新任务读取新 engine;不需要重新建 workflow revision。
旧任务冻结task/task_run 上存 engine_profile_at_create,Continue/Ask/retry 不读 live override。
Capability block不支持 Claude resume 的 workflow 会 409 engine_override_capability_blocked,不会写坏 override。
清理临时 canary workflow 删除,override 删除,flag 关闭,BFF/FastAPI source readback 404。

11. 中途发现并修掉的真实问题

这些不是额外发挥,是 V11 做到能上线必须处理的问题。

DB migration

0036 低锁改造

hot columns 改为 nullable/no-default,reader 把 NULL 和 {} 都当 absent,减少锁表风险。

pooler timeout

migration timeout 安全化

加 lock_timeout / statement_timeout,并修 SQL literal 安全校验,避免注入或错误 timeout SQL。

idle-in-tx

cancel polling 短 session

worker/scheduler cancel polling 之前会留下 idle-in-transaction 读锁,改成短 session 并回滚关闭。

host auth

Claude auth sync

worker2 第一次 Claude 失败是 host 配置差异,补 auth 后通过,不是 selector 代码错。

NAS Claude home

Claude context 共享

用户确认 claim 模型串行后,worker2 的完整 Claude home 移到 NAS。

worker status

fork flicker 降噪

probe_stale 不再显示成红色 fork unavailable,后端/BFF stale 阈值统一放宽。

12. 默认行为没有被改掉

UNCHANGED existing production templates default to codex-default
UNCHANGED no global “all Claude” switch
UNCHANGED no Material Board production template was moved to Claude
UNCHANGED old tasks keep frozen engine/workflow/session state
CLEANED temporary worker2 canary workflow and *_ignis aliases deleted/soft-deleted
DEFERRED cloud memory 11C explicitly cancelled by user

13. 证据和提交链

报告的事实来自 repo 审计文档和 cc readback。下面是主要可核点。

审计文档

  • docs/v11-slice-11a-audit.md:worker2 / NAS / smoke / scale。
  • docs/v11-slice-11b-audit.md:Claude engine / Admin switch / migration。
  • docs/tobatsu-goal-v11.0.md:V11 scope 和 11C deferral。
  • docs/v11-goal-delivery-report.md:repo 版交付摘要。

关键 commit

  • 0143024 11A audit。
  • 4eeb8e7 Claude engine profile foundation。
  • a72f0bf Admin override controls。
  • 242ae07 cancel polling idle-in-tx fix。
  • 2dee307 11B audit。
  • 92687d3 fork-flicker fix + delivery report。
验收项状态说明
worker2 新机器PASSNAS mount、repo/env、appserver、worker、task_inquiry。
4 个 workflowPASSgeneric、subtitle、PIP、OmniHuman 全部 done/success。
Ask resumePASSturn 2 和 restart 后 turn 3 都 resume,不 refork。
ContinuePASSchild 成功,source invariance 保持。
scale 30PASSmai-ignis 30/30,clean reads 通过。
Claude enginePASSClaude smoke + Codex rollback smoke。
Admin switchPASSdefault-off、override cleanup、旧任务冻结。
Cloud memoryDEFERRED用户明确不要做,V11 不包含。

14. 剩余事项

后续

依赖同步/镜像化

把 `.venv`、Node deps、系统包、字体、hook 做成可重复同步,不靠手工补。

后续

magi3 是否迁 NAS

这是单独迁移,不属于 V11 已完成 worker2 scope。需要停服窗口和独立计划。

后续

Cloud memory 新 scope

如果以后要做,重新开 scope,不继承 V11 许可。