Files
makelore/.project-docs/10-decisions/proposals/20260822-pi-runtime-spec-b6e2c9a4__pi-runtime-cutover-tickets.md
T

1143 lines
57 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.
# ML-CODE-PI-001 实施票据与依赖图
## 0. 文档信息
| 字段 | 值 |
| --- | --- |
| 关联 Spec | `ML-CODE-PI-001` |
| 状态 | 实施中;`PI-000` Done with explicit waivers |
| Task | `20260822-pi-runtime-spec-b6e2c9a4` |
| `PI-000` 实施基线 | `2bc423ebc58589307442ebdaf1c81d83ec9dc2d5`(`feat: qualify Pi runtime cutover foundation`) |
| 目标 | 把完整硬切换拆成可验证、无循环依赖的执行图 |
| 当前 Ready Frontier | `PI-010`, `PI-020`, `PI-030`(`PI-000` 已 Done with explicit waivers) |
| Phase-0 macOS | **Explicitly Waived / Deferred by user on 2026-08-22**;不是 Pass,实际验收移至 `PI-150` |
| 真实 Provider | `QG-004`/`QG-005` **Explicitly Waived / Accepted Risk by user on 2026-08-22**;不是 Pass,也不再阻断 release |
本文中的“票据”是仓库内实施单元,不代表已经创建 GitHub Issue、分支、PR 或子智能体。后续执行者可以把票据同步到外部 issue tracker,但票据 ID、依赖和验收语义必须保持。
## 0.1 当前规划状态(2026-08-22)
| 字段 | 当前判断 |
| --- | --- |
| `PI-000` 实施任务 | `20260822-pi-runtime-qualification-c52e8a14`;commit `2bc423e`;`ready_for_integration` |
| `PI-000` 状态 | Done with explicit waivers;不是全部 QG Pass |
| 规划 frontier | `PI-010`, `PI-020`, `PI-030`;其余票据继续按 31 条依赖边锁定 |
| `PI-010` 交接 | `20260822-pi-conversation-contracts-a61d9c42`;基线 `2bc423e`;当前 `planning` |
| 资格证据 | `.project-docs/50-evidence/topics/20260822-pi-runtime-qualification-c52e8a14__pi-runtime-qualification.md` |
已确认事实:
- `PI-000` 已作为 commit
`2bc423ebc58589307442ebdaf1c81d83ec9dc2d5` 提交;实施工作树干净,任务登记为
`ready_for_integration`。`PI-010` 已在该 commit 上建立独立工作树并进入
`planning`;这不改变依赖已满足的 Ready Frontier 定义。
- 精确候选 pin 为 `@earendil-works/pi-coding-agent@0.84.2`;上游 tag
`v0.84.2`、npm `gitHead` 与 commit 均为
`914cf1472e715297caa30db4b9535d534a9eb718`。
- Windows x64 的 workspace、临时 production closure,以及独立受控 Electron
Builder `dir`/`app.asar` probe 均可通过 `ELECTRON_RUN_AS_NODE=1` 启动 Pi
RPC。受控 artifact 使用 `MakelorePiProbe.exe` 和
`resources/app.asar/dist/cli.js`,刻意不继承 Makelore 正式
`electron-builder.yml` 的 OpenCode/Python/UV/signing/install hooks,也没有
改动最终产品打包 wiring。
- 受控 artifact 可定位 Pi 0.84.2、CLI、130 个 Windows 适用 production
packages、9 个按平台跳过项和 6 个 runtime WASM/native assets;`.node`
位于 `app.asar.unpacked`。Electron Builder 把同版本
`@types/retry@0.12.0` 从 `p-retry` nested layout 扁平化到 root
`node_modules`,属于可解析布局变化,不是依赖丢失。
- 受控 packaged artifact 的 5 cold / 5 warm 样本分别为:cold
p50/p95/max 668/682/682 ms,warm 660/663/663 ms;10 个 RSS 样本
138404/141320/141320 KiB;exit 16/18/18 ms。session/reopen、
deterministic failure、local shell overlap、单侧 abort isolation、stdin
close 均通过,结束后没有 artifact 或 Pi RPC 残留进程。
- packaged runtime 上的 `127.0.0.1` HTTP/SSE 合同 probe 已覆盖
`openai-completions`、`openai-responses`、`anthropic-messages`、`openrouter`。
每种协议恰好产生 4 个 POST,验证 base URL/path、环境凭据 header、custom
header、model、PNG image、双 worker 成功 settled、turn 重叠、单侧 abort
与另一侧成功以及 stdin-close;最终收紧重跑的重叠时间依次为
304/309/290/297 ms。
- Anthropic 配置使用 Provider root,由 SDK 追加 `/v1/messages`;OpenAI 风格
base URL 以 `/v1` 结尾,再追加 `chat/completions` 或 `responses`。该差异应
进入后续 Provider catalog fixture,而不能对四种协议统一拼接路径。
- 最终 focused suite 为 9 tests;scoped ESLint、typecheck、`build:vite`、
`git diff --check` 和 project-doc drift gate 已通过。
- Linux x64 在 WSL2 Ubuntu 24.04、kernel
`6.6.87.2-microsoft-standard-WSL2` 中取得 workspace、staged production
closure 与 controlled Electron Builder `dir/app.asar` 三层证据。隔离快照以
Node 22.22.2 和仓库 pin `pnpm@10.33.4` frozen install,运行 seam 为
Electron 43.4.0 与 embedded Node 24.18.1。
- Linux workspace 5 cold / 5 warm:cold p50/p95/max 426/853/853 ms,warm
432/437/437 ms,RSS p95 170388 KiB,exit p95 8 ms。staged closure:cold
426/428/428 ms,warm 423/440/440 ms,RSS p95 175956 KiB,exit p95 8 ms。
- Linux controlled `dir/app.asar`:cold 526/545/545 ms,warm 545/569/569
ms,RSS p95 181928 KiB,exit p95 7 ms;131 个 Linux 适用 package、8 个
platform skip、6 个 runtime asset 和 unpacked native assets 均无缺失,只有
与 Windows 相同的同版本 `@types/retry@0.12.0` flattening。
- Linux packaged 四协议 loopback 每种恰好 4 个 POST,路径、鉴权头、自定义
header、model、PNG image、双 worker overlap、单侧 abort isolation 与清理
均通过;overlap 依次为 292/290/277/288 ms,结束后无 artifact/Pi RPC
残留进程。Linux 报告代码也已移除运行时仍硬编码“Linux missing”的字段,
改为 cross-platform aggregate requirement;7 tests、scoped ESLint、
typecheck 和 1-sample integration probe 通过。
- macOS 实跑前发现并修复一个真实 packaged-closure path defect:旧 inspector
在 artifact 内用 `dirname(process.execPath)/resources` 推导资源目录;macOS
executable 位于 `<app>/Contents/MacOS/MakelorePiProbe`,旧逻辑会错误读取
`Contents/MacOS/resources/app.asar`,实际路径是
`Contents/Resources/app.asar`。
- 修复后由外层 platform-aware `packagedResourcesDirectory()` 只计算一次资源
目录,并通过 `PI_PROBE_RESOURCES_DIRECTORY` 传入 artifact process;closure
inspector 不再二次推导。focused test 已覆盖 darwin executable →
`Contents/Resources`。
- 修复后的 Windows controlled packaged actual regression 以 1 cold / 1 warm
样本通过,ready 为 650/641 ms;130 个适用 package、6 个 runtime asset 与
unpacked native asset 均无缺失,证明显式资源目录传递没有破坏 Windows。
这只验证修法和 Windows 回归,不是 macOS 运行证据。
未验证但由用户于 2026-08-22 明确接受、且不再阻断 `PI-000` 或 release 的风险:
- 四协议 loopback 只证明 Pi request serialization、SSE parsing、图片/header/
model/credential plumbing、worker 重叠与 abort 隔离。它没有发起外部请求或
产生费用,也不证明任何真实 Provider Account、认证、proxy、rate-limit 或
provider-specific response variance;四协议真实 endpoint/account/credential/
successful settled/concurrency/abort/reopen/image-where-supported 样本仍缺失。
- 用户明确接受真实认证/endpoint/proxy/rate-limit/provider-specific response
variation,base URL/header/environment credential/model/image 的真实协议兼容,
真实 provider 并发或串行/限流,以及跨 worker abort/event/session/model/
credential 隔离风险。`QG-004`、`QG-005` 因此标记为 **Explicitly Waived /
Accepted Risk**,不是 Pass;所有资格/发布报告继续保留
`realTurnVerified: false`。
用户明确豁免并延期的 Phase-0 项(不是 Pass,也不再阻断 `PI-000`):
- 用户于 2026-08-22 决定跳过 `PI-000` 的 macOS 实跑。macOS x64 与 macOS
arm64 标记为 **Explicitly Waived / Deferred by user**;workspace、staged
production closure、controlled packaged seam、packaged loopback、资源和
metrics 全部移至 `PI-150`。
- darwin 资源路径 preflight defect 已修并有静态测试,但两个架构都尚未实际
运行,所以不得标记 macOS Pass。延后可能使 packaging/native/resource/
performance defect 到 release stage 才暴露并造成返工;这是用户接受的风险,
不是已消除风险。
范围限定和后续约束:
- 当前 Linux 证据来自真实 Ubuntu 24.04 x64 用户空间、Linux executable/native
selection、asar layout 和 process seam,但 kernel 为 WSL2 且 artifact 是
controlled Builder `dir`。正式 Spec 的 `QG-002` 只明确要求 Linux packaged
app,没有额外要求 non-WSL kernel、native compositor、AppImage 或 deb,
因此这些不是新增的 `PI-000` blocker;若它们属于最终发行格式,仍必须在
`PI-150` 以实际 release artifact 验收。
- 已发布包的 shrinkwrap 是 production-only,但 package root 仍列出 10 个
devDependencies;npm 11 的直接 `ci --omit=dev` 会在 omit 前因不同步失败。
当前资格 probe 只在临时副本移除该字段后复用原 shrinkwrap。`PI-030`
必须把永久 staging 处理定义为显式、可复现的实现与验收项,不能把临时
workaround 当成最终打包已通过。
- `PI-150` 的 macOS handoff 要求 x64/arm64 各使用独立 checkout、对应架构
Node/Electron download 与 frozen install,依次运行 workspace 5+5、staged
5+5、controlled packaged 5+5、packaged loopback、closure/native/resource
检查和 metrics,再验证最终目标 artifact;不得跨架构复用 `node_modules`
或 artifact。`PI-000` waiver 不得在 `PI-150` 被当作证据。
- 当前执行环境没有仓库 CI definition、macOS runner/SSH host、GitLab runner
CLI 或 Provider credential environment variable。internal GitLab remote 只能
提供源码远端,不能生成真实 Provider 证据,也不能提前补齐 `PI-150` 延期的
macOS 证据;前者已由用户接受为非阻断风险,后者仍将在 release stage 阻断
`PI-150`。
当前 QG 状态(编号严格以 `ML-CODE-PI-001` 第 8.1 节为准;实施证据中的
task-local 状态表不是规范编号来源):
| Gate | 状态 | 规划解释 |
| --- | --- | --- |
| `QG-001` | Pass | 精确 identity、pin、engine、CLI 已确认 |
| `QG-002` | Pass | 修订后的 Phase-0 平台范围为 Windows x64 + Linux x64;两者 packaged qualification artifact 的 spawn/RPC/session/prompt/abort/settle/reopen/exit 已通过。macOS x64/arm64 Explicitly Waived / Deferred,不是 Pass |
| `QG-003` | Pass | 修订后的 Phase-0 平台范围内,Windows/Linux controlled qualification artifact 的完整适用 package、WASM/native asset 可解析;最终产品 artifact 与 macOS 实跑留在 `PI-150` |
| `QG-004` | Explicitly Waived / Accepted Risk | 不是 Pass。Windows/Linux packaged 四协议 loopback 合同通过且 `realTurnVerified=false`;真实 Account/auth/endpoint/proxy/rate-limit/response variance 与真实 base URL/header/environment credential/model/image 兼容未验证,由用户接受风险 |
| `QG-005` | Explicitly Waived / Accepted Risk | 不是 Pass。provider-shaped loopback two-worker overlap/单侧 abort 通过;真实 provider 并发或串行/限流及跨 worker abort/event/session/model/credential 隔离未验证,由用户接受风险 |
| `QG-006` | Pass | 修订后的 Phase-0 平台范围内,Windows/Linux cold/warm/RSS/exit 的 p50/p95/max 与样本数已报告;macOS metrics Explicitly Waived / Deferred 到 `PI-150`,不是 Pass |
| `QG-007` | Pending / 未触发 | 尚无已确认失败;只有未豁免的 packaging/provider-shaped contract/concurrency/abort/预算门确认失败才触发 utility-process SDK 修订。用户 waiver 不是失败 |
规划判断:逐项审计 `PI-000` Required work、Acceptance 与 Stop condition 后,
所有未豁免要求均已有证据且没有已确认失败。macOS Phase-0 明确 deferred 到
`PI-150`;`QG-004`/`QG-005` 明确 Accepted Risk;两类均不是 Pass。`QG-007`
保持 Pending / not triggered。因此 `PI-000` 标记为 **Done with explicit
waivers**。按未修改的 DAG 重新计算,精确新 Ready Frontier 是 `PI-010`、
`PI-020`、`PI-030`。真实外部 Provider 不再是 `PI-000`/`PI-150`/release
blocker;macOS x64/arm64 在 `PI-150` 仍是不可豁免的 release blocker。若未来
任何未豁免的 packaging、provider-shaped contract/concurrency/abort 或预算门
出现确认失败,继续按 Stop condition 修订为 SDK-in-Electron-utility-process;
仍禁止 OpenCode fallback 或 RPC/SDK 双生产路径。
## 1. 执行规则
1. 所有产品代码票据属于同一个 OpenCode → Pi 硬切换 release unit。中间提交可以存在新旧源码,但任何部分不得以双 runtime 形式发布。
2. `PI-000` 是阻断式资格门;当前已 Done with explicit waivers。任何历史或未来执行中,它未完成前仍不得开始会制造迁移成本的产品实现;本图将所有实施票据显式依赖它。
3. 只有依赖全部 `Done` 的票据才进入 Ready Frontier。依赖不满足时,不得以“先写一点”绕过。
4. 每张票据只拥有其“主要文件/责任区”。共享文件必须由依赖更靠前的票据定义合同,后续票据按合同消费;需要改变合同必须先更新上游测试和关联 Spec。
5. 一张票据只有在自身 acceptance 和 verification 全部通过后才能标 `Done`。仅编译、仅单测、仅人工体验均不充分。
6. `PI-000`~`PI-150` 构成一个实施分支/PR 的完整代码范围;不得把未删除 OpenCode 的中间状态合入 release。
7. `PI-160` 是终端 Integration/Release Gate。它在实现 PR 完成后执行最终审阅、集成、canonical promotion 和发布阻断检查。
8. 本票据图不要求任何特定协作方式。当前文档任务按用户要求不创建子智能体;未来执行也必须遵守当时用户和仓库并发所有权规则。
## 2. 依赖图
```mermaid
flowchart TD
P000[PI-000 Runtime qualification gate]
P010[PI-010 Conversation contracts & reducer]
P020[PI-020 Schema v2 & migration]
P030[PI-030 Pi process/RPC foundation]
P040[PI-040 Provider & managed resources]
P050[PI-050 Worker pool & session registry]
P060[PI-060 Event projector & hydration]
P070[PI-070 Extension host, interactions & lease]
P080[PI-080 Subagent scheduler]
P090[PI-090 Product tools & change tracker]
P100[PI-100 Core /api/coding Host API]
P105[PI-105 Files/changes/skills Host API]
P110[PI-110 Renderer protocol store]
P120[PI-120 Core Chat & first-Conversation UX]
P130[PI-130 Feature-complete Coding UI]
P140[PI-140 OpenCode removal & cutover migration]
P150[PI-150 Packaging, E2E & performance release proof]
P160[PI-160 Integration and release gate]
P000 --> P010
P000 --> P020
P000 --> P030
P020 --> P040
P030 --> P040
P010 --> P050
P020 --> P050
P030 --> P050
P040 --> P050
P010 --> P060
P050 --> P060
P060 --> P070
P040 --> P070
P070 --> P080
P070 --> P090
P020 --> P090
P020 --> P100
P060 --> P100
P070 --> P100
P020 --> P105
P090 --> P105
P010 --> P110
P100 --> P110
P110 --> P120
P080 --> P130
P090 --> P130
P105 --> P130
P120 --> P130
P130 --> P140
P140 --> P150
P150 --> P160
```
## 3. 票据总览
| ID | 标题 | Depends on | 主要责任区 | 完成后解锁 |
| --- | --- | --- | --- | --- |
| `PI-000` | Runtime qualification gate | — | 精确版本、packaged probe、Provider/并发/RSS 证据 | `010`, `020`, `030` |
| `PI-010` | Conversation contracts & reducer | `000` | shared contracts、fixtures、in-memory runtime | `050`, `060`, `110` |
| `PI-020` | Schema v2 & migration | `000` | `coding-projects`、project/conversation schema、backup | `040`, `050`, `090`, `100`, `105` |
| `PI-030` | Pi process/RPC foundation | `000` | bundler、worker process、LF framer、RPC client | `040`, `050` |
| `PI-040` | Provider & managed resources | `020`, `030` | provider catalog、secret、prompt/skill/resource loader | `050`, `070` |
| `PI-050` | Worker pool & session registry | `010`, `020`, `030`, `040` | runtime、pool、registry、lifecycle、telemetry base | `060` |
| `PI-060` | Event projector & hydration | `010`, `050` | live assembly、active leaf、snapshot/reconcile/recover | `070`, `100` |
| `PI-070` | Extension host, interactions & lease | `040`, `060` | managed extension bridge、ask_user、write lease | `080`, `090`, `100` |
| `PI-080` | Subagent scheduler | `070` | `subagent.v1`、child process、caps、abort | `130` |
| `PI-090` | Product tools & change tracker | `020`, `070` | browser/game/task/changed-file/skills、change tracker | `105`, `130` |
| `PI-100` | Core `/api/coding` Host API | `020`, `060`, `070` | project/conversation routes、SSE、interactions | `110` |
| `PI-105` | Files/changes/skills Host API | `020`, `090` | file/search/change/skill routes | `130` |
| `PI-110` | Renderer protocol store | `010`, `100` | typed facade、per-Conversation store、snapshot/patch | `120` |
| `PI-120` | Core Chat & first-Conversation UX | `110` | Composer、timeline、optimistic prompt、render batching | `130` |
| `PI-130` | Feature-complete Coding UI | `080`, `090`, `105`, `120` | model/thinking/queue/compaction/interactions/subagents/changes | `140` |
| `PI-140` | OpenCode removal & cutover migration | `130` | 删除旧 runtime/routes/deps/UI/tests/resources、migration notice | `150` |
| `PI-150` | Packaging, E2E & performance proof | `140` | artifact、real smoke、full E2E、Windows/Linux/macOS x64+arm64、perf report | `160` |
| `PI-160` | Integration and release gate | `150` | final review、zero residue、canonical docs、release decision | Release |
## 4. Ready Frontier 演进
下面是依赖完成后的预期 frontier,不是必须串行执行的阶段清单:
| 条件 | 新 Ready Frontier |
| --- | --- |
| 初始,以及 `PI-000` 完成前 | `PI-000`(唯一 frontier;未 Done,无下游解锁) |
| 2026-08-22 `PI-000` Done with explicit waivers | `PI-010`, `PI-020`, `PI-030` |
| `PI-020` + `PI-030` Done | `PI-040`(同时等待中的 `PI-010` 可继续) |
| `PI-010` + `PI-020` + `PI-030` + `PI-040` Done | `PI-050` |
| `PI-050` Done | `PI-060` |
| `PI-060` Done | `PI-070`;`PI-100` 仍等 `PI-070` |
| `PI-070` Done | `PI-080`, `PI-090`, `PI-100` |
| `PI-090` Done | `PI-105` |
| `PI-100` Done | `PI-110` |
| `PI-110` Done | `PI-120` |
| `PI-080` + `PI-090` + `PI-105` + `PI-120` Done | `PI-130` |
| `PI-130` Done | `PI-140` |
| `PI-140` Done | `PI-150` |
| `PI-150` Done | `PI-160` |
## 5. 票据详情
## PI-000 — Runtime qualification gate
### Objective
在写业务迁移前,证明选定 Pi 版本能在 Makelore qualification 打包边界中满足 runtime、四协议 packaged loopback/provider-shaped 并发、资源和退出要求;对明确未验证的真实外部 Provider 风险作出显式人类决定,确认失败时尽早终止错误架构。
### Dependencies
- None。
### Current planning status
- **Done with explicit waivers**;实施任务为
`20260822-pi-runtime-qualification-c52e8a14`。这不是全部 QG Pass。
- Windows x64 与 WSL2 Linux x64 的 workspace/staged/controlled packaged RPC、
session、process、closure、loopback 四协议合同与预算证据通过;受控 artifact
不是最终 bundler 或 release installer。
- 用户于 2026-08-22 将 macOS x64/arm64 明确标记为 **Explicitly Waived /
Deferred** for `PI-000`。packaged resource path defect 已修并通过 focused path
test 与 Windows actual regression,但 macOS 没有实跑、不是 Pass;workspace/
staged/controlled packaged/loopback/metrics 全部移交 `PI-150`。
- 用户于 2026-08-22 明确接受四协议真实 Provider Account/兼容与真实双 worker
并发/隔离风险,`QG-004`、`QG-005` 为 Explicitly Waived / Accepted Risk,
不是 Pass。loopback 不得被归类为 Provider Account qualification,报告保持
`realTurnVerified=false`。
- Linux 最终 release artifact 与 macOS 全套实跑属于 `PI-150`;macOS 仍是
release blocker。当前 `PI-000` 无剩余 Phase-0 blocker,已解锁 `PI-010`、
`PI-020`、`PI-030`。
### Owns
- 精确 Pi version/tag/commit 决策。
- 最小 package pin 与 lockfile 变更。
- 最小 `scripts/probe-pi-runtime.*`、临时/受控 packaged probe、结果报告。
- 资格证据,不拥有最终 Chat、Host route 或迁移实现。
### Required work
1. 复核候选 `@earendil-works/pi-coding-agent@0.84.2`;锁定确切 package version、CLI entry、Node engine、RPC/session docs 对应 tag/commit。
2. 以 Electron Node 在 Phase-0 平台范围 Windows x64、Linux x64 的 unpackaged 与 packaged qualification seam 启动 RPC。
3. 验证 `get_state`、persistent session create/open、prompt accepted、abort、`agent_settled`、reopen、clean shutdown。
4. 从 frozen dependency graph stage Windows x64、Linux x64 的最小完整 production closure,验证 packaged qualification artifact 的 WASM/native/optional resources;最终产品 artifact 留给 `PI-150`。
5. 用 Windows/Linux packaged loopback 覆盖所有受支持协议的 base URL/path、headers、environment credential plumbing、模型、图片 request/SSE 合同;记录真实外部 Provider Account 验证已 Explicitly Waived / Accepted Risk,`realTurnVerified=false`。
6. 两个独立 worker 同时运行 provider-shaped loopback turn,证明受控时间窗口重叠、单侧 abort 与另一侧 settled;记录真实 provider 并发/串行/限流及跨 worker abort/event/session/model/credential 隔离为 Accepted Risk。
7. 在 Windows x64、Linux x64 运行 cold/warm/RSS/exit samples,报告 p50/p95/max、样本数、平台和 artifact 状态。
8. 明确 `AGENTS.md`/context、offline、trust、resource discovery、shell 的锁定版本行为。
macOS x64/arm64 在本票据中 Explicitly Waived / Deferred by user on
2026-08-22;这不是平台通过证据。对应 workspace/staged/controlled packaged/
loopback/metrics 工作由 `PI-150` 接管。
### Closure audit(2026-08-22)
| Required work | 审计状态 | 依据 |
| --- | --- | --- |
| 1. identity/pin/engine/entry | Pass | Pi 0.84.2、tag/commit、CLI、Electron Node engine 与 frozen lockfile 已确认 |
| 2. platform process seam | Pass + explicit macOS deferral | Windows x64 与 Linux x64 workspace/staged/controlled packaged 已通过;macOS x64/arm64 不是 Pass,转 `PI-150` |
| 3. session/RPC lifecycle | Pass | get_state、create/open、prompt accepted、abort、settled、reopen、clean shutdown 已通过 |
| 4. production closure/assets | Pass | Windows/Linux 适用 packages、WASM/native/optional assets 在 qualification artifact 可解析;最终 artifact 留 `PI-150` |
| 5. protocol compatibility | Explicitly Waived / Accepted Risk;替代 smoke Pass | 四协议 packaged loopback 的 base URL/path/header/environment credential plumbing/model/image request/SSE 已通过;真实外部 Provider 未验证且 `realTurnVerified=false` |
| 6. two-worker concurrency/isolation | Explicitly Waived / Accepted Risk;替代 smoke Pass | provider-shaped two-worker overlap、单侧 abort、另一侧 settled 与受控路由已通过;真实 provider 行为未验证 |
| 7. latency/RSS/exit budgets | Pass | Windows/Linux cold/warm/RSS/exit 样本与 p50/p95/max 已记录并满足预算 |
| 8. context/offline/trust/resources/shell | Pass | 锁定版本以 explicit no-discovery/no-context/no-approve/offline flags 运行,shell 与 abort 行为已验证 |
审计未发现除上述两类显式 waiver 外的未完成 Required work。Acceptance 的
非豁免证据均成立,Stop condition 没有已确认失败,因此 `QG-007` 不触发。
### Acceptance
- Spec `QG-001`、`QG-002`、`QG-003`、`QG-006` 在修订后的 Phase-0 平台范围内有可重复证据;`QG-004`、`QG-005` 有明确人类 waiver、完整风险记录和不可误标 Pass 的证据状态。
- cold `rpc.ready` p95 ≤ 3,000 ms;warm p95 ≤ 1,500 ms;10 秒 operational deadline 内确定性失败。
- 两 worker packaged provider-shaped loopback turn 重叠;一个 worker abort/crash 不改变另一个受控状态。真实外部 Provider turn 不属于 hard gate。
- 完整 dependency closure 从 Windows/Linux packaged qualification artifact resolve,退出无遗留 Pi child;最终产品 artifact closure 属于 `PI-150`。
- Packaged loopback matrix 覆盖当前实际支持的每种协议类型;真实外部 Account 兼容保持 `realTurnVerified=false` 和 Accepted Risk,不 silently fallback 或伪报 Pass。
- 精确 pin,不使用 `^`/`~`。
- macOS waiver 只允许 `PI-000` 不等待该平台,既不构成 macOS Pass,也不满足 `PI-150` 的 cross-platform acceptance。
- `QG-004`/`QG-005` waiver 只移除真实外部 Provider hard gate;Windows/Linux 及最终 artifact 的 packaged loopback/provider-shaped overlap/abort smoke 仍必须通过。
### Stop condition
若修订后 Phase-0 范围内未豁免的 packaging、provider-shaped contract/concurrency/abort 或预算不通过:本票据保持或重新进入 Blocked,停止后续实现。只能通过修订 Spec/ADR 选择“Pi SDK in Electron utility process”后重新验收;不得引入 OpenCode fallback 或 RPC/SDK 双生产路径。缺少已豁免的真实外部 Provider 样本不是失败,不触发 `QG-007`。延期的 macOS 验证若在 `PI-150` 失败,则必须阻断 release 并返工或修订架构,不得以本 waiver 放行。
### Verification
- Probe command 和结果可以在干净安装依赖后重跑。
- artifact dependency resolve verifier。
- 两 worker packaged provider-shaped loopback overlap/abort smoke;结果明确 `realTurnVerified=false`。
- process-tree clean-exit 检查。
## PI-010 — Conversation contracts and reducer
### Objective
先固化 vendor-neutral Conversation 领域协议,使 Main、Renderer 和测试不再围绕 OpenCode/Pi wire 结构耦合。
### Dependencies
- `PI-000`。
### Owns
- `electron/coding-runtime/contracts.ts` 或 shared 等价位置。
- `ConversationSnapshot`、`ConversationPatchEnvelope`、node/run/queue/context/interaction/model/error DTO。
- 统一 normalization reducer。
- `InMemoryConversationRuntime`。
- 锁定 Pi 版本的 wire fixture → product fixture 边界定义。
### Required work
1. 实现 Spec 第 5、10 节全部公开类型,公共 export 不导入 Pi/OpenCode。
2. reducer 支持 snapshot replace、严格 generation/seq、gap invalidation、message/block/tool/queue/interaction/compaction/subagent/context ops。
3. UI ID 与 durable source ID 分离;optimistic user node 通过 `clientRequestId` reconcile。
4. 用同一个 reducer 处理 live fixture 和 hydrated fixture。
5. 实现 in-memory runtime,供 Renderer/Host product tests 使用。
6. 明确 unknown op/schema 的 fail-closed 行为。
### Acceptance
- 混合 text/thinking/tool、parallel tools、tool error、retry、compaction willRetry、queue、interaction、subagent、unknown custom fixture 全通过。
- seq gap 只 invalidates 目标 Conversation;旧 generation patch 被丢弃。
- `toolResult` 不成为 message;cumulative tool output 不重复。
- `agent_end` fixture 不产生 idle;`agent_settled` 才产生 idle。
- Renderer contract test 没有任何 Pi/OpenCode import。
### Verification
- Focused contract/reducer unit tests。
- Type-level no-vendor import check 或 scoped `rg` assertion。
- Snapshot → patches → snapshot equivalence fixture。
## PI-020 — Project and Conversation schema v2 migration
### Objective
把项目/伙伴/Conversation 产品数据从 OpenCode runtime identity 中解耦,并保证一次性迁移可回退、不会误删用户数据。
### Dependencies
- `PI-000`。
### Owns
- `electron/coding-projects/project-config.ts`。
- `project-store.ts`、`conversation-store.ts`、migration/backup helpers。
- schema v2 types/tests。
- 项目、伙伴、空 Conversation 的 local-only create flow。
### Required work
1. 定义 project schema v2 `ProductModelRef` 和 model unresolved 状态。
2. 定义 Conversation schema v2、产品 UUID、optional Pi binding、opaque sessionKey。
3. 实现 schema v1 backup → model mapping → v2 atomic write。
4. 无唯一 model mapping 时保留 Agent,标记用户选择;禁止默认模型。
5. v1 Conversation metadata 备份后初始化空 v2,不将旧 OpenCode Session 放入 sidebar。
6. 只清理已证明未修改的 generated `.opencode/agent`;uncertain/modified 移到 backup。
7. project/partner/Conversation create 不调用 runtime。
### Acceptance
- stable Agent ID/name/prompt/skills/archive 完整保持。
- 无 backup 时绝不覆写 v1;任意写失败保留可重试原状态。
- `sessionKey` path traversal/absolute path 被拒绝。
- 两个并发首发只建立一个 Pi session binding(通过 store single-flight contract fixture;实际 runtime 在后续票据接入)。
- 旧 Conversation 不显示;一次性 notice 状态可被 UI 后续消费。
- userData/opencode 和不确定 `.opencode` 内容未被递归删除。
- 项目、伙伴、Conversation metadata 性能可单独测量,且无 child process。
### Verification
- Migration table tests:unique/unresolved/no-account/corrupt write/retry/modified Agent file。
- Atomic persistence tests。
- Local-create integration test with spawn spy = 0。
## PI-030 — Pi process and RPC foundation
### Objective
提供可打包、可测试、可恢复的 Pi child process/RPC 底座,不掺入项目 CRUD 或 Renderer 逻辑。
### Dependencies
- `PI-000`。
### Owns
- `electron/coding-runtime/pi/worker-process.ts`。
- `rpc-framer.ts`、`rpc-client.ts`、process errors。
- 初版 `scripts/bundle-pi-runtime.mjs` 与 runtime manifest。
- programmable fake Pi child test fixture。
### Required work
1. Electron Node + `ELECTRON_RUN_AS_NODE=1` 启动锁定 Pi entry。
2. 显式 offline/no-approve/no-auto-resource 参数;stdout RPC only、stderr log only。
3. 自有 strict LF framer,支持 chunk 边界和 U+2028/U+2029。
4. command ID correlation、out-of-order response、event dispatch、timeout/AbortSignal。
5. malformed/oversized stdout、unexpected exit、stderr sanitizer、backpressure。
6. process graceful shutdown 3 秒 + forced kill,确保整个 child tree 清理。
7. stage 完整 production closure 与 manifest。
8. 为已发布 Pi package 的 production-only shrinkwrap 与 root 10 个
devDependencies 不同步选择并测试一个显式、可复现的永久 staging 机制;
不把 `PI-000` 临时副本处理或受控 Electron Builder probe 直接当成最终
bundler。artifact verifier 按可解析 package/version/asset 验证 closure,
不把 Electron Builder 的同版本依赖扁平化误判为缺失。
### Acceptance
- Spec `RPC-001`~`RPC-005` 全部通过。
- stdout 任意非 JSONL 导致目标 worker protocol error,不污染其他 worker。
- pending command 在 exit/abort/generation invalidation 时全部 settle,无 promise leak。
- prompt 类 command timeout 不自动重发。
- fake child 可脚本化输出 response/event/crash/partial line/large line,供后续 Main integration 使用。
- bundler 在 frozen install 上确定性生成相同 manifest 内容(不要求额外 checksum 文件)。
- 永久 staging 能在 npm 11 下从发布 package/shrinkwrap 可重复生成 production
closure,且测试覆盖 root devDependencies 不同步与同版本 nested-to-root
flattening;不依赖开发机已有 `node_modules` 或受控 probe 的临时目录。
### Verification
- Focused process/RPC unit tests。
- Real Pi `get_state` protocol smoke。
- Packaged entry load/exit smoke。
## PI-040 — Provider and managed resources
### Objective
把当前 Provider Account、Works gateway、credential、伙伴 prompt 和 skills 映射为锁定 Pi 版本的受管输入,同时保持 Main-owned secret/trust 边界。
### Dependencies
- `PI-020`。
- `PI-030`。
### Owns
- `electron/coding-runtime/pi/provider-config.ts`。
- `resource-loader.ts`、prompt/Agent manifest cache。
- `resources/coding-skills` 与 registry 映射。
- Provider revision/staleness contract。
### Required work
1. 实现 `PiProviderDescriptor` 和 account → runtime catalog 投影。
2. 迁移 Works `/v1`、proxy token、custom header/base URL 语义。
3. credential 只通过 worker environment/受管 provider 注入,完整日志脱敏。
4. account refresh single-flight;认证恢复最多一次。
5. provider/resource revision:idle stale 下次 prompt 前重建,running settled 后重建。
6. 生成受管伙伴 prompt/Agent manifest,不生成 `.pi/agents`。
7. 移动内建 skills 到 vendor-neutral resources,仅显式传 selected paths。
### Acceptance
- 当前支持的每种 Provider Account/协议配置 fixture 都能构建有效 catalog,并通过
packaged provider-shaped loopback 完成 prompt/settled;真实外部 Provider prompt
保持可选、非阻断,未取得证据时 `realTurnVerified=false`。
- 两个同 vendor account 的 runtime ID 不冲突。
- model/image capability 校验准确;不可用模型原子失败。
- token/header/prompt 内容不出现在 argv、snapshot、SSE、Renderer、diagnostics 或 test snapshot。
- 项目/用户 `.pi` resources 不被自动加载。
- provider revision 不打断 running run;settled 后才重建。
### Verification
- Provider catalog fixtures。
- Secret-redaction tests over argv/env-safe projection/stderr/API DTO。
- Resource discovery negative tests。
- Packaged provider-shaped loopback smoke from qualification matrix;可选 real account
smoke 只能作为非阻断诊断,不得把 waiver 改写为 Pass。
## PI-050 — Worker pool and session registry
### Objective
实现一 Conversation 一 worker 的真实并发、session 持久绑定、资源调度和生命周期隔离。
### Dependencies
- `PI-010`。
- `PI-020`。
- `PI-030`。
- `PI-040`。
### Owns
- `electron/coding-runtime/pi/runtime.ts`。
- `worker-pool.ts`、session registry、permit queue、idle LRU。
- prepare/prompt/queue/abort/model/thinking/compact/fork/dispose lifecycle orchestration。
- telemetry base/span correlation。
### Required work
1. per-Conversation `prepare` single-flight 和 lazy session open/create。
2. worker state machine、generation、pending commands/interactions/children references。
3. top-level running cap 4、warm idle cap 4、total process soft cap integration。
4. running 不 eviction,idle LRU,app quit shutdown。
5. prompt/steer/follow-up acceptance,不等待 settle。
6. abort/model/thinking/compact/fork/recover/dispose 目标隔离。
7. Provider/resource stale 在安全边界重建。
8. `worker.queue_wait/spawn/rpc.ready/session.open/resources.ready/prompt.accepted` telemetry。
### Acceptance
- 一 worker 永不并行承载两个 Conversation。
- 第 5 个 top-level run 进入自己的 queue;前四个 settled 后按公平顺序继续。
- running worker 不被 LRU kill;idle 超限准确 eviction/reopen。
- crash generation 清理 pending RPC/permit/interaction/child reference,并不影响其他 worker。
- prompt HTTP/RPC acceptance 与 run completion 分离。
- model/thinking 只改变目标 Conversation;不可用模型不改变旧状态。
- app quit 3 秒后无遗留 parent worker。
### Verification
- Worker-pool focused tests:single-flight、caps、fair queue、LRU、crash、quit、stale revision。
- Two-worker fake + packaged provider-shaped loopback concurrent run integration;真实外部 Provider 非阻断且不得写成已验证。
- Process-tree cleanup test。
## PI-060 — Event projector, hydration, and recovery
### Objective
把 Pi live RPC 和 persisted session tree 正确投影为 Makelore Snapshot/Patch,解决 streaming identity、active branch、settled reconciliation 和恢复。
### Dependencies
- `PI-010`。
- `PI-050`。
### Owns
- `event-projector.ts`。
- `session-projector.ts`。
- attachment projection hooks。
- snapshot creation、durable reconcile、recover orchestration integration。
### Required work
1. 按 `contentIndex` 组装 text/thinking/toolcall;`message_end` 权威替换。
2. cumulative `partialResult` replace;`toolResult` attach tool card。
3. run/turn/retry/compaction/queue/interaction/usage/context 映射。
4. `agent_end` checkpoint、`agent_settled` idle。
5. entries + leafId + parentId active path hydration;废弃分支排除。
6. live UI ID 与 durable entry ID reconcile。
7. generation/seq envelope、gap invalidation、snapshot rebuild。
8. unknown/custom bounded diagnostics、large image attachment ref。
9. recover:旧 generation close、资源清理、reopen、hydrate、新 snapshot。
### Acceptance
- Spec 第 10、11、18 节 event/session/failure 规则全部有 fixture。
- live run 完成后的 Snapshot 与从 session 冷 hydrate 的 Snapshot 等价。
- compaction `willRetry` 不 idle;queue continuation 不提前释放 permit。
- abandoned branch 永不进入 active timeline。
- tool partial output 不重复;camel-case `toolResult` 不变 assistant。
- SSE gap/recover 只替换目标 Conversation。
- unreadable session 保留原文件并进入 recoverable error,不自动截断。
### Verification
- Projector/session unit fixtures from exact Pi version。
- Fake Pi end-to-end run → settle → reopen comparison。
- Small real Pi drift smoke。
## PI-070 — Managed extension host, interactions, and write lease
### Objective
建立唯一受管 extension entry、最小 child→Main seam、用户 interaction 和同项目 mutation lease。
### Dependencies
- `PI-040`。
- `PI-060`。
### Owns
- `extensions/makelore-runtime.ts`。
- extension internal endpoint/IPC bridge 与 worker token registry。
- `interaction.ts`、`write-lease.ts`。
- interaction Host-side store and projector integration。
### Required work
1. 只显式加载一个 versioned extension bundle。
2. 每 worker loopback/IPC token,dispose/recover 后失效。
3. 验证 conversationId/generation/runId 与 worker registry。
4. `ask_user` select/confirm/input/editor;notify/status/widget/title/editor-text 安全投影。
5. 同项目 mutation write lease、可取消等待、所有终态释放。
6. worker crash/abort 清理 interaction/lease。
7. unknown UI/widget/details 只诊断,不 raw dump。
### Acceptance
- 项目/用户第三方 Pi extension 不会被加载。
- 伪造旧 generation/token 的 request 被拒绝且不影响当前 worker。
- interaction response 严格按 ID;crash/abort 后全部 cancelled。
- 同项目 mutation 串行;不同项目并行;read-only 不等待 lease。
- complete/error/abort/timeout/crash 全部释放 lease,无永久占用。
- Textarea draft revision 已变化时 `set_editor_text` 不覆盖。
### Verification
- Extension integration tests through real bridge, not direct function-only mocks。
- Lease concurrency/cancellation matrix。
- Interaction lifecycle and stale-token tests。
## PI-080 — Subagent scheduler and nested protocol
### Objective
用 Makelore-owned `subagent.v1` 实现多 child Pi 调度,不依赖官方示例的非稳定 GUI details。
### Dependencies
- `PI-070`。
### Owns
- `extensions/subagent.ts`。
- child process supervisor、global semaphore、parent-child registry。
- `subagent.v1` schema/projector fixtures。
### Required work
1. `single`、`parallel`、`chain` dispatch validation;单次最多 8 tasks。
2. 每 child 独立 Pi process/context,使用受管 Agent manifest/model/tool profile。
3. 全应用最多 4 running child,和 parent process 组成 soft cap 8。
4. read-only/coding tool profile;coding child 接入 write lease。
5. parent abort/crash 传播 child;child exit 清理 permit。
6. parallel 保留其他完成结果;chain 首失败停止并标 skipped。
7. nested progress/details 只输出 `subagent.v1`。
### Acceptance
- 1、4、8 tasks 的 single/parallel/chain fixture 正确;第 9 个 schema validation 拒绝。
- 两个 parent 争用全局 child semaphore 时总 running child ≤ 4。
- parent abort 后无 child orphan;permit 全释放。
- 一个 parallel child failure 不删除其他 summary/usage;chain 后续标 skipped。
- unknown schema/version 不崩 UI、不 dump raw JSON。
- 同项目 coding child 与 parent mutation 遵守同一 lease。
### Verification
- Fake child scheduler integration tests。
- One real subagent child packaged smoke。
- Process-tree and semaphore leak check。
## PI-090 — Product tools and Conversation change tracker
### Objective
迁移 Makelore 真实使用的 browser、game asset、task/changed-file 和 skill 能力,并以 Main-owned tracker 替代 OpenCode Session diff。
### Dependencies
- `PI-020`。
- `PI-070`。
### Owns
- `extensions/agent-browser.ts`、`game-assets.ts`、`task-state.ts`、`changed-file.ts`。
- `electron/coding-projects/skill-registry.ts`。
- `conversation-change-tracker.ts`。
- Main browser/attachment integration at the existing seam。
### Required work
1. `agent_browser` extension 直连现有 Main browser service;删除对 MCP 的运行时依赖。
2. 迁移现有 game asset browse/review 产品语义,不复制 OpenCode plugin API。
3. `task_state` 使用版本化 typed details;不暴露旧 todos endpoint。
4. `changed_file` 上报 relative touched paths。
5. run start 记录 git head/status baseline;settled 后刷新 status/diff,bash 触发 project-level refresh。
6. 只读 changed path diff;untracked 有界 preview;无 per-file hash/checkpoint。
7. selected skills registry 与 command catalog 安全投影。
### Acceptance
- browser tool 不启动 `@playwright/mcp`/MCP child,screenshot 使用 attachment ID。
- game asset/product tool 有 real/fake integration coverage。
- changes panel 数据不来自 Pi message 文本猜测。
- write/edit touched path 精准刷新;bash 后能发现未上报改动。
- untracked preview 有界且无绝对路径。
- fork UI 不暗示文件回滚。
- 没有为 diff 增加 hash/checkpoint framework。
### Verification
- Browser/game tool packaged smoke。
- Git/no-git/dirty/untracked/bash change tracker tests。
- Skill command and explicit-path tests。
## PI-100 — Core `/api/coding` Host API
### Objective
用产品域 Host API 连接 project/conversation service、runtime Snapshot/Patch 和 interactions,完全移除 Renderer 对 OpenCode route contract 的依赖。
### Dependencies
- `PI-020`。
- `PI-060`。
- `PI-070`。
### Owns
- `electron/api/routes/coding-projects.ts`。
- `electron/api/routes/coding-conversations.ts`。
- `/api/coding/events` SSE。
- interactions route、runtime diagnostics 安全投影。
- Renderer typed facade 的 Main contract half。
### Required work
1. 实现 Spec 第 12.1 节除 files/skills/changes 外的核心 routes。
2. prompt/steer/follow-up 返回 HTTP 202 acceptance;不等待 settle。
3. `clientRequestId` bounded dedupe 与 uncertain request 行为。
4. SSE envelope、per-Conversation seq/generation、snapshot-first reconnect。
5. request validation、conversation/project ownership、sanitized errors。
6. diagnostics 只给 worker state/revision/stage summary,无 secret/absolute session path。
7. interactions list/respond ID correlation。
### Acceptance
- Renderer-facing core route 中不出现 `/api/opencode` 或 Pi wire field。
- project/partner/Conversation create route 不启动 runtime。
- prompt 202 在 provider first token/settled 前返回。
- seq gap test 只 GET 目标 snapshot;SSE reconnect 不重发 prompt。
- duplicate accepted `clientRequestId` 返回相同 acceptance;uncertain mutation 不二次发送。
- raw stderr/provider/extension path/credential 不穿透。
### Verification
- Route contract tests with in-memory and fake Pi runtime。
- Host API → SSE → snapshot integration。
- Error redaction and timeout tests。
## PI-105 — Files, changes, skills, and command Host API
### Objective
提供 vendor-neutral project file、search、changes、skills 和 command API,使 Renderer 不再依赖 OpenCode 的文件/Session diff/todo 路由。
### Dependencies
- `PI-020`。
- `PI-090`。
### Owns
- `electron/api/routes/coding-files.ts`。
- file/status/find/content/search facade。
- Conversation changes、skills、commands route integration。
- Renderer typed facade 的 file/tool catalog contract half。
### Required work
1. 迁移现有受支持 file status/find/content/search 行为到 product service。
2. 所有 path 相对 active project,保持现有内容/搜索边界。
3. expose Conversation changes snapshot,不 expose Pi/session diff。
4. 合并 Pi extension/skill commands 与 Makelore commands,稳定 DTO。
5. 删除 todos/revert/unrevert/share 相关 API 外形。
### Acceptance
- Renderer 无绝对项目路径和任意 filesystem proxy 能力。
- files/search 行为与现有受支持 UX 等价。
- changes 与 target Conversation/run 关联,数据来自 tracker。
- skills/commands 只包含显式受管资源。
- route/type/test 中无旧 todos/share/revert contract。
### Verification
- Focused file/search/change/command route tests。
- Path boundary and redaction tests。
- Renderer facade contract tests。
## PI-110 — Renderer Snapshot/Patch store
### Objective
建立按 Conversation 分片、可 gap recovery、无 vendor import 的 Renderer 状态层和 typed Host facade。
### Dependencies
- `PI-010`。
- `PI-100`。
### Owns
- `src/stores/coding-conversations.ts`。
- `src/types/coding-conversation.ts` 或 shared re-export。
- `src/lib/coding-conversations.ts`/existing Host API facade integration。
- SSE subscription/reconnect、snapshot loader、draft state。
### Required work
1. 每 Conversation 独立 snapshot/run/error/queue/model/draft/unread/cursor。
2. Snapshot first load + SSE live,generation/seq/gap reducer。
3. hidden Conversation 只更新 lightweight summary。
4. optimistic user node/draft revision/clientRequestId reconciliation。
5. target-only error/recover;top-level error 只用于真实全局错误。
6. Selector 粒度避免 token 时全 store rerender。
### Acceptance
- 两 Conversation simultaneous patch 不串 node/run/error/queue/model/draft。
- seq gap 只刷新目标;旧 generation 丢弃。
- optimistic accept/reject/uncertain state 可恢复 draft/附件。
- hidden Conversation streaming 不触发其 Markdown component render。
- store/facade/types 无 Pi/OpenCode import/name。
- 旧 `src/stores/opencode.ts` 不再被新 UI 读取;实际删除留 `PI-140`。
### Verification
- Store reducer/selector tests。
- Two-Conversation SSE integration。
- Render-count fixture for hidden/current Conversation。
## PI-120 — Core Chat and first-Conversation UX
### Objective
交付 vendor-neutral Chat core,彻底修复首次 Conversation 输入框被全局 runtime/loading 阻塞,并控制流式渲染成本。
### Dependencies
- `PI-110`。
### Owns
- `CodingChatPanel` 核心组合层。
- Composer、message/timeline/tool blocks 的 vendor-neutral components。
- optimistic prompt/recover UI。
- delta batching/attachment preview/render performance。
### Required work
1. Textarea enable rule严格实现 `UX-010`~`UX-014`。
2. create/select Conversation 不等待 runtime;prewarm 仅显示局部状态。
3. first send optimistic node、202 acceptance、preparing/queued/running/error/recover UI。
4. message/thinking/tool/compaction/boundary 基础渲染。
5. 16–33 ms Main batching 的 Renderer局部 block 更新;memo/折叠/虚拟化。
6. attachment ID/preview URL,不持有重复 base64。
7. 组件拆分,避免把旧 4k 行面板机械改名。
### Acceptance
- Runtime/metadata response 被测试故意 hold 时,selected Agent 的 Textarea 仍可输入。
- fresh userData 选择首 Conversation → Composer p95 ≤ 500 ms。
- cold local prepare 超过 10 秒显示 recoverable error,Textarea 仍可编辑。
- prompt accepted 前后 user node不丢;Provider error 不回滚 user message。
- 100 KB cumulative tool/长 thinking 下 Main delta → Renderer commit p95 ≤ 50 ms,输出不重复。
- hidden Conversation 不做全文 Markdown rerender。
### Verification
- Red-capable first-Conversation component test。
- Core Chat focused tests。
- Render commit/IPC payload benchmark fixture。
- First prompt Electron E2E。
## PI-130 — Feature-complete Coding UI
### Objective
在新协议上补齐需要保留的 Code 产品能力和多会话/subagent 交互,使旧 OpenCode UI 可以完整拆除。
### Dependencies
- `PI-080`。
- `PI-090`。
- `PI-105`。
- `PI-120`。
### Owns
- model/thinking controls。
- steer/follow-up queue UI。
- compaction/retry/context UI。
- interactions、subagent nested graph、changes/files/browser/skills/commands UI。
- Conversation fork/title/archive/unread/recover/diagnostics UI。
### Required work
1. model/thinking Conversation setting,与伙伴默认分离。
2. queue 两种 mode、position、等待和 abort。
3. retry/compaction willRetry/settled 正确生命周期。
4. select/confirm/input/editor interactions 与 stale/cancelled 状态。
5. `subagent.v1` nested nodes、parallel/chain error/abort。
6. Conversation changes/file preview、browser attachment、skills/commands。
7. “从这里创建新对话分支”替代 revert 文案,不暗示文件回滚。
8. 删除 share/todo/global runtime controls 的产品入口。
### Acceptance
- 文本、图片、thinking、tools、retry、compaction、queue、interaction、model/thinking、files/changes、browser、skills 全部可在新 UI 使用。
- 两 Conversation 同时 streaming,切换/隐藏/abort/model 互不污染。
- subagent single/parallel/chain nested UI 正确;child error/abort 可理解。
- `agent_end` 不清 busy;`agent_settled` 才释放 queue。
- tool result 不独立 bubble;compaction summary/raw custom details 不泄露。
- share/unshare/revert/unrevert/todos/global runtime controls UI 不存在。
### Verification
- Focused UI tests for every retained/removed behavior。
- Electron E2E:concurrency、model、queue、compaction、interaction、subagent、image、browser/skill、recover。
## PI-140 — OpenCode removal and cutover migration
### Objective
在新链路达到 feature completeness 后,删除所有生产 OpenCode 源码、依赖、route、资源、脚本和旧 UI,并接通最终一次性迁移/提示。
### Dependencies
- `PI-130`。
### Owns
- 删除 `electron/opencode`、OpenCode route/manager/client/materialization/provider/plugin code。
- 删除/重命名 `src/*opencode*`、`shared/opencode-*`、旧 tests/E2E。
- package/lockfile OpenCode 与 MCP dependency removal。
- `.opencode` packaged resources、bundle/smoke script removal。
- 迁移 notice、legacy data inert policy、release-facing removed-feature copy。
### Required work
1. 删除 `/api/opencode/*` 与 Renderer 调用。
2. 删除 `opencode-ai`、`@opencode-ai/plugin`、仅服务 OpenCode 的 `@playwright/mcp`。
3. 删除 manager/client/project-agent-runtime/provider-config/playwright-mcp/plugin materialization。
4. 删除旧 store/types/normalizer/panel/runtime controls/diff preview 和浅 Implementation tests。
5. 删除 share/unshare/revert/unrevert/todos/global runtime controls 的 route/type/test/doc copy。
6. 移动保留的 product skills/assets 到 vendor-neutral 资源。
7. 接通 schema migration、一次性 notice、userData inert/no-read。
8. 保持 app id/protocol/storage identifiers。
### Acceptance
- 生产源码/route/dependency/runtime resource 不包含 OpenCode。
- `rg -i` 只命中明确允许的历史/迁移文本,并逐项分类记录。
- package/lockfile 无 OpenCode package/plugin/MCP dependency。
- 新应用不读取项目 `.opencode` 或 `<userData>/opencode`。
- uncertain/modified `.opencode/agent` 被 backup,未误删。
- stable Agent IDs/app id/protocol/storage 保持。
- 全部 Code UI/Host tests 已指向 `/api/coding` 和新 store。
### Verification
- Zero-residue source/package search。
- Migration E2E from schema v1 fixture。
- Full focused Code tests + typecheck/build before `PI-150`。
## PI-150 — Packaging, E2E, and performance release proof
### Objective
把硬切换打成可发布 artifact,运行完整自动化、真实 Pi、三平台和性能验收,产出可审阅证据。
### Dependencies
- `PI-140`。
### Owns
- 最终 `bundle-pi-runtime`、electron-builder staging、artifact verifier。
- `smoke:pi:real`。
- rewritten/new Electron E2E suite。
- performance harness/report、release note/runbook draft、README current product update。
- feature task verification record与 promotion candidates;canonical docs 留 `PI-160` Integration Gate。
### Required work
1. stage exact Pi production closure、extensions、skills、manifest。
2. artifact verifier 检查 version/engine/resources/resolve/get_state/no-OpenCode/no-dev-path。
3. actual packaged Pi smoke:通过受控 loopback/provider-shaped endpoint 覆盖 session、prompt、tool、abort、settle、reopen、two-worker overlap/isolation、subagent、shutdown;不要求真实外部 Provider Account,报告保持 `realTurnVerified=false`。
4. 完整 typecheck/lint/unit/build/E2E。
5. Windows x64、Linux x64 最终产品 artifact 的 packaged verifier/smoke。
6. 对 macOS x64 与 arm64 分别使用独立 checkout/frozen install,运行 workspace 5+5、staged 5+5、controlled packaged 5+5、packaged loopback、closure/native/resource 检查和 metrics,再验证各自最终目标 artifact;不得用静态 path test、其他平台结果或 `PI-000` waiver 替代。
7. Spec 第 17.3 节全部场景,报告 p50/p95/max/samples/RSS/IPC/commit。
8. release note:旧 Conversation、删除能力、完整版本回退、Pi 新 Conversation 不兼容旧版。
9. README 同步当前 runtime/功能,不写历史迁移日记。
### Acceptance
- `pnpm run typecheck`、`pnpm run lint:check`、`pnpm test`、`pnpm run build:vite`、`pnpm run test:e2e` 全通过。
- artifact verifier 与 real Pi smoke 全通过。
- 最终 packaged 四协议 loopback、provider-shaped two-worker overlap、单侧 abort 与另一侧 settled 全通过;真实外部 Provider waiver 不是 Pass,也不是 release blocker。
- Windows x64、Linux x64、macOS x64、macOS arm64 目标 artifact 与对应验证全部通过;macOS 任一架构缺失即不允许宣称 cross-platform release-ready。
- `PI-000` 的 macOS Explicitly Waived / Deferred 到本票据即失效;延期造成 release-stage packaging/native/resource/performance 返工的风险已经接受,但任何实际失败仍必须阻断 release。
- Composer、worker、acceptance、render p95 全达 Spec 预算。
- 4 parent + 4 child 压力下 UI 可交互,无 orphan process/permit/lease。
- 最终 artifact 无 OpenCode package/binary/plugin/resource、无开发机绝对路径。
- 性能报告分离本地 overhead 与受控 provider-shaped first-event,不使用一次体验替代统计;可选真实外部 Provider 样本只能作为非阻断诊断。
### Verification
- 保存命令、版本、artifact、平台、样本数和结果摘要到 task evidence。
- macOS x64/arm64 分架构保存 workspace/staged/controlled packaged/loopback/metrics 与最终 artifact 实跑证据;不得只记录 waiver 或静态测试。
- 保存最终 packaged loopback/provider-shaped concurrency/abort 证据并明确 `realTurnVerified=false`;不得因缺少真实外部 Account/credential 把 release 标为 Blocked,也不得把 waiver 写成 Pass。
- 对允许的 `opencode` 搜索命中逐项解释。
- 更新 task record 的验证和未完成外部环境项;任何 release 阻断不得藏在 follow-up。
## PI-160 — Integration and release gate
### Objective
以 Integration Task 所有权完成最终 Spec/Standards 审阅、合并验证、canonical memory 提升和 release go/no-go;不让 feature branch 的自证替代集成事实。
### Dependencies
- `PI-150`。
### Owns
- Integration Task record、merge/rebase conflict handling。
- merge tree 的最终验证与独立 Spec/Standards review。
- accepted ADR、canonical current state/architecture/data flow/domain/success/evidence/commitments 清理。
- release decision、tag/runbook handoff;不自动 push/release,除非用户另行授权。
### Required work
1. 重新运行 Concurrent Task Gate,确认 main/worktree ownership 和最新 base。
2. 集成完整 feature tip,不选择性合并会留下双 runtime 的部分提交。
3. 在 merge tree 重跑风险相称的 focused/full/build/E2E/artifact/real smoke/perf checks。
4. 对照 `ML-CODE-PI-001` 逐条审阅,不以 ticket 自报 Done 代替证据。
5. 新增 accepted ADR:Pi 唯一 runtime、无 OpenCode fallback。
6. 更新 system overview/module map/data flow/business rules/success criteria/current state/README/evidence。
7. 关闭或改写仅对 OpenCode 有意义的 model-switch、dual-session、compaction、saturation commitments。
8. 执行零残留和 release note/rollback runbook 审阅。
### Acceptance
- 全部 Spec requirements 和 DoD 有可追踪证据,无未解释偏离。
- merge tree 与 feature tree 验证一致,无 main 回归。
- accepted ADR 和 canonical docs 描述实际 Pi 架构,不提前声称未跑的 macOS 或已豁免的真实外部 Provider 证据通过。
- accepted ADR、release note 与风险记录明确真实外部 Provider compatibility/concurrency/isolation 是用户接受的未验证风险,不声称 Pass;macOS x64/arm64 仍须有实际发布证据。
- OpenCode commitments 不再伪装为当前待办;需要保留的历史证据仍可追踪。
- 无 runtime fallback/compat layer/old route/dependency/artifact。
- release go/no-go 明确;若任一硬门不通过,状态保持 Blocked,不发布。
### Verification
- Integration Gate scripts、documentation drift gate。
- Final full command suite + artifact/real/runtime/performance evidence review。
- Independent human/reviewer Spec and Standards review;不要求特定智能体机制。
## 6. 票据状态模板
后续若同步为 task/issue,每张票据至少维护:
```text
Status: Pending | Ready | In progress | Blocked | Done
Depends on: <ticket ids>
Owner/worktree: <explicit owner>
Owned files/responsibility: <bounded scope>
Acceptance evidence: <tests, artifacts, measurements>
Contract changes: <none or linked upstream update>
Blockers: <concrete unmet condition>
```
禁止使用“代码基本完成”“看起来正常”“后续再测”作为 Done 证据。阻断项如果属于 Spec 硬门,必须留在当前 ticket,不得降级为 release 后 follow-up。