Files
deepseek-harness/missions/tasks/20260719-1902-apiproxy-api-design/README.md
imccyu 0681ac47de chore(gui): mission work logs
chore(gui): mission work logs — cordis design finalization, tool-card wire archive, incident records

chore: missions

chore: missions

chore(gui): mission ledger — batch-2 answers, parallel dispatch state, jsdom coverage re-scope

chore(gui): ledger — night-mode standing orders (self-commit small, no push, 5-min refresh)

chore(gui): ledger — jsdom batches 2-4 landed (233 green), coverage probe next

chore(gui): ledger — web-ui coverage probe 65%, four-tier fill plan approved

chore(gui): ledger — cordis-impl B1 state after third API drop, decisions on file

chore(gui): ledger — 01:32 patrol snapshot (jsdom tier-1 landed, coverage-fixer probed)

chore(gui): ledger — 01:37 patrol (peer src trio landed, coverage-fixer still silent)

chore(gui): ledger — 01:42 patrol (jsdom tier-2 landed, peer committed x2, coverage-fixer 2nd probe)

chore(gui): ledger — coverage diagnosis complete (6-file gap list), web-ui at 91.4%

chore(gui): ledger — 01:46 patrol (B1 done, jsdom tier-3 landed, coverage fix batch running)

chore(gui): ledger — 01:51 patrol (jsdom tails x2 landed, B2 underway)

chore(gui): ledger — 01:56 patrol (gateway.ts 337 lines, checkpoint T-7min)

chore(gui): ledger — hold/pending split ruling, coverage-fixer externalize-or-restart ultimatum

chore(gui): ledger — 02:01 patrol (B2 done, jsdom final arms, coverage ultimatum pending)

chore(gui): ledger — 02:03 checkpoint executed (fixer2 respawn, four lanes released, three owners cold-started)

chore(gui): ledger — all six lanes acked, type isolation first live proof (client closure clean)

chore(gui): ledger — 02:08 patrol (all seven lanes active, wire carrier assembled)

docs(gui): respond-design task checkpoint — apiproxy wire-layer recon done

chore(gui): ledger — P0-2 contributor AGENTS.md landed (dd28a5019)

docs(gui): respond-design checkpoint 2 — host-side recon (stub respond, frame types, approval seam, ACP answerer precedent)

docs(gui): OOP debt inventory — seven territories, 2 real debts (createApiProxy, createFixtureApi), rest ruled keep-as-is

docs(gui): disambiguation note on the archived i18n design task

chore(gui): ledger — 02:12 patrol (exclude removed, mixed-knife incident under reconciliation)

chore(gui): ledger — 02:15 wave (jsdom mission closed, OOP audit done, B3 isolation proof, mixed-knife resolved)

chore(gui): ledger — 02:17 patrol (attribution reversal filed, arch-session probed)

chore(gui): ledger — 02:22 patrol (B4 done, B5+B6 merged batch, arch-session deadline set)

docs(gui): respond-design checkpoint 3 — client-side recon (pending map, PendingCard onRespond stub, AbstractApiClient.respond ready, bootHost missing approval mounts)

docs(gui): peer carrier territory review — 2 fixes (SSE cancel leak, route-reservation guard), 1 ruling ask (RPC-log visibility), compliance ledger

chore(gui): ledger — 02:27 (arch-shell respawn, territory review verdicts routed, ask-deny finding flagged)

docs(gui): P1-5 respond design page complete — pending registry, wire answerer, client state machine, first-wins arbitration

chore(gui): ledger — 02:31 patrol (respond design complete, B5 wire smoke green, shell knife 1 underway)

docs(gui): respond design — add §0 status warning (web host ask defaults to deny), mount-behavior delta, no-timeout ruling with Config discipline

chore(gui): ledger — 02:42 patrol (respond line closed pending review, B7 last piece underway)

docs(gui): respond design contract review — direction pass, 2 doc fixes (settle-order contradiction, answering-state race), A/B/C compliance ledger

