设计已定(v1 讲的「是什么」)。v2 讲「怎么造」:代码怎么分层、新接缝在哪、测试怎么覆盖、20 张票的依赖顺序和发版顺序。规格 BERTH-2191,子票 BERTH-2192 ~ 2211。
业务逻辑全在 contexts/bot,apps/bot 只装配。容器藏在 ComputerMachine 端口后面:生产实现包住 ctx.container,测试换内存替身。CI 不碰真容器。
flowchart TB
subgraph APPS["apps/bot(装配)"]
O["BotOwner DO
Run · 线程 · 平台额度权威"]
M["BotComputer DO
机器状态 · 并发 · alarm · 结算游标"]
E["出网 Worker 入口
WorkerEntrypoint"]
A["admin 端点
封禁 / 解封"]
end
subgraph CTX["contexts/bot"]
D["domain
工具契约 · 截断 · 单价×运行秒 · 出网判定
启动参数构建器 · 镜像清单 · 批量闸"]
U["application
云电脑用例 · 批量下单写管线"]
P{{"ComputerMachine 端口"}}
end
REAL["生产实现
ctx.container + 镜像仓库 API"]
FAKE["内存替身(/testing 门)
假文件系统 · 脚本化结果 · 注入故障"]
O -- RPC --> M
M --> U
O --> U
U --> D
U --> P
P -. 生产 .-> REAL
P -. "测试(miniflare 专用 binding)" .-> FAKE
E --> D
A --> M
按 CLAUDE.md 落点判据,只列新增 / 改动的模块。
contexts/bot/src/ ├── domain/ │ ├── tools/computer/ # 5 个工具契约 · 事实表 · 错误码 │ ├── tools/hl/ # + hl__place_orders 契约 │ ├── tools/toolFacts # + ToolEffect computer_local │ ├── tools/cardKinds # + computer.artifact │ ├── calculators/ # 截断 · 计费 · 批量闸聚合 │ └── entities/auditEvent # + computer_reset / _banned ├── application/ │ ├── computer/ # 唤醒 · 并发 · 结算 · 上传 · 导出 │ └── write/ # + 批量下单管线 · computerInvolved └── testing/ # + ComputerMachine 内存替身
apps/bot/ ├── wrangler.jsonc # v3 BotComputer · containers · R2 └── src/ ├── computer/ # BotComputer DO · 生产适配器 ├── platform/egress # 出网 Worker · 令牌桶 ├── platform/crons # + computer_spend 聚合 → 熔断 └── routes/ # 产物下载 · 上传 · admin 封禁 apps/server/ # billing 迁移(先发版) apps/web · apps/mobile/ # 内联卡 · 审批卡 · 设置 · 用量
computer__exec("python analyze.py");可见前提是有 bot.computer 权益且来源为 user 2196bash -lc 执行;出网经出网 Worker:HL /info 放行,/exchange 硬拦 2198hl__place_orders([...]) → 整批一个意图,写服务记 computerInvolved 2209 · 2208A–E 是仓库已有的接缝,只新增 ComputerMachine 替身一个。断言外部可观察行为,金额用 BigNumber 字符串比较。
| 接缝 | 测什么 | 主要票 |
|---|---|---|
| A contexts/bot domain 单测 | 截断边界 · 运行秒×单价 · 出网判定 · 启动参数无密钥 · 镜像清单 = description · 批量闸取最严 · cloid / intentHash | 2196 2198 2201 2209 |
| B application 集成(node sqlite + 替身) | 批量下单:意图 → 闸 → 审批 → 重过闸 → 执行 → 逐笔回执;computerInvolved | 2208 2209 |
| C apps/bot vitest-pool-workers | 聊天 Run 全链:可见性 · 污染 · 预算 · 待机 / 重建 / 中断 · 结算幂等 · 熔断 · 重置 / 硬删 · 封禁 · 上传 / 产物 · 出网入口 | 2196–2207 |
| 新 ComputerMachine 内存替身 | 给 C 用:假文件系统、脚本化结果,注入起机超时、中断、磁盘满、snapshot 过期 | 2196 起 |
| D 两壳 BotThreadCard 组件测试 | 终端 / 文件 / 产物卡 · 状态行 · 审批卡来源行与批量表格 | 2196+ · 2210 2211 |
| E *.testnet.test.ts + 人工 QA | hl__place_orders 签名活路径,web / mobile 各验一次 | 2209 |
| staging 冒烟(不进 CI) | 真容器:起机 · 证书 · 出网 · snapshot 往返 · 回滚 | 2192 2196 2198 2199 |
箭头表示「先完成 → 后开工」,加粗边框的是现在就能开工的票。
flowchart LR
S1["2192 Spike
真容器冒烟"]:::now
S2["2193 Spike
DirectoryBackup"]:::now
S3["2194 Spike
混合 perp+spot"]:::now
P1["2195 平台额度改名"]:::now
T14["2209 hl__place_orders"]:::now
T1["2196 exec 曳光弹"]:::core
T2["2197 实时尾部"]
T3["2198 出网 Worker"]
T4["2199 待机与恢复"]
T5["2200 文件工具"]
T6["2201 计量扣额度"]:::bill
T7["2202 熔断"]:::bill
T8["2203 导出产物"]
T9["2204 上传"]
T10["2205 并发+Stop"]
T11["2206 重置+硬删"]
T12["2207 封禁+元数据"]
T13["2208 computerInvolved"]
T15["2210 mobile 卡"]:::mob
T16["2211 mobile 上传+设置"]:::mob
S1 --> T1
T1 --> T2 & T3 & T4 & T5 & T6 & T8 & T10 & T13
S2 --> T4
P1 --> T6 --> T7
T4 --> T9
T4 --> T11
T8 --> T11
T3 --> T12
T2 & T4 & T5 & T8 & T10 --> T15
T9 & T11 --> T16
classDef now stroke:#32d3d6,stroke-width:3px
classDef core fill:#0f3b3c,stroke:#32d3d6
classDef bill stroke:#f5b83d
classDef mob stroke:#8b7cf6
2192 → 2196 → 2199 → 2206 → 2211。真容器冒烟和首片是瓶颈,后面的票大多可以并行。
2195 改名与 2209 批量下单都不依赖云电脑,现在就能并行开工。2194 不挡 ①。
2196 完成后可以同时开 8 张票,适合用 worktree 并行推进。
sequenceDiagram
participant S as apps/server
participant B as apps/bot
participant C as 两壳
S->>S: 2195 迁移 platform_allowance_daily · 2196 新增 bot.computer flag
S-->>B: server 先发(bot 读新权益键)
B->>B: 2196 起:wrangler v3 BotComputer + containers + R2
Note over B: 回滚要另删容器应用和镜像 tag(删 Worker 不连带)
B-->>C: web 卡随各票上线,mobile 由 2210 / 2211 补齐
C->>C: 2209 web / mobile 各自跑 testnet QA 后才上生产
containers:write,旧 OAuth scope 会误报,用空 XDG_CONFIG_HOME 绕开。