oh-my-muse/docs/agent-specs/2026-06-06-P1R7bSourceOwnerPropagation审阅版.md

149 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.

# P1R7b Source Owner Propagation 审阅版
## 结论
推荐进入 P1R-7b但只进入 source owner propagation 的第一切片,不进入 Events / P1R-7 / Market completed approval。
推荐拆分为:
1. P1R-7b只选择 AI task terminal event 作为第一切片,证明 AI owner 本域事件通过最小 publish outbox / worker 调用 `EventsPublishApi`,落入 `muse_unified_event`,并可被 `/app-api/muse/events` SSE 读到。
2. P1R-7c 或后续:再评估 Knowledge、Market、Member(Account) 的 source owner propagation不在 P1R-7b 同时改造多个 owner。
P1R-7b 最多补齐 source owner propagation 的 `needs_verification` 证据;不得自动把 Events、总 P1R-7 或 Market 32 operations 标为 `completed`
## 已验证事实
- 正确工作区已核验为 `/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0``git log -1 --oneline``fa29753 test(p1r): 收口 Events SSE 门禁`
- P1R-7a 推送后正确 worktree 曾核验为干净;本文档写入后当前 live `git status --short` 显示 `?? docs/agent-specs/`。后续执行版和实现前必须重新记录 live dirty baseline。受保护文件无改动
- `docs/api-contracts/market/openapi.yaml`
- `docs/api-contracts/ai/openapi.yaml`
- `docs/api-contracts/knowledge/openapi.yaml`
- `docs/api-contracts/events/openapi.yaml`
- `muse-cloud/scripts/p1r-audit-api-coverage.py`
- coverage 当前为 `completed=100``needsVerification=133``incomplete=0``genericPersistence=0``ssePlaceholder=0`
- Events 当前唯一 operation`streamEvents GET /app-api/muse/events = dedicated / needs_verification`
- Market 当前 32 operations 均仍为 `dedicated / needs_verification`
- P1R-7a 收口文档明确P1R-7a 未接入 source owner propagation未运行 source owner publish tests。
- `muse-module-events-api` 已存在 `EventsPublishApi.publish(EventsPublishReqDTO)`Events server 已有 `muse_unified_event` 投影、幂等回查、payload 脱敏、`accepted/rejected/blocked` 状态和可见事件查询。
- 当前 AI 有 `muse_ai_task_event`、task event replay mapper、`MuseAiRuntimeJobDispatcher``MuseAiJobMapper.claimNextQueuedRuntimeJob()`;但 AI runtime job 只领取 `ai_task_runtime`AI source event retry 只提交 `source_event_retry` job未验证存在 Events publish worker。
- 当前 Knowledge 有 `muse_knowledge_source_event``muse_knowledge_projection_task``MuseKnowledgeSourceEventService` 同步更新 projection 后把 task 直接写为 `completed`,注释说明避免制造无执行者的 queued task。
- 当前 Market 有 `MarketAccountProjectionOutboxService`,但接口只有 `recordSynced` / `recordBlocked`,用于 Market 写 member Account projection 的同步状态;未发现 claim/retry/dead-letter/replay worker。
- 当前 Member(Account) 有 `AccountIntegrationCallDO``MemberSecurityEventDO` 和安全事件脱敏转换mapper 只支持查询,不支持 publish outbox claim 或补偿状态转换。
## 推断
- AI 是 P1R-7b 第一切片的最小风险 owner它已有 owner-visible task terminal event、runtime job、sequence/replay 和 focused test 基础,新增 Events publish outbox/worker 的范围最小。
- Market 虽然有 outbox 命名和状态字段,但当前职责是 Account 投影同步记录,不是通用 Events publish 补偿队列;直接复用会混淆职责。
- Knowledge 和 Member(Account) 要进入统一事件传播,都需要先补本域 publish outbox/worker 语义;放入 P1R-7b 会扩大 blast radius。
- 如果 P1R-7b 同时拉 AI、Knowledge、Market、Member(Account),大概率会变成跨 owner 队列重构,不符合“真实最小”的阶段目标。
## 假设
- P1R-7b 允许在 AI owner 内新增最小 Events publish outbox/worker 结构,但仍不得修改 OpenAPI、scanner 或 coverage 口径。
- P1R-7b 的 source owner publish tests 可以优先使用 focused unit / integration tests 证明发布、失败、重试、幂等和 SSE 可见性,不要求一次性覆盖所有业务 owner。
- 当前代码结构中的 Events API 依赖方向会保持source owner 可以依赖 `muse-module-events-api`,但 Events server 不反向依赖 AI / Knowledge / Market / Member server。
## 目标
- 证明至少一个真实 source owner 能把本域事实传播到统一 Events 投影。
- 第一切片只覆盖 AI task terminal event 的 `done` / `error` 或等价最小可公开事件。
- 建立 source owner 本域 outbox/job 到 `EventsPublishApi` 的可追踪链路。
- 产出 publish tests 和最小 E2E evidence证明 source owner -> Events -> `muse_unified_event` -> SSE stream 的链路可验证。
- 保持 `streamEvents` 和相关 owner 状态在 `needs_verification` 证据推进层,不做 completed approval。
## 非目标
- 不实现代码;本文档只做人类审阅版设计。
- 不修改任何 OpenAPI 合同。
- 不修改 coverage scanner 或通过 scanner 改口径掩盖缺口。
- 不修改 coverage JSON / Markdown不标 `completed`
- 不把 P1R-7b 扩大成总 P1R-7 End-to-End Acceptance。
- 不把 Market 32 operations 从 `needs_verification` 推进到 `completed`
- 不同时改造 AI、Knowledge、Market、Member(Account) 四个 owner。
- 不清理、不回退、不修复错误 checkout `/Users/qingse/Sync/local-git/oh-my-muse` 的任何残留。
## 推荐方案
采用“AI first slice + 后续 owner 分批”的真实最小方案。
```mermaid
flowchart LR
Owner["AI source owner<br/>task terminal fact"] --> Outbox["AI local publish outbox/job<br/>queued/running/failed/dead_letter"]
Outbox --> Worker["AI publish worker<br/>retry + idempotency"]
Worker --> Api["EventsPublishApi<br/>events-api only"]
Api --> Store[("muse_unified_event<br/>accepted/rejected/blocked")]
Store --> Query["Events visible query<br/>tenant + ownerUserId + sequence"]
Query --> SSE["/app-api/muse/events<br/>SSE stream"]
```
推荐 P1R-7b 第一切片边界:
- Source ownerAI。
- Source factAI task terminal event优先选择已可公开、已持久化、已有 ownerUserId 和 sequence 的 done/error 事实。
- Publish modeAI 本域 outbox/job 异步调用 `EventsPublishApi`,不在业务事务内阻塞等待 Events 成功。
- Idempotency使用 AI 本域 command/source tuple 映射 Events `commandId``(sourceOwner, sourceType, sourceId, sourceRevision, eventType)`
- FailureEvents 临时失败时 AI 业务事实仍保留outbox 保持可重试;达到上限后进入阻塞或 dead-letter 等价状态。
- SSE evidence只证明 accepted 事件进入 `muse_unified_event` 后能被当前用户 SSE 可见查询读到。
后续切片:
- P1R-7cKnowledge source/projection event publish outbox。
- P1R-7dMarket governance / Account projection 相关事件,需先拆清 Account 投影 outbox 与 Events publish outbox 职责。
- P1R-7eMember(Account) 安全/额度通知,需先冻结脱敏 payload contract。
## 候选 source owner 分级
| 分级 | Owner | 结论 | 主要证据 |
|---|---|---|---|
| 第一切片 | AI | 推荐 P1R-7b 先做 | 已有 task event、runtime job、ownerUserId、sequence/replay 基础;缺口集中在 Events publish outbox/worker |
| 后续高优先 | Knowledge | 放入 P1R-7c | 有 source event/projection 事实,但 projection task 当前同步完成,不是可执行补偿队列 |
| 后续中优先 | Market | 放入后续 | 有 Account projection outbox 状态记录,但职责是 Market -> Member Account 投影同步,不是 Events publish worker |
| 后续中优先 | Member(Account) | 放入后续 | 有安全事件和脱敏转换,但缺少 publish outbox/job/retry/dead-letter 入口 |
## 关键取舍
- 选择 AI不选择 MarketMarket outbox 名称容易误导,但当前没有 claim/retry/dead-letter/replay workerAI 的 task terminal event 更接近可公开事件源。
- 做一个 owner不做四个 ownersource owner propagation 的核心风险在失败补偿和幂等;先用单 owner 打穿链路,比并行堆多个半成品更可审核。
- 新增本域 publish outbox不把 runtime job 当 Events publish 队列AI runtime job 职责是执行 New-API task混用会污染任务语义和重试策略。
- 保持 Events API 单向依赖source owner 依赖 events-apiEvents server 不读取 source owner 表,不反向依赖 source owner server。
- 只推进证据,不推进 completedP1R-7b 是 source propagation evidence 阶段,不是审批阶段。
## 影响范围
- 直接影响AI owner 的 task terminal event 发布路径、Events publish API 调用、`muse_unified_event` 投影可见性、SSE focused evidence。
- 间接影响P1R-7 completed approval 的后续证据链更完整,但不会自动改变 completed 状态。
- 不影响OpenAPI 合同、scanner 规则、Market coverage 状态、错误 checkout `/Users/qingse/Sync/local-git/oh-my-muse`
## 风险与兼容性
- 幂等风险:同一 AI task terminal event 重试不能生成多条 unified event必须用 command/source tuple 双重幂等验证。
- 事务风险AI 业务事实不能因为 Events 暂时不可用而回滚publish outbox 必须承载失败补偿。
- 敏感信息风险AI payload 只能发布 OpenAPI 允许的 done/error 摘要,不能透传 provider raw body、prompt、token、授权头或私有上下文。
- 顺序风险AI task sequence 与 Events 全局 sequence 是不同序列;文档和测试必须明确映射,不得混用 cursor。
- 兼容性风险:新增 AI -> events-api 依赖可以接受;不得新增 AI -> events-server 依赖,也不得新增 Events server -> AI server 依赖。
- 状态风险P1R-7b evidence 可能让 Events 更接近 completion但没有用户明确 approval 前不得改 coverage completed。
## 验收标准
- 有只读 preflight 证明 worktree、HEAD、coverage 和 protected files 状态。
- AI 第一切片 source fact、outbox/job、publish worker、EventsPublishApi、`muse_unified_event` 和 SSE 可见查询形成闭环证据。
- Publish tests 至少覆盖成功发布、重复发布幂等、EventsPublishApi 临时失败后 outbox 可重试、非法/敏感 payload 不进入可见 SSE、dead-letter 或等价阻塞状态。
- E2E evidence 至少证明 AI terminal fact 发布后,`muse_unified_event` 有 accepted 记录,并能被 `/app-api/muse/events` 当前用户 SSE 读到。
- 依赖方向测试证明 Events server 不依赖 AI / Knowledge / Market / Member serverAI 只依赖 `muse-module-events-api`
- coverage 仍不标 completed若需要 completed approval必须另起审批任务。
- 受保护文件保持无改动。
## 待确认项
1. P1R-7b 第一切片是否确认只选 AI task terminal event而不是 Market / Knowledge / Member。
2. AI terminal event 的最小事件类型是否限定为 `done` / `error`,还是允许补一个 `notification` 摘要。
3. P1R-7b 是否允许新增 AI 本域 publish outbox/job 表或等价状态字段;若不允许,只能做更弱的同步 publish 证明,不建议。
4. P1R-7b 的 E2E evidence 是否需要真实 PostgreSQL `_test` + MockMvc/SSE还是 focused integration test 足够进入下一轮 review。
## 下一步
1. 人类确认本文推荐方案和待确认项。
2. 确认后再写执行版计划,路径建议为 `docs/agent-specs/2026-06-06-P1R7bSourceOwnerPropagation执行版.md`
3. 执行版计划需先过 fresh spec review + fresh quality review双 PASS 前不实现代码、不跑 full verification。
4. 实现阶段只在 `/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0` 进行,不处理 `/Users/qingse/Sync/local-git/oh-my-muse` 残留。