docs(gui): respond design — contract review fixes (R1 verify-before-delete arbitration, R2 answering+resolved-frame transition, ask dual-source wording, rejected-is-ok-value note)

chore(gui): ledger — 02:46 patrol (respond line final, two user decisions distilled, arch-shell deadline)

docs(gui): respond review addendum — contract-gap ruling: approve plan A (ApprovalRequest.id), wire unchanged, drop plan B backscan

chore(gui): ledger — cordis B7 summit: real-browser 10/10 green, user acceptance criterion proven

docs(gui): respond design — contract gap #4 approved as plan A (ApprovalRequest.id), backscan fallback retired, blade 0 prepended

docs(gui): respond design — final polish (owner-approval vs user-go-ahead wording, implementation handoff notes)

chore(gui): ledger — 02:51 (shell-exec third respawn with operational script, respond line 4-knife final)

chore(gui): ledger — 02:53 wave (respond five-knife true final, B7 closed 12/12, client.ts green)

chore(gui): ledger — 02:56 patrol (cordis closeout bounced pending R1/R2/N1, shell-exec first sign of life)

chore(gui): ledger — 03:01 patrol (R1/R2/N1 remediation in flight across four files)

chore(gui): ledger — cordis line officially closed and archived, verified on disk (24 knives, 12/12, reviews closed)

chore(gui): ledger — 03:06 patrol (shell-exec final window, lowered first-knife bar)

chore(gui): ledger — 03:11 patrol (shell line iced-broken: three registries on disk)

chore(gui): ledger — 03:15 patrol (quiet window, both active lanes within threshold)

chore(gui): ledger — 03:20 patrol (shell five files up, api-proxy plan reported)

chore(gui): ledger — 03:25 patrol (shell migration in flight with history-preserving moves, webserver green)

chore(gui): ledger — 03:30 patrol (shell knife-1 in verification, api-proxy patching)

chore(gui): ledger — shell knife 1 accepted (694cecc53), knife 2 released

chore(gui): ledger — 03:40 patrol (knife 2 pre-move stage, cold-list spec appears)

chore(gui): ledger — 03:45 patrol (rpclog moves staged, api-proxy two specs in flight)

chore(gui): ledger — 03:54 patrol (knife-2 code done, coverage full-run final check)

docs(gui): coverage-fixer task ledger — fixer2 takeover, per-file fix log, isolated reportsDirectory pitfall

chore(gui): ledger — coverage lane closed and accepted (a19f069a5), the PR #443 CI fix knife

chore(gui): ledger — 04:04 patrol (knife-2 calibration, sole active lane)

chore(gui): ledger — shell knife 2 accepted (f8fb77b95), knife 3 released as final night task

chore(gui): ledger — 04:19 patrol (knife-3 past half: callback chain through, ToolCallDetail up)

chore(gui): ledger — night closeout summary: seven lanes closed, wake-up decision sheet

chore: missions

chore: missions

chore: missions

chore(gui): mission-local browser/probe verify scripts under missions/scripts/

The six acceptance/probe scripts move here as mission-side working
material (headers and relative imports adjusted for the new location):
carrier-errors, rpclog-panel, session, session-real,
webserver-backpressure, webserver-hardening.

chore(gui): verify-relocate mission log

chore(gui): verify-relocate mission log — R1 guard addendum

chore(gui): gates-continue mission log — CI-equivalent sequence all green

chore(gui): VS Code 扩展体系双边设计调研报告

chore(gui): 调研追加 4.5 节——git 扩展数据面与 scope 绑定

docs(gui): web plugin system RFC — walkthrough + design notes

docs(gui): RFC — restore existing SSE/POST as the v1 transport; envelope rides on it (D16)

docs(gui): RFC — envelope demoted to chan-dispatch, scope out of envelope, rpc-log cut, peer deferred, scope tree is native cordis (D17-D21)

