oh-my-muse/docs/memorys/2026-06-05-P1R7aEventsSSE审阅版.md

138 lines
7.0 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.

# P1R7a Events SSE 审阅版留痕
## 结论
P1R-7a Events SSE 已完成只读 preflight、审阅版文档、执行版计划和 fresh review 双 PASS当前可以在用户明确批准后从执行版 Task 1 开始实现。
P1R-7a 是总 P1R-7 End-to-End Acceptance 的前置子任务,不是全量 P1R-7 completed approval。阶段目标只允许把 `streamEvents``sse_placeholder / incomplete` 推进到 `dedicated / needs_verification`,不能标为 `completed`
## 已验证事实
- 正确工作区:`/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0`
- 分支:`dev/1.0.0`,远端:`origin/dev/1.0.0`
- `git pull --ff-only origin dev/1.0.0` 输出 `Already up to date`
- 当前最新提交链路:
- `3deb0de test(p1r): 收口 Market 真实 API 门禁`
- `621d45a feat(p1r): 落地 Market 真实 API`
- `f02defd docs(p1r): 补齐 Market 真实 API 规格计划`
- coverage summary
- `completedOperations = 100`
- `needsVerificationOperations = 132`
- `incompleteOperations = 1`
- `genericPersistenceOperations = 0`
- `ssePlaceholderOperations = 1`
- Events 当前只有 1 个 operation`streamEvents GET /app-api/muse/events`,状态为 `sse_placeholder / incomplete`
- 当前 `AppMuseEventsController` 发送固定 `muse event stream ready` notification 后立即 `complete()`
- `docs/api-contracts/events/openapi.yaml` 只声明 `200 text/event-stream``401`,不声明 `400` 或版本错误响应。
- `muse-studio/src/lib/sse.ts` 的全局事件流当前使用 `new EventSource(url)`,无法发送 `Authorization``X-API-Version` header。
## 本轮产物
- 审阅版文档:`docs/superpowers/specs/2026-06-05-P1R-7-events-sse-review.md`
- 执行版计划:`docs/superpowers/plans/2026-06-05-P1R-7a-events-sse.md`
- 模块上下文:`docs/superpowers/.agent`,当前被 `.gitignore` 忽略,提交前如需纳入版本库必须单独处理。
审阅版关键决策:
1. 命名为 `P1R-7aEvents SSE 前置子任务`,避免和总 P1R-7 End-to-End Acceptance 混淆。
2. 新增独立 `muse-module-events-api/server` 作为 Events owner不继续把统一事件流放在 Content 模块内。
3. 新增 `muse_unified_event` 统一事件投影,推荐迁移版本 `V16__extend_events_sse_schema.sql`
4. source owner 通过 Events API / outbox 契约幂等发布事件Events 不反向依赖 AI、Knowledge、Market、Account 或 Member server。
5. `lastEventId` 推荐采用 `muse:<sequence_no>`
6. 不修改 OpenAPI 时,非法 cursor / version 不支持在 SSE 连接内发送已声明 `error` event 后结束。
7. 前端全局事件流从 `EventSource` 切换到 fetch 流式 SSE以支持 app bearer auth 和 `X-API-Version`
## Review 结果
### 审阅版第一轮 spec compliance review
- 结果FAIL。
- blocker
1. P1R-7 阶段口径冲突。
2. 跨模块 projector 入口契约缺失。
3. 不改 OpenAPI 与连接前业务错误冲突。
4. 浏览器 EventSource 鉴权和 `X-API-Version` 链路未闭合。
### 审阅版修正后 fresh spec compliance re-review
- 结果PASS。
- 复审结论4 个 blocker 已收敛;剩余为执行版确认和落地风险。
### 审阅版 fresh quality / feasibility review
- 结果PASS with warnings。
- warnings
1. 执行版必须明确 Maven 接线任务,并用 dependency tree 证明无循环。
2. `EventsPublishFacade.publish(...)` 必须固定重复发布、rejected、blocked 的返回语义。
3. fetch SSE 不能只替换构造函数,必须保留 `close()``on(event, handler)``lastEventId`、断线重连和事件名分发。
4. `notification.type` 合同很窄,首批 source mapping 必须严格限缩。
5. 失败路径要写成测试任务:非法 cursor、DB 异常、线程池拒绝、客户端断开、跨 tenant replay。
### 执行版第一轮 spec compliance review
- 结果FAIL。
- blocker
1. source owner 发布策略没有闭合 retry / dead-letter / replay。
2. fetch SSE 没有保留断线重连语义。
### 执行版修正后 spec compliance review
- 结果PASS。
- 复审结论:发布补偿链路和 fetch SSE 重连语义已收敛。
### 执行版第一轮 quality / feasibility review
- 结果FAIL。
- blocker
1. Task 6 把 P1R-7a 扩大成 AI / Knowledge / Market / Member 四个 source owner 全量 outbox worker 改造。
- 修正Task 6 收窄为 source owner publish 兼容性盘点与可选最小接入;没有安全公开事实或可复用 outbox / job 的 owner 进入 P1R-7b / `needs_verification`
### Task 6 修正后 spec compliance review
- 结果PASS。
- warnings
1. 实现阶段必须证明 source owner 是否满足已有 outbox / job 条件。
2. 如果没有任何 source owner 可接入,最终报告必须明确 source owner propagation 进入 P1R-7b。
### Task 6 修正后 quality / feasibility review
- 结果FAIL。
- blocker
1. V16 DDL 缺 `command_id` 与唯一约束,`source_revision` 可空导致 PostgreSQL 唯一约束不能可靠去重。
2. `sequence_no` 并发分配策略未写清,可能诱导 `max(sequence_no)+1`
- 修正:执行版补 `command_id VARCHAR NOT NULL``UNIQUE (tenant_id, command_id)``source_revision VARCHAR NOT NULL DEFAULT '__none__'``muse_unified_event_sequence_no_seq``sequence_no DEFAULT nextval(...)`,并禁止 `max(sequence_no)+1`
### DDL 修正后 spec compliance review
- 结果FAIL。
- blocker
1. unsupported `X-API-Version` 未明确用 SSE `error` event 收敛。
2.`lastEventId` 首连不回放历史语义未闭合。
- 修正Task 5 补版本校验、unsupported version 发送 `error` event 后 complete、空 cursor 连接建立时冻结当前可见最大 `sequence_no`,并补对应 focused tests。
### 最终 fresh spec compliance review
- 结果PASS。
- 结论:执行版计划符合审阅版 P1R-7a Events SSE 关键边界。
### 最终 fresh quality / feasibility review
- 结果PASS。
- non-blocking warnings
1. Maven `-am + -Dtest` 可能遇到上游模块无匹配测试,执行时要避免掩盖拼写错误。
2. 新增 `events-server` 后,`mvn -pl muse-server -Dtest=... test` 可能依赖本地仓库构件,更稳妥是 `-pl muse-server -am` 或先 reactor install。
3. `payload_summary JSONB` 需要明确 MyBatis 映射策略。
4. `muse-studio` fetch SSE 实现前要确认 token 来源,不能硬编码或 query token。
## 后续边界
- 不修改以下受保护文件来掩盖缺口:
- `docs/api-contracts/market/openapi.yaml`
- `docs/api-contracts/ai/openapi.yaml`
- `docs/api-contracts/knowledge/openapi.yaml`
- `muse-cloud/scripts/p1r-audit-api-coverage.py`
- 不把 Market 或 Events 标为 `completed`
- 不把 dedicated gate PASS 等同 completed。
- 当前执行版计划已通过 fresh spec review + fresh quality review但尚未实现、尚未运行实现验证、尚未推进 coverage。
- 进入实现后仍必须按 `superpowers:subagent-driven-development` 逐 Task 使用 fresh implementer并在每个 Task 后做 fresh spec review + fresh quality review。