354 lines
15 KiB
Markdown
354 lines
15 KiB
Markdown
# P1R7 Source Owner Propagation 全局执行版
|
||
|
||
## 结论
|
||
|
||
本执行版只定义 P1R-7 Source Owner Propagation 的全局落地顺序、子阶段拆分、review gate、验证门槛和当前 AI 草稿处理规则;不实现代码,不提交,不推送,不推进 completed。
|
||
|
||
总执行主线:
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
GlobalReview["全局审阅版<br/>已双 review PASS"] --> GlobalPlan["全局执行版<br/>本文件,待双 review"]
|
||
GlobalPlan --> Freeze["冻结全局合同<br/>用户可见 Events 不替代内部 Source/Authorization"]
|
||
Freeze --> P7bPlan["P1R-7b 子计划<br/>AI terminal event"]
|
||
P7bPlan --> P7bImpl["P1R-7b 实现<br/>AI outbox + worker + Events evidence"]
|
||
P7bImpl --> NextDecision{"下一 owner 选择"}
|
||
NextDecision --> P7c["P1R-7c Knowledge<br/>source status / projection notification"]
|
||
NextDecision --> P7e["P1R-7e Account<br/>security / quota notification 备选"]
|
||
P7c --> P7d["P1R-7d Market<br/>lifecycle / governance notification"]
|
||
P7e --> P7d
|
||
P7d --> P7f["P1R-7f Content<br/>用户可见 content/task notification"]
|
||
P7f --> Approval["P1R-7 completed approval<br/>用户单独批准"]
|
||
```
|
||
|
||
硬边界:
|
||
|
||
1. 当前 AI outbox / V17 / docs 草稿在 P1R-7b 子计划修订并双 review PASS 前不得继续测试、提交、推送或作为完成证据。
|
||
2. 全局方案只定义“用户可见 Events 发布链路”,不替代正式 Source / Authorization 内部传播链路。
|
||
3. 每个 owner 的实现都必须 fresh implementer + fresh spec review + fresh quality / feasibility review。
|
||
4. completed approval 必须另起任务,不能由任何 dedicated gate 或 owner evidence 自动推出。
|
||
|
||
## 范围
|
||
|
||
本执行版负责:
|
||
|
||
- 固化 P1R-7 全局 source owner propagation 合同。
|
||
- 定义后续 P1R-7b/c/d/e/f 子计划顺序和拆分条件。
|
||
- 定义每个子计划必须继承的通用验证门槛。
|
||
- 定义当前 dirty AI 草稿如何进入 P1R-7b 子计划复审。
|
||
|
||
本执行版不负责:
|
||
|
||
- 不改业务代码、迁移、OpenAPI、scanner、coverage JSON/Markdown。
|
||
- 不运行 Maven / pnpm / Flyway / coverage scanner full verification。
|
||
- 不清理或回退当前 dirty/untracked baseline。
|
||
- 不把 `streamEvents`、P1R-7、Market 或任何 owner 标为 `completed`。
|
||
|
||
## 已验证事实
|
||
|
||
### 工作区与 review gate
|
||
|
||
1. 正确工作区为 `/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0`。
|
||
2. 当前分支为 `dev/1.0.0`,远端 `origin/dev/1.0.0` 已 ff-only 对齐。
|
||
3. 当前 HEAD 为 `fa29753 test(p1r): 收口 Events SSE 门禁`。
|
||
4. 当前 `git status --short --branch` 显示未提交 AI P1R-7b 草稿、V17 migration 草稿和 `docs/agent-specs/` 文档草稿。
|
||
5. 受保护文件定向 `git status --short` 无输出。
|
||
6. `docs/agent-specs/2026-06-06-P1R7SourceOwnerPropagation全局审阅版.md` 已通过 fresh spec review:
|
||
- Kant / `019e9987-ca59-7370-bc49-9938eb93c70f` / PASS。
|
||
7. 同一全局审阅版已通过 fresh quality / feasibility review:
|
||
- Hubble / `019e998b-2d82-7200-9289-c6c8dd37f744` / PASS。
|
||
|
||
### Coverage 与状态边界
|
||
|
||
1. 当前 coverage summary:
|
||
- `totalOperations = 233`
|
||
- `completedOperations = 100`
|
||
- `needsVerificationOperations = 133`
|
||
- `incompleteOperations = 0`
|
||
- `genericPersistenceOperations = 0`
|
||
- `ssePlaceholderOperations = 0`
|
||
2. Events 当前唯一 operation 为 `streamEvents GET /app-api/muse/events = dedicated / needs_verification`。
|
||
3. Market 当前 32 operations 均为 `dedicated / needs_verification`。
|
||
4. P1R-7a 收口文档明确:P1R-7a 未接入 source owner propagation,未运行 source owner publish tests。
|
||
|
||
### 全局设计事实
|
||
|
||
1. `CLAUDE.md` 将 Source 传播定为“事件驱动 + 各模块自治”。
|
||
2. `design-docs/架构-02-核心数据结构与双轨模型.md` 明确不需要独立 source 模块。
|
||
3. `design-docs/后端-03-关键流程实现与接口契约.md` 明确异步失败不得回滚已提交 Canonical。
|
||
4. P1R-7a 执行版已固定 source owner 本域 outbox + worker 调用 Events API;Events server 不反向依赖 source owner server。
|
||
5. Events owner 当前已有 `EventsPublishApi`、`EventsPublishReqDTO`、commandId/source tuple 幂等、payload sanitizer、accepted-only 可见查询和 SSE stream。
|
||
|
||
## 推断
|
||
|
||
1. 全局执行顺序应先冻结通用合同,再修订 P1R-7b AI 子计划;否则当前 AI 草稿可能继续携带单点设计里的事务和 dirty baseline 风险。
|
||
2. AI 仍是第一实现切片,因为它已有 terminal fact、ownerUserId、runtime job 和 focused test 基础。
|
||
3. Knowledge 适合作为第二个 source status propagation owner,但如果后续目标更偏用户通知而非来源状态传播,Account security event 可以作为更低风险 second slice 备选。
|
||
4. Market 应排在 AI/Knowledge 之后,因为 Market Account projection outbox 与 Events publish outbox 职责不同,直接复用风险较高。
|
||
5. Content 需要先界定内部领域事件与用户可见事件,否则容易把 BlockSavedEvent 等内部 trigger 过度推送到 SSE。
|
||
|
||
## 假设
|
||
|
||
1. 后续 owner 允许在本域新增 publish outbox 或等价状态表。
|
||
2. 后续 owner server 允许新增 `muse-module-events-api` 依赖。
|
||
3. 现有 Events OpenAPI 事件类型足够覆盖第一轮用户可见摘要;如果不够,应另起合同变更审批。
|
||
4. 当前 AI 草稿可以作为 P1R-7b 子计划的候选素材,但必须经过执行版修订、双 review 和本地验证后才能继续。
|
||
|
||
## 全局合同
|
||
|
||
### 依赖合同
|
||
|
||
1. Source owner server 可以依赖 `muse-module-events-api`。
|
||
2. Source owner server 不得依赖 `muse-module-events-server`。
|
||
3. `muse-module-events-server` 不得依赖 AI / Knowledge / Market / Member / Content server。
|
||
4. `muse-server` 可以装配 Events server 与各 source owner server。
|
||
5. 每个 owner 子计划必须包含 Maven dependency tree 验证命令。
|
||
|
||
### 发布 envelope 合同
|
||
|
||
每个 owner 子计划必须固定:
|
||
|
||
| 字段 | 要求 |
|
||
|---|---|
|
||
| `commandId` | 稳定短幂等键,长度 `<= 128`,推荐 `<owner>_evt:<sha256-32>` |
|
||
| `tenantId` | 必填,worker 必须恢复租户上下文 |
|
||
| `ownerUserId` | 必填,决定 SSE 可见性 |
|
||
| `sourceOwner` | 固定 owner 枚举 |
|
||
| `sourceType` | 固定业务事实类型 |
|
||
| `sourceId` | 本域事实稳定 id 或业务 id |
|
||
| `sourceRevision` | 本域事实版本;缺失时必须在子计划解释占位语义 |
|
||
| `eventType` | 只能使用 Events OpenAPI 已声明类型 |
|
||
| `resourceType/resourceId` | UI 定位对象,不参与替代 source tuple 幂等 |
|
||
| `payloadSummary` | OpenAPI allowlist 安全摘要 |
|
||
| `emittedAt` | 本域事实发生时间 |
|
||
|
||
### 用户可见事件判定
|
||
|
||
每个候选事件进入 SSE 前必须满足:
|
||
|
||
1. 用户需要实时感知。
|
||
2. 用户可据此采取动作或理解当前工作状态。
|
||
3. payload 能压缩为 OpenAPI 已声明 schema 的安全摘要。
|
||
4. 不需要暴露内部 source propagation、授权快照、worker、风控或 provider raw 细节。
|
||
5. 能提供稳定 source tuple、commandId、ownerUserId 和 emittedAt。
|
||
|
||
默认不进入 SSE:
|
||
|
||
1. 内部 followup trigger。
|
||
2. projection rebuild / worker heartbeat / retry job 状态。
|
||
3. 需要完整正文、知识资料、provider raw、授权详情或安全原始证据才能解释的事件。
|
||
|
||
### Outbox 合同
|
||
|
||
每个 owner 子计划必须包含:
|
||
|
||
1. `queued/running/retryable/published/dead_letter` 或等价状态。
|
||
2. `attempt_count` 或等价 claim 次数字段。
|
||
3. `max_attempt` 配置。
|
||
4. `next_retry_at`。
|
||
5. `claimed_at`。
|
||
6. `claim_expires_at`。
|
||
7. 固定退避策略。
|
||
8. claim 索引。
|
||
9. `FOR UPDATE SKIP LOCKED` 或等价原子领取机制。
|
||
10. `ON CONFLICT DO NOTHING` / `insertIgnore` + 回查,禁止把唯一约束异常作为正常幂等路径。
|
||
11. `published_event_id` / `published_sequence_no` 或等价回写字段。
|
||
12. `last_error_code` / `last_error_message` 安全错误摘要。
|
||
13. 中文日志,包含 owner、tenantId、ownerUserId、source tuple、outboxId、attempt、状态转换和错误摘要。
|
||
|
||
### Payload 合同
|
||
|
||
每个 owner 子计划必须列出:
|
||
|
||
1. 允许的 `eventType`。
|
||
2. 每个 `eventType` 的 payload allowlist。
|
||
3. 需要丢弃或归一化的敏感字段。
|
||
4. payload invalid 时的 fail-closed 状态和错误码。
|
||
5. rejected/blocked 后不得进入 SSE 可见查询的验证方式。
|
||
|
||
## 子阶段执行顺序
|
||
|
||
### Task 0:冻结总执行版
|
||
|
||
目标:
|
||
|
||
- 本文件完成 fresh spec review + fresh quality / feasibility review 双 PASS。
|
||
- 双 PASS 前不修订 P1R-7b 子计划,不继续 AI 草稿测试或实现。
|
||
|
||
验收:
|
||
|
||
- Reviewer 明确 PASS。
|
||
- 如有 FAIL,先修订本文件并重审。
|
||
- protected files 仍无改动。
|
||
|
||
### Task 1:P1R-7b 子计划修订
|
||
|
||
目标:
|
||
|
||
- 修订 `docs/agent-specs/2026-06-06-P1R7bSourceOwnerPropagation执行版.md`。
|
||
- 将它从“AI 单点执行版”改为“全局执行版下的 AI 第一切片子计划”。
|
||
- 明确当前 AI 草稿的处理策略:修订沿用、拆分提交或用户批准后清理。
|
||
|
||
必须补充:
|
||
|
||
1. 继承本执行版的依赖合同、envelope 合同、outbox 合同和 payload 合同。
|
||
2. 明确 AI 只发布用户可见 terminal `done/error` 摘要。
|
||
3. 明确 AI outbox 创建不得依赖捕获 `DuplicateKeyException` 作为正常幂等路径。
|
||
4. 明确 P1R-7b 只处理 AI,不处理 Knowledge / Market / Account / Content。
|
||
5. 明确 P1R-7b 不推进 completed。
|
||
|
||
Review gate:
|
||
|
||
- Fresh spec compliance review。
|
||
- Fresh quality / feasibility review。
|
||
- 双 PASS 前不得继续当前 AI 草稿实现。
|
||
|
||
### Task 2:P1R-7b AI 实现收口
|
||
|
||
目标:
|
||
|
||
- 在 P1R-7b 子计划双 PASS 后,处理当前 AI 草稿或由 fresh implementer 重做。
|
||
- 实现 AI terminal event -> AI publish outbox -> AI worker -> EventsPublishApi -> `muse_unified_event` -> SSE 可见证据。
|
||
|
||
必须验证:
|
||
|
||
1. AI focused tests。
|
||
2. Outbox mapper/service/worker tests。
|
||
3. Events publish accepted/rejected/blocked/duplicate tests。
|
||
4. SSE visible query tests。
|
||
5. Dependency tree:AI 只依赖 events-api,不依赖 events-server;Events server 不依赖 source owner server。
|
||
6. Migration SQL test 和 Flyway `_test`。
|
||
7. protected files 无改动。
|
||
|
||
Review gate:
|
||
|
||
- 每个实现 Task fresh implementer。
|
||
- 每个实现 Task fresh spec review。
|
||
- 每个实现 Task fresh quality / feasibility review。
|
||
|
||
### Task 3:第二 owner 选择决策
|
||
|
||
目标:
|
||
|
||
- 在 AI 第一切片通过后,只读评估第二 owner 是 Knowledge source status 还是 Account security notification。
|
||
|
||
选择规则:
|
||
|
||
1. 如果目标是 source status propagation 证据优先,选择 Knowledge。
|
||
2. 如果目标是用户可见通知链路低风险扩展优先,选择 Account security event。
|
||
3. 不因 Market 有 outbox 命名而优先选择 Market。
|
||
4. Content 进入前必须先冻结内部事件与用户可见事件判定。
|
||
5. 如果 Account security event 先于 Market 落地,阶段编号仍保留 P1R-7e,不重命名 P1R-7d,避免阶段编号反向改写历史计划。
|
||
|
||
输出:
|
||
|
||
- `docs/agent-specs/YYYY-MM-DD-P1R7c...审阅版.md`。
|
||
- fresh spec review + fresh quality review。
|
||
|
||
### Task 4:P1R-7c / P1R-7e 子计划与实现
|
||
|
||
目标:
|
||
|
||
- 按 Task 3 决策进入 Knowledge 或 Account。
|
||
- 每个 owner 都必须先产出单独审阅版,再产出单独执行版;审阅版和执行版各自 fresh spec review + fresh quality / feasibility review 双 PASS 后,才允许进入该 owner 实现。
|
||
|
||
必须继承:
|
||
|
||
- 本执行版的全局合同。
|
||
- P1R-7b 的复用经验,但不得复制 AI payload / 状态机细节到不匹配 owner。
|
||
|
||
### Task 5:Market 与 Content 后续切片
|
||
|
||
目标:
|
||
|
||
- Market 先拆清 Account projection outbox 与 Events publish outbox 职责。
|
||
- Content 先拆清内部 followup trigger 与用户可见 Events notification。
|
||
|
||
进入条件:
|
||
|
||
- 至少已有两个 owner 的 Events publish 链路通过验证,或者用户明确要求优先 Market / Content。
|
||
|
||
### Task 6:P1R-7 completed approval 预检
|
||
|
||
目标:
|
||
|
||
- 汇总 Events owner + 各 source owner evidence。
|
||
- 只读判断是否具备 completed approval 申请条件。
|
||
|
||
必须包含:
|
||
|
||
1. coverage 当前状态。
|
||
2. 所有 owner 的测试证据。
|
||
3. HTTP / SSE / DB / Flyway / dependency / protected file evidence。
|
||
4. 未覆盖 owner 和未覆盖失败路径清单。
|
||
|
||
边界:
|
||
|
||
- 该 task 只做预检,不自动标 completed。
|
||
- completed approval 必须用户单独批准。
|
||
|
||
## 验证命令模板
|
||
|
||
每个 owner 子计划必须按实际模块填充以下模板:
|
||
|
||
```bash
|
||
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
|
||
git status --short --branch
|
||
git status --short -- 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 docs/superpowers/reports/p1r-api-coverage.json docs/superpowers/reports/p1r-api-coverage.md
|
||
```
|
||
|
||
```bash
|
||
cd muse-cloud
|
||
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" mvn -o -pl <owner-module> -am -Dtest=<focused-tests> -Dsurefire.failIfNoSpecifiedTests=false test
|
||
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" mvn -o -pl muse-server -am -Dtest=<p1r-gate-tests> -Dsurefire.failIfNoSpecifiedTests=false test
|
||
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" mvn -o -pl <owner-module> -am dependency:tree
|
||
```
|
||
|
||
Flyway `_test` 必须使用独立测试库,且必须显式清空 JVM 代理参数或证明代理不会影响内网 PostgreSQL 连接。
|
||
|
||
## 当前 dirty baseline 处理规则
|
||
|
||
当前未提交 AI P1R-7b 草稿包括:
|
||
|
||
- AI module POM、runtime projection service、job service 与相关测试改动。
|
||
- AI publish outbox service / mapper / DO 新文件。
|
||
- `muse-cloud/sql/muse/V17__extend_ai_events_publish_outbox.sql`。
|
||
- P1R-7b migration SQL/Flyway test 草稿。
|
||
- `docs/agent-specs/` 文档草稿。
|
||
|
||
处理规则:
|
||
|
||
1. 本执行版双 PASS 前,不继续测试或实现这些草稿。
|
||
2. P1R-7b 子计划修订时必须显式决定这些草稿是“修订沿用”还是“废弃重做”。
|
||
3. 如果选择修订沿用,必须补证据证明草稿已符合本执行版全局合同。
|
||
4. 如果选择废弃重做,必须先征得用户明确批准后才能清理相关 dirty/untracked 文件。
|
||
5. 任何情况下不得回退用户或其他代理的无关改动。
|
||
|
||
## 完成条件
|
||
|
||
本总执行版完成条件:
|
||
|
||
1. 本文件存在且内容覆盖全局合同、子阶段顺序、验证模板、dirty baseline 处理规则。
|
||
2. Fresh spec compliance review PASS。
|
||
3. Fresh quality / feasibility review PASS。
|
||
4. protected files 无改动。
|
||
5. 输出下一步:修订 P1R-7b 子计划,而不是直接继续 AI 实现。
|
||
6. 本轮 reviewer 只读审查文档,不运行 full verification;review PASS 不能解释为实现验证 PASS。
|
||
|
||
P1R-7 全链路完成条件不在本文件完成范围内;它必须在 P1R-7 completed approval 任务中单独判断。
|
||
|
||
## 回滚策略
|
||
|
||
本执行版只新增文档;若 review FAIL:
|
||
|
||
1. 只修订本文件和必要的 `.agent` 说明。
|
||
2. 不回退代码草稿。
|
||
3. 不修改 protected files。
|
||
4. 不运行 full verification。
|
||
|
||
若后续实现阶段发现全局合同错误:
|
||
|
||
1. 停止对应 owner 实现。
|
||
2. 回到全局审阅版 / 执行版修订。
|
||
3. 重新 fresh spec review + fresh quality review。
|