docs(gui): RFC — hooks re-derived from component needs: useWatch/useAction only, useService removed; sessionHub cut, projections user-space, router rename, loader-only root (D22-D25)

docs(gui): RFC — drop stale fork vocabulary (vendored cordis has Fiber only; scope = mintScope pattern), hook idempotence contract (D26-D27)

docs(gui): RFC — session precision seam: plugins read scope key (host paradigm), React gets it from tree position via SlotOutlet (D28)

docs(gui): RFC — domain hooks owned by plugins over framework primitives; useConversation paradigm carried over (D29)

docs(gui): RFC — ctx services are the inter-plugin API (cordis proper); declarations are wire-only; get(id) returns scoped ctx (D30)

docs(gui): RFC — full ctx.conversation walkthrough: root-singleton scope-sensitive service, caller-ctx scope key, get(key) as scoped ctx (D31)

docs(gui): RFC — no client-side agents collection: session state machine already expresses the duality; agent resolution stays host authority (D32)

docs(gui): RFC — v1 stays session-precision, no agent-level isolation; incarnation/agent-axis designs archived in ledger (D33)

docs(gui): RFC walkthrough — full rewrite to final state (D16-D33 consolidated), end-to-end chain restored

docs(gui): RFC — apiproxy demoted to generic channel routing; domain RPCs dissolve into owner plugins (D34)

docs(gui): RFC — TS-interface-first wire contract (zod internal), conversation owns the dialogue frame with pluggable views (D35)

docs(gui): RFC — page skeleton (sidebar+conversation), projects as plugin not service, nested slots via owner registries (D36)

docs(gui): RFC — SlotMap declaration-merging slot model: single register API, inject-as-ownership, FC-typed registration, typed outlets (D37)

docs(gui): RFC — slot props whitelist: identity, display params, materialized snapshot slices, stable UI callbacks (D38)

docs(gui): RFC — end-to-end data flow: three transforms, equality protocol table, immer placement; i18n/theme kept standard (D39-D40)

docs(gui): RFC — full external-injection model: props carry values + stable injected hooks; shared/client/react example rewritten (D41-D43)

docs(gui): RFC final trio — modules.md (agent implementation spec), architecture.md (human walkthrough), plugins.md (business plugin inventory)

docs(gui): RFC — props three-source merge (scope-standard useSession auto-injected); keyed key vs list id disambiguated (D44)

docs(gui): RFC — inject comment says what it is (the React-facing props bundle); SessionHandle rename; snapshot-production story unified on buildSnapshot

docs(gui): RFC architecture — full React component tree walkthrough: props three sources, slot vs plain children, hook taxonomy per node

docs(gui): RFC — module map finalized (ui-slots/web-react/connection/runtime/ui-*/web); slots onChange replaced by cordis events; toolcall dimension; detail sidebar default-collapsed with toolName-keyed routing

docs(gui): RFC plugins — openDetail relay chain: toolcard calls chat-view injected action, chat-view relays to conversation sidebar

chore(gui): progress ledger — full archive rewrite: RFC outcome digest, open gaps, dispatch plan, cold-start entry

docs(gui): RFC grill pass 1 — SlotScope axis (root/session) on declares, Gate dependency inversion, inject handle by scope, W5 acceptance list, gantt relay chain fixed

docs(gui): figma analysis — sidebar/projects/sessions 区域交互视觉理解报告

docs(gui): figma 解析报告 — details 面板/多视图 tabs/未来功能区盘点 + slot 需求清单

docs(gui): figma 对话主区解析报告 — 消息流/tool calls 变体/审批接管输入框/Header tabs/视觉 token

docs(gui): plugins.md rewritten from figma analysis — three-column layout, full slot reservation table, selection channel, composer-takeover approvals, phased scope

docs(gui): layout dynamics ruled (drag+collapse both rails, details yields first, composer swap-panel, same-component transition); toolviews promoted to named scope-aware registry

