v2 · 阶段 ① 已拆票

云电脑阶段 ① 落地方案

设计已定(v1 讲的「是什么」)。v2 讲「怎么造」:代码怎么分层、新接缝在哪、测试怎么覆盖、20 张票的依赖顺序和发版顺序。规格 BERTH-2191,子票 BERTH-2192 ~ 2211。

只给聊天 Run · 终端 / 文件 5 个 computer__* + hl__place_orders 新接缝 1 个:ComputerMachine 现在可开工 5 张

1 · 分层与唯一的新接缝

业务逻辑全在 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

2 · 代码落点

按 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/     # 内联卡 · 审批卡 · 设置 · 用量

3 · 一次调用的链路(标注负责的票)

  1. 模型调 computer__exec("python analyze.py");可见前提是有 bot.computer 权益且来源为 user 2196
  2. BotOwner平台额度 > 0?否 → computer_allowance_exhausted 2201
  3. BotComputer熔断 / 封禁?并发 < 4?待机就唤醒computer_unavailable / computer_busy 2202 · 2207 · 2205 · 2199
  4. 容器bash -lc 执行;出网经出网 Worker:HL /info 放行,/exchange 硬拦 2198
  5. 客户端实时尾部输出推给终端卡,不进模型 2197
  6. BotComputer截断到 16k,完整日志写进工作区;按运行秒结算(区间 id 保证幂等) 2196 · 2200 · 2201
  7. BotOwner结果加 nonce 信封,Run 标记污染 2196
  8. 模型hl__place_orders([...]) → 整批一个意图,写服务记 computerInvolved 2209 · 2208
  9. 用户在表格审批卡上整批批准 → 一个 HL order action,回执逐笔 2209

4 · 测试接缝

A–E 是仓库已有的接缝,只新增 ComputerMachine 替身一个。断言外部可观察行为,金额用 BigNumber 字符串比较。

接缝测什么主要票
A contexts/bot domain 单测截断边界 · 运行秒×单价 · 出网判定 · 启动参数无密钥 · 镜像清单 = description · 批量闸取最严 · cloid / intentHash2196 2198 2201 2209
B application 集成(node sqlite + 替身)批量下单:意图 → 闸 → 审批 → 重过闸 → 执行 → 逐笔回执;computerInvolved2208 2209
C apps/bot vitest-pool-workers聊天 Run 全链:可见性 · 污染 · 预算 · 待机 / 重建 / 中断 · 结算幂等 · 熔断 · 重置 / 硬删 · 封禁 · 上传 / 产物 · 出网入口2196–2207
新 ComputerMachine 内存替身给 C 用:假文件系统、脚本化结果,注入起机超时、中断、磁盘满、snapshot 过期2196 起
D 两壳 BotThreadCard 组件测试终端 / 文件 / 产物卡 · 状态行 · 审批卡来源行与批量表格2196+ · 2210 2211
E *.testnet.test.ts + 人工 QAhl__place_orders 签名活路径,web / mobile 各验一次2209
staging 冒烟(不进 CI)真容器:起机 · 证书 · 出网 · snapshot 往返 · 回滚2192 2196 2198 2199

5 · 票的依赖图

箭头表示「先完成 → 后开工」,加粗边框的是现在就能开工的票。

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
现在可开工 / 首片 计费线 mobile 壳

关键路径

2192 → 2196 → 2199 → 2206 → 2211。真容器冒烟和首片是瓶颈,后面的票大多可以并行。

独立线

2195 改名与 2209 批量下单都不依赖云电脑,现在就能并行开工。2194 不挡 ①。

扇出点

2196 完成后可以同时开 8 张票,适合用 worktree 并行推进。

6 · 发版顺序

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 后才上生产
  

开工须知

  • 设计稿归大佬:带 UI 的票照稿实现前须钉住 canvas artboard,不跑 design-edit;稿子没出时先做结构和行为。
  • 接缝是锁死的:只用 A–E 加 ComputerMachine 替身;实现中要新增接缝,先停下来问。
  • 部署坑:wrangler 部署容器需要 containers:write,旧 OAuth scope 会误报,用空 XDG_CONFIG_HOME 绕开。
  • 待各票定的细节:实时流复用线程连接还是另开 WS(2197)· 令牌桶数值(2198)· admin 端点鉴权(2207)。
  • 完成一张票:勾 AC,写带偏差说明的证据 comment,状态推到 Done,否则后面的票开不了工。