文档:DirectProject 待发消息条目改为事件投影,prompt 改为条目重投影

- ADR §3/§4/§5 与备选方案 6–8、影响与代价:删掉 StoredEvent.pending 的第二份产物,队列成员由事件折出;prompt 只在引用 part 上冻结算不出的片段(to_prompt_cache,宿主内存专用),canonical 形状与 prompt 放行时重投影;analyticsAttemptId 进 queue.enqueued
- 实施计划:状态改第 0–6 步、落地进度表补第 6 步、新增「第 6 步:条目不再另存产物」的实现点与验收
- decision-log:追加 2026-09-30 修订条目(背景、三条决策、埋点身份的口径)
This commit is contained in:
2026-09-30 15:20:39 +08:00
parent 888c249ffd
commit e70b338900
3 changed files with 78 additions and 10 deletions
@@ -9143,6 +9143,30 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
`directTurnPresentation` / `project-conversation` 定向用例、`npm --workspace apps/ai-game-creator-shell run typecheck`、
`npm run check:encoding`、`git diff --check`。
## 2026-09-30 待发消息条目不再另存产物:队列成员由事件折出,prompt 改为条目重投影
- 背景:09-24 落地时给 `StoredEvent` 加了一个"挂着的队列条目"字段(`Option<PendingDirectTurn>`),条目上带七个字段。
复核发现其中 `client_turn_id` / `user_item` / `creation_type` / `at` 与 `queue.enqueued` 的载荷是同一份事实的第二份拷贝,
`canonical_user_item` 是 `serde_json::to_value(user_item)`(第三份),而这两项在构造事件之后再没被读过;
`Some/None` 同时兼着"宿主产物袋"与"在队标记"两职,于是取消 / 放行要写两处事实、回收规则还要加"产物还在就不许回收"的防御。
与该 ADR §3 写的"队列的成员与顺序就是事件列表本身"已经不一致。
- 决策(队列成员):删掉 `StoredEvent.pending`(`append_inner` 并入 `append`);在队条目 = 事件窗口里"有 `queue.enqueued`、
且还没有配对 `queue.removed`"的那些事件,按事件顺序即队首到队尾。判重、容量、取消、认领、bootstrap 全部改读这一次折叠,
`mark_queue_events_cleanable` 删掉产物防御。
- 决策(prompt):不另存整条 prompt。prompt 是 `userItem` 的投影,唯一的例外是引用 UI 设计文档时要展开的代码上下文
(渲染它会往项目里写 `ui/generated-*.js`)。把它在那次入队检查里冻结到引用 part 的 `to_prompt_cache` 上——
该字段宿主内存专用(`#[serde(skip)]` + `#[ts(skip)]`:不序列化、不上线、不进历史、不进绑定)。
投影拆成两半:入队侧的 `freeze`(校验 + 算片段 + 写盘)与放行侧的纯折叠(零 IO、零校验、无失败出口),
于是"放行不重跑任何检查、没有放行失败"这条不变式对新形状仍然成立。`canonical_user_item` 同理改为放行时
`serde_json::to_value(user_item)` 重投影。副作用:引用的代码上下文片段不再统一追加在 prompt 末尾,而是跟在它所属的引用片段里,
单条引用时逐字节不变。
- 决策(埋点身份):`analyticsAttemptId` 由前端在入队那一刻生成、随命令交给宿主,宿主把它写进
`queue.enqueued{clientTurnId,userItem,creationType?,analyticsAttemptId?,at}`。理由是它与 `clientTurnId` 同类——
发送侧在这一刻定下的身份、放行时要原样交给埋点候选——所以跟着事件走,而不是另存条目产物。
不用 `clientTurnId` 兼作埋点身份:埋点候选的 `attempt_id` 必须是 UUID(`analytics/run.rs` 的 `validate`),
而 `clientTurnId` 在 WebView 没有 `crypto.randomUUID` 时会退化成时间戳 + 序号的形状。
- 验证方式(设计稿,尚未实施):ADR §3 / §4 / §5 与「备选方案与取舍」6–8 条、实施计划第 6 步。
## 2026-09-28 渲染层下沉分支与最新 master 对齐:活动回合事实源、维护态出口与诊断详情
- 背景:`codex/agc-renderer-io-downshift` 把 AGC 渲染层的网络与状态下沉 Rust 之后,要重新落到 master 已经演进出的新形状上。29 处冲突里 25 处是机械取舍,真正的分歧只有三处需要定口径。