docs(gui): P-I scope locked (details minimal, dual theme, chat-view, custom toolview sample); teammate dispatch plan — 6 owners by package, dependency-driven waves, contract arbitration

docs(gui): P-I api-contracts (full inter-package API spec) + dispatch plan (T0 skeleton knife, 7-dev roster, task briefs, milestones)

docs(gui): api-contracts v2 — scope tree in P-I, bundle loader + per-plugin CSS isolation in P-I, agent-scoped toolviews live, zustand engine, renames (SessionProvider/ObservableSnapshot/SessionBinding), router owns all shell view-state

docs(gui): services roster + progressive loading (no blocking loadAll), SlotsService as real cordis Service, renderSlot/renderSuspenseSlot duo, ui-traj teammate

docs(gui): loading-chain gaps ruled — dev=rebundle no HMR, ui-primitives package, externals on globals (no import map), host injects __DSH_BOOT__ into HTML (zero round-trip)

docs(gui): api-contracts v3 + dispatch v2 final — 12 packages, services merged in, progressive loader, global externals, __DSH_BOOT__ injection, 8-dev roster with convo split and ui-traj

docs(gui): v3 amendments — router renamed ctx.layout, ui-trajectory has no service (pure consumer sample), wait-for-settled loading (no Suspense in P-I, ledger 6b)

chore(gui): progress — pre-compact final state: v3 revision chain, 8-dev roster, T0 procedure, doc authority order

docs(gui): authority banners — modules/architecture get v3 term-mapping headers, walkthrough marked as archived process doc

docs(gui): cssdesign token set is THE theme source (--dsw-* variables, data-ds-dark-theme switch); recorded in contracts + progress

docs(gui): architecture.md full v3 rewrite — loading chain, 12-package map, service roster, slot/inject/toolviews, data flow, component tree, perf model, all current

docs(gui): contracts — UI plugins are dual-entry host plugins (node half serves client asset via ctx.webPlugins; __DSH_BOOT__ derives from it; client-closure gate back in scope)

docs(gui): contracts — closure-factory bundles with DI require (no globals), package.json dshWeb declarative discovery (no serve ritual), create-then-send empty state with project picker, ancestry() for breadcrumb, unload stubbed until HMR, props.renderSlot confirmed

docs(gui): dshClient declaration (inject/platform/immediately, exports./client), closure-DI require loading — synced across contracts/dispatch/modules/architecture/walkthrough

chore(gui): progress — record final loading-chain rulings (dshClient declaration, closure-DI require, startSession) before compact

docs(gui): architecture.md — developer-facing whole-web architecture on master baseline 6b16a67cb: what exists, what is new, no process narrative

docs(gui): architecture.md — self-contained whole-web architecture: absorbs still-valid substance from the branch RFCs (host layering, four-quadrant RPC, object layer, testing tiers) under the new plugin system as the override

chore(gui): progress — final pre-compact snapshot: contracts digest, apiproxy purity ruling, T0 procedure with first-action list

docs(gui): api-contracts v3 §3.1 — apiproxy purity principle with three-way existing-code verdicts

docs(gui): api-contracts v3 — immediately reinterpreted as static-infra group (8-package dshClient scope, boot manifest reconciliation)

docs(gui): api-contracts v3 — immediately corrected to early-load dynamic group (prod shell must not rebundle); loader shell-held; bundles register their export surface into module table

docs(gui): architecture — align with immediately=early-load dynamic group ruling; loader shell-held; module-table registration of loaded bundles

docs(gui): T0 checklist — 12-package skeleton table, 4-cut sequence, mv/attic/rewire rules (pre-drafted, awaiting go)

docs(gui): t0-checklist — pin figma-flows findings (missing font-family base vars, three alias vars behind upstream)

docs(gui): dispatch v2.1 — drop cordis-web salvage wording, two-wave staffing, loader/immediately boundary updates

docs(gui): progress + t0-checklist ledger — T0 landed, staffing status, execution accounting

