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

12 KiB
Raw Blame History

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.0git log -1 --onelinefa29753 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=100needsVerification=133incomplete=0genericPersistence=0ssePlaceholder=0
  • Events 当前唯一 operationstreamEvents 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、MuseAiRuntimeJobDispatcherMuseAiJobMapper.claimNextQueuedRuntimeJob();但 AI runtime job 只领取 ai_task_runtimeAI source event retry 只提交 source_event_retry job未验证存在 Events publish worker。
  • 当前 Knowledge 有 muse_knowledge_source_eventmuse_knowledge_projection_taskMuseKnowledgeSourceEventService 同步更新 projection 后把 task 直接写为 completed,注释说明避免制造无执行者的 queued task。
  • 当前 Market 有 MarketAccountProjectionOutboxService,但接口只有 recordSynced / recordBlocked,用于 Market 写 member Account projection 的同步状态;未发现 claim/retry/dead-letter/replay worker。
  • 当前 Member(Account) 有 AccountIntegrationCallDOMemberSecurityEventDO 和安全事件脱敏转换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 分批”的真实最小方案。

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 残留。