docs(gui): api-contracts v3 — arbitration round 1: renderBody deps, RootBindingProvider, flush default sync, prune current, loader subpath, config-source P-I bar

docs(gui): v3 §3.2 connection 导出清单附录(rt-core 对账)+ rt-core 实现计划档案

docs(gui): progress — T1 milestone, arbitration round 1 ledger, fw-react timeout escalation

docs(gui): progress rolling update — per-line battlefield state at 00:2x, mailbox-vs-contract lesson, small-batch discipline reinforced

docs(gui): fw-react notes — v3 §2 complete, seven knives, T1/T2 follow-ups

docs(fw-slots): archive — four packages landed, open tails logged

docs(gui): progress — framework layer complete (web-react five, fw-slots four packages), T2 gated on rt-core runtime knife only

docs: api-contracts

docs: style-spec

docs

docs(gui): tsconfig convergence ruling — no host.json, root resumes host-aggregate duty, typecheck = root + client aggregates

docs(gui): missions 根三份 07-18 世代档案加「已被取代」头注——指向 web-plugin-rfc 现行权威并注明新旧对应

missions

docs(gui): progress rewritten for post-closeout state — wave ledger, architecture finale, teammate roster with handover notes, pending-user-command queue
2026-07-22 21:30:30 +08:00

69 lines
12 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.
# apiproxy 统一 API 层设计(step2 协议基础)
任务:定义 apiproxy 对多形态(Web/Electron/TUI)暴露的统一 API 接口层 + web client 的 HTTP/SSE 架构。主会话直写(决策密度高),文档等用户 review。
## 用户拍板记录(2026-07-19)
| 议题 | 结论 |
|---|---|
| 契约权威 | TS interface 权威 + fetch 载体(进程内注入 handler 当 fetch = opencode 同构点) |
| 流形态 | AsyncIterable + AbortSignal |
| 事件面 | 两条 SSE:全 session 一条 mux 聚合 + host 信息一条(沿用旧结论) |
| 接口分组 | 按业务域分文件:`sessions.ts` 一域一文件 |
| 路径映射 | RPC 风格,不考虑 REST 体验 |
| 错误模型 | 类型化 ResultType(不 throw) |
| 校验 | zod 双向校验,**不要 passthrough**;可 dev-only 开启 |
| 事件 payload | 原则透传 core 结构,不自造封装;tool presentation 先透传,文档标注遗留 |
| 历史读取 | 按简单来,不做多套(事件重放 + client 单一 fold) |
| mux 重连 | 不做 since 续传(签名留座),重连=重开流+重拉 history(采纳 opencode 对照建议) |
| 冷 session | attach 状态不对客暴露,只给 running(冷=false);history/prompt 隐式 resume |
| history 分页 | **按消息边界切页**(不从消息中间截断,chunk 随定稿消息归组),参数 maxMessages |
| SessionSummary | v1 不建索引:sessionId + 文件 mtime(updatedAt) + running 三字段 |
| prompt 载荷 | 直接收 core `ContentBlock[]`,不设 text 简化层 |
| schema 文件 | 一域一对:`sessions.ts`(类型)+ `sessions.schema.ts`(zod) |
| subscribed 帧 | 保留 lastSeq 字段(history 补缝竞态检测) |
| SessionListCursor(2026-07-19 20:00) | **不 brand**:v1 未实现占位用裸 `cursor?: string`,实现分页时再定是否 brand |
| HostInfo(2026-07-19 20:02) | 五字段定稿:version/cwd/provider?/model?/attachedSessions;**不设 protocolVersion**(client/host 绑定发布,无跨版本组合;独立发布 client 出现时再引入) |
| RPC 命名体系(2026-07-19 20:15) | ApiResult→**RpcResponse**(方向可辨识:Request 族 / Response 族 / Frame 族);**每方法具名 Request/Response,签名禁内联**;空 request 也具名;流方法 signal 独立第二参不进 Request;HostInfo 并入 HostDescribeResponse;`hostEvents` 方法名改 `host`(对齐 wire 路径 `events.host`,避免 EventsHostEventsRequest 推导怪名) |
| RPC map(2026-07-19 20:30) | 方向拍板:加 RpcMethodMap + ClientRequest\<K\>/ServerResponse\<K\> 泛型索引;`events.host` 改名通过;map key 单复数授权设计层定(定单数 `session.list`,wire 路径同步);形态 A vs B 并排呈案 |
| RPC map 终选(2026-07-19 20:41) | **形态 B:函数签名即事实源**——参数/返回内联在方法签名,RpcMethodMap 登记方法,ClientRequest/ServerResponse/ServerValue infer 反推;「禁内联」放宽为「禁重复内联」;平铺具名 15 类型删除(zod 直接锚派生类型,报错展开代价用户接受);空 request 用 `{}` |
| RpcError 强类型化(2026-07-19 20:56) | **details 走错误码→类型 map**(RpcErrorDetailsMap,与 RpcMethodMap 同构第二张表);RpcError 用 map 展开分布式 union(泛型 interface 默认形式不窄化,弃);**details 必填**(internal 显式 `{}`),「必须真填」纪律升编译期强制;zod 用 discriminatedUnion('code') 逐支锚定 |
| 审批/问答形态(2026-07-19 21:00) | **「unary 对」定案**:请求下行 mux 帧(requested,稳定 id+session 锚)、回答上行 HTTP unary(respond 带 id),不做双向帧;域从不做清单**升格为本轮出协议设计**(实现可排后);细节提案见 core-coverage.md 审批/问答节,随 L1-L7 一并裁决 |
| rpcId + 信封(2026-07-19 21:04) | **所有 unary 指令带 client mint 的 rpcId**(不做只 prompt 带的区分);**wire 两层分离**:RpcRequestEnvelope(rpcId/method/payload) / RpcResponseEnvelope(rpcId/result);ApiProxy 签名不感知信封(载体层统一包/解);method 字段保留(日志自含+path 校验);RpcId brand(首个 client mint id,构造函数照 SessionId 先例);SSE open 不带 rpcId;prompt 的 rpcId 经 MessageSource 透传为 provisional 关联机制(转正执行仍 v1 不做) |
| 整轮裁决(2026-07-19 21:13) | **L1/L2/L5 进契约**(SessionSummary+session-added 帧加 parentSessionId?、SessionSummary 加 cwd?、HostFrame 加 host/agent-error);**L3/L4/L6/L7 类型写全预留**(design §8,不进 map——fail loud 优于 not-implemented 兜底);**审批/问答提案整体采纳**并入正文 §3.4(先到先赢/resolved 收敛/subscribed 基线重放/ApprovalRequestId 复用+QuestionAskId host mint 均按推荐);rpcId≠资源 id 辨析入档;design.md 定稿 v1.5 |
| 问答 id 统一(2026-07-19 21:19) | **取消 QuestionAskId**:问题标识复用 `RpcId` 类型(host 受理 ask 时同一 `RpcId()` mint);RpcId 语义扩为「**交互发起方 mint**」;**审批仍透传 core ApprovalRequestId,有意不对称**(durable 审计事件关联+透传非自造);rpcId≠资源 id 辨析措辞更新(类型统一、语义仍分立) |
| 帧信封对称化(2026-07-19 21:19) | **每条 SSE 帧包 `RpcFrameEnvelope{rpcId, frame}`**,rpcId 由 server 发帧时 mint(标识这一次推送);职责=日志对账+去重/追溯接缝,**不承担 cursor**(续传锚仍是 event.seq);流侧同样签名不感知信封(AsyncIterable\<MuxFrame\> 不变,createApiClient 内拆);信封模型全对称:Request/Response/Frame 三信封 |
| 签名信封化(2026-07-19 21:5x) | **推翻「签名不感知信封」**:ApiProxy 方法签名显式收 `RpcRequest<P>` 封装(rpcId 进签名不进业务 payload);「单次 HTTP 所以 rpcId 不重要」论证被用户否定——rpcId 是逻辑层关联,不因传输自带信道而省略 |
| 四象限消息模型(2026-07-19 22:00–22:1x,v2.0) | **通道与消息彻底解耦**(HTTP=C→S 通道、SSE=S→C 通道,仅此而已);wire 全形=**四具名判别 union**(ClientRequest/ServerResponse/ServerRequest/ClientResponse,22:1x 用户坚持字面四具名,判别子=type 四字面量);**纯推送=不期待应答的 server-request,严格二分不设 notify**(22:1x 用户采纳设计层方案);**respond 重建模为 client-response**:回填 requested 帧 rpcId、不 mint 新 id、不进 RpcMethodMap,wire=POST /api/respond 单端点、HTTP 应答体=RpcReceipt 载体回执;两个 not-pending 错误码删除;泛型工具撞名改 RequestPayload\<K\>/ResponseValue\<K\>;流签名 yield RpcRequest\<帧\>(rpcId 暴露给业务层);流程放宽:文档更新完直接生码不等确认 |
| client 载体类体系(2026-07-20 shape-a + abstract-base,commit 893421d50;本行由 rfc-consolidation 代笔补记——apiproxy-design 静默中,RFC 第二篇写作核码顺手补一致) | **createApiClient 工厂废除,改 AbstractApiClient 抽象基类**:协议不变量(mint/四象限包解/zod/SSE 解帧/超时/rpcId 回显校验)全在基类,平台差异=两切面(抽象 doFetch 传输 + 可覆写 onEnvelope 观测);**IApiClient=caller 视图(shape a)**:unary 收业务 payload 直传、载体 mint、业务代码永不 mint,与 ApiProxy(impl 窄形契约)由基类桥接;**实例级 envelope 观测**:subscribeEnvelopes 批量订阅(微任务合批、异常隔离、无订阅者零成本),旧 onEnvelope 选项+ApiEnvelopeTapEvent 废除,rpcLog 降纯订阅者;子类=InProcessApiClient(同构点新写法)/WebApiClient/FixtureApiClient(协议层覆写虚方法,假信封包装器删除);design.md §4.1/§5 已同步 |
## 文件索引
| 文件 | 内容 |
|---|---|
| `design.md` | API 层设计文档(主产出) |
| `opencode-crosscheck.md` | opencode 调研对照表(同构面验证/CQRS 同向/重连砍 cursor,建议已采纳) |
| `core-coverage.md` | core 能力面 × 契约覆盖度盘点(7 域四态标注 + 漏判清单 L1-L7 已裁决,存档;契约以 design.md 为准) |
## 进展
| 时间 | 事项 |
|---|---|
| 2026-07-19 19:02 | 主会话开写 design.md;核实 core 类型面(SessionEvent/seq/foldSurface/Agent 原语) |
| 2026-07-19 19:06 | design.md v1 落盘:三域接口(sessions/host/events)、ApiResult、fetch 载体映射、client 分层、不做清单、3 个开放问题 |
| 2026-07-19 19:10 | opencode 调研回队;对照写入 opencode-crosscheck.md(同构面/CQRS/无 cursor 重连三判断) |
| 2026-07-19 19:48 | 用户拍板 Q1–Q8;design.md 升 v1.1:重连重建、消息边界分页、ContentBlock 透传、schema 文件对、lastSeq 保留;开放问题清零(时间按 design.md 文件 mtime 推断) |
| 2026-07-19 20:00 | 用户拍板 SessionListCursor 取消 brand;design.md 同步(id 纪律 + §3.1 `cursor?: string`) |
| 2026-07-19 20:02 | 用户拍板 HostInfo 五字段定稿(去 protocolVersion,命名回 version);design.md §3.2 落 interface 全文 + 决策边界注记 |
| 2026-07-19 20:15 | 用户拍板 RPC 命名体系重构;design.md 全文替换:RpcResponse/RpcError(rpc.ts)、11 个具名 Request/Response、Frame 族独立、新增「命名 convention」小节 |
| 2026-07-19 20:30 | 用户三点裁决:key 单复数授权设计层(定单数)、events.host 通过、map 形态待终选;design.md 落「RPC map 两种形态」对比小节(A 类型对 / B 函数签名 infer,五维差异表 + 推荐 A) |
| 2026-07-19 20:41 | 用户终选形态 B;design.md 升 v1.3 分批收尾:map 节改终选结论、§3 三域内联回归签名(删 15 个平铺具名)、convention 改「禁重复内联」、zod 锚 infer 派生、布局落 rpc-map.ts、wire 表 key 对齐 |
| 2026-07-19 20:54 | core-coverage.md 盘点完成(session/agent/subagent/tasks/审批问答/杂项/LLM 七域,file:line 为证);漏判清单 L1-L7:建议进 v1 三条(L1 谱系/L2 cwd/L5 agent-error 帧)、留接缝四条(L3 fork/L4 inject/L6 tasks/L7 provider 枚举),待用户逐条裁决 |
| 2026-07-19 20:56 | 用户拍板 RpcError.details 强类型化,design.md §2 重写(RpcErrorDetailsMap + 分布式 union + details 必填 + zod discriminatedUnion + 扩展路径);rpc-compare 三采纳项落档:details 真填纪律(并入 §2 升编译期强制)、client unary 超时注记(§5)、并发 resume 去重注记(§3.1) |
| 2026-07-19 21:00 | 用户拍板审批/问答「unary 对」形态并升格为本轮出协议;core-coverage.md 落协议提案节(方法/帧、id 纪律、竞争语义、subscribed 基线重放恢复、core 事实对齐六表),补核 user-interaction 无 request 级 id、ask 不落日志两事实;随 L1-L7 待整体修订轮裁决 |
| 2026-07-19 21:04 | 用户拍板全指令 rpcId + 信封两层分离;design.md 升 v1.4(§2 信封类型+纪律、§4 wire 两级 parse、id 纪律 RpcId、convention 二层分离、不做清单改写) |
| 2026-07-19 21:13 | 用户整轮裁决;design.md 定稿 **v1.5**:L1/L2/L5 合入(批1)、审批/问答域并入正文 §3.4+根接口+map+四帧+两错误码(批2)、§8 预留接缝类型 L3/L4/L6/L7(批3)、版头/README/core-coverage 标注(批4) |
| 2026-07-19 21:19 | 用户两条修订并入 v1.5:QuestionAskId 取消(问答 id 复用 RpcId,RpcId 语义扩「交互发起方 mint」,审批有意不对称留 ApprovalRequestId);帧信封对称化(RpcFrameEnvelope{rpcId,frame},SSE data 改信封 JSON,流侧签名不感知,rpcId 不承担 cursor);design.md §2/§3.4/§4/id 纪律/convention/版头六处同步,core-coverage 提案节标注修订 |
| 2026-07-19 21:55 | W1 契约包(旧三信封模型)dispatcher 直写落盘 14 文件 typecheck 绿;Wire<T> 锚定修正回写 §0.5(exactOptionalPropertyTypes 与 zod .optional 不兼容) |
| 2026-07-19 22:00–22:3x | 用户三轮拍板推到四象限模型(签名信封化→通道解耦→四具名 union+二分裁决);design.md 升 **v2.0**:§2 重写(四具名/窄形/RpcReceipt/错误码删两个)、§3 签名全改 RpcRequest<P>、§3.3 流 yield RpcRequest<帧>、§3.4 respond 重建模、§4 wire 四象限表、rpc-map 6 key+RequestPayload/ResponseValue、convention 同步、§8 补 hostInstanceId 预留(ui-design 提出);期间主会话短暂接管又交还(用户澄清 owner 不变) |