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

27 KiB
Raw Blame History

P1R7c Knowledge Source Owner Propagation 审阅版

结论

推荐进入 P1R-7c但只进入 Knowledge source owner propagation 的第二 owner 切片,不进入 Events / P1R-7 / Knowledge / Market completed approval。

推荐方案:

  1. P1R-7c 只选择 MuseKnowledgeSourceEventService.triggerGlobalKBSourceEvent 这一条 canonical source status / projection summary 链路,使用 Events 现有 notification event type。
  2. 在 Knowledge owner 内新增独立 publish outbox / worker 语义outbox 按受影响 muse_knowledge_source_binding_projection.ownerUserId fan-outworker 只依赖 muse-module-events-api 调用 EventsPublishApi
  3. 不复用 muse_knowledge_projection_task 作为 Events publish 队列;它当前是内部投影任务读模型,且在现有链路里被同步写为 completed
  4. 本轮不覆盖 MuseKnowledgeAccessPolicyServiceMuseKnowledgeBaseServiceMuseKnowledgeDocumentService 中直接构造 MuseKnowledgeSourceEventDO 的入口;这些入口缺少统一 eventType / affected count 合同,必须另起后续切片或先做标准化入口设计。
  5. muse_knowledge_source_event.ownerUserId=0 只代表全局来源事实,不能直接作为 SSE 可见 ownerEvents publish 请求的 ownerUserId 必须来自受影响 projection owner。
  6. 不发布知识资料原文、RAGFlow 原始返回、GraphRAG 细节、授权快照或 provider/error raw detail。
  7. P1R-7c 完成后最多推进 Knowledge propagation evidence 到 needs_verification 证据层,不把 Events、P1R-7、Knowledge 或 Market 标为 completed
flowchart LR
    Source["triggerGlobalKBSourceEvent<br/>canonical source status event"] --> Projection["Knowledge projection update<br/>内部同步投影"]
    Projection --> Fanout["Affected binding projections<br/>ownerUserId fan-out"]
    Source --> Fanout
    Fanout --> Outbox["Knowledge Events publish outbox<br/>per owner queued/running/retryable/dead_letter"]
    Outbox --> Worker["Knowledge publish worker<br/>claim + retry + dead_letter"]
    Worker --> Api["EventsPublishApi<br/>muse-module-events-api only"]
    Api --> Unified[("muse_unified_event<br/>notification / accepted")]
    Unified --> SSE["/app-api/muse/events<br/>SSE 可见"]

本审阅版只做方案审阅,不实现代码,不修改 Java / SQL / OpenAPI / scanner / coverage不提交不 push。

已验证事实

工作区与提交状态

  • 正确 worktree/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
  • 当前分支:dev/1.0.0
  • git push origin dev/1.0.0 已完成,远端从 fa29753 推进到 230152c
  • 当前最近提交:
    • 230152c test(p1r): 收口 AI 事件传播真实链路门禁
    • 3db5fbe feat(p1r): 接入 AI 事件传播真实链路
    • fa29753 test(p1r): 收口 Events SSE 门禁

Coverage 与阶段边界

  • 当前 coverage summary
    • totalOperations = 233
    • completedOperations = 100
    • needsVerificationOperations = 133
    • incompleteOperations = 0
    • genericPersistenceOperations = 0
    • ssePlaceholderOperations = 0
  • Knowledge 59 operations 当前为 dedicated / completed
  • Events 当前唯一 operation streamEvents GET /app-api/muse/eventsdedicated / needs_verificationtarget stage 仍是 P1R-7 End-to-End Acceptance
  • Market 32 operations 当前仍为 dedicated / needs_verification
  • P1R-7 completed approval 必须另起任务,不能由 P1R-7b 或 P1R-7c 自动推出。

全局 P1R7 Source Owner Propagation 约束

  • 全局审阅版把 P1R-7 后续拆分为:
    • P1R-7bAI terminal event 第一 owner 切片。
    • P1R-7cKnowledge source status / projection event propagation。
    • P1R-7dMarket lifecycle / account projection / governance event propagation。
    • P1R-7eAccount(Member) security / entitlement / usage notification propagation。
    • P1R-7fContent canonical change / block saved / export task event propagation。
  • 全局执行版要求每个 owner 保持 source owner 自治:事实归 owner发布补偿归 owner统一可见投影归 Events。
  • 全局执行版要求 source owner server 可以依赖 muse-module-events-api,不得依赖 muse-module-events-serverEvents server 不得反向依赖 source owner server。
  • 全局执行版要求每个 owner 子计划必须包含 outbox 合同、payload allowlist、dependency gate、migration gate、focused tests 和 fresh spec / quality review gate。

Events owner 当前合同

  • EventsPublishApi 位于 muse-module-events-api/src/main/java/cn/iocoder/muse/module/events/api/publish/EventsPublishApi.java
  • EventsPublishReqDTO 必填字段包括 commandIdtenantIdownerUserIdsourceOwnersourceTypesourceIdeventTypepayloadSummaryemittedAt
  • EventsPublishRespDTO 返回 eventIdsequenceNopublishStatuspublishErrorCodeduplicate
  • EventsPublishServiceImpl 现有 OpenAPI payload schema 校验只接受 chunkquality_checkdoneerrornotification
  • notification payload 要求 type 是已声明类型,且 message 是字符串。
  • Events OpenAPI 与 EventsPublishServiceImpl 当前已声明 notification.type 包括 source_status_changeknowledge_projection_donegovernance_actionquota_alert
  • Events publish 当前对 payload 含敏感信息、schema mismatch 或未知 event type 的服务路径会写 rejected 审计记录;blocked 是既有 publish status 与 SSE 过滤兼容口径,执行版如覆盖 blocked 必须引用实际产生路径或作为兼容状态处理。
  • Events publish 支持 commandId 优先、source tuple 次级幂等source owner 重放同一 source fact 会返回同一 eventId/sequenceNo

Knowledge owner 当前能力

  • Knowledge server 当前 POM 直接依赖:
    • muse-module-knowledge-api
    • muse-module-infra-api
    • muse-module-content-server
    • web / security / tenant / mybatis / validation / test starter
  • Knowledge server 当前没有 muse-module-events-api 依赖。
  • muse_knowledge_source_event 已存在,字段包括 source_event_idsource_ownersource_typesource_idsource_revisionowner_user_idkb_idstatusaction_policycommand_idevent_summaryerror_codeerror_messagetenant_id
  • muse_knowledge_source_event 约束 status 只允许 activestalerevokedrecalleddelistedblockedowner_missingunauthorized
  • muse_knowledge_source_event 约束 action policy 只允许 allowedread_onlyblockedneeds_recheck
  • MuseKnowledgeSourceEventService.triggerGlobalKBSourceEvent 当前在一个事务中:
    1. 校验 global KB。
    2. 预占 Knowledge command。
    3. 写入 muse_knowledge_source_event
    4. 同步更新 muse_knowledge_source_binding_projection
    5. 写入 muse_knowledge_projection_task
    6. 记录 command completed。
  • MuseKnowledgeSourceEventService.createProjectionTask 当前明确把 projection task 写为 completed,代码注释写明 projection 已在当前事务同步更新,避免制造无执行者的 queued task。
  • muse_knowledge_projection_taskstatusattempt_noretry_countretryablenext_retry_atresult_summaryerror_codeerror_messagestarted_atfinished_at 字段和 retry 索引,但当前没有 claim/retry/dead-letter worker。
  • MuseKnowledgeProjectionTaskMapper 只提供 selectByTaskId 和按 status 分页查询,没有 claimNext... / FOR UPDATE SKIP LOCKED / 状态转换 SQL。
  • MuseKnowledgeProjectionTaskService 当前只是 projection task 查询服务,不是执行 worker。
  • MuseKnowledgeSourceEventServiceTest 已覆盖 source event 写入、binding projection 同步更新、projection task completed 记录和非法事件不写事实。
  • MuseKnowledgeSourceEventService 当前把 eventType 写入 eventSummary / projection summary JSONaffectedTargets / affectedProjectionCount 写入 projection task summary JSON这些不是 MuseKnowledgeSourceEventDO 顶层字段。
  • muse_knowledge_source_binding_projection 当前有 owner_user_idwork_idkb_idbinding_idstatusaction_policylast_event_idprojection_summary 字段,并有 (tenant_id, owner_user_id, source_owner, source_type, source_id, kb_id) 唯一约束。
  • Events SSE visible query 只返回同租户、同 ownerUserIdpublishStatus=accepted、未删除、已到 visibleFrom 且 sequence 大于 cursor 的事件。
  • triggerGlobalKBSourceEvent 当前写入 MuseKnowledgeSourceEventDO.ownerUserId=0;该值代表 global KB 来源事实 owner不代表普通用户 SSE 可见 owner。

其他 Knowledge source event 入口

  • MuseKnowledgeAccessPolicyService 会写 MuseKnowledgeSourceEventDO,用于 policy publish 后 source event 记录;该入口当前写 sourceType=access_policystatus=activeactionPolicy=allowedevent summary 只有 policyIdkbId,没有标准化 eventType
  • MuseKnowledgeBaseService 会写 MuseKnowledgeSourceEventDO,用于 KB 状态、版本和 user KB block 相关 source event其中 enableGlobalKnowledgeBase 的通用 changeGlobalStatus 当前只更新 KB 状态并记录 command completed不写 source event。
  • MuseKnowledgeDocumentService 会写 MuseKnowledgeSourceEventDO,用于 document deletion 相关 source event该入口 event summary 写入 affectedBindings,但没有标准化 eventType
  • 这些入口当前只是写 Knowledge 本域 source event没有写 Events publish outbox。

推断

  • Knowledge 适合作为 P1R-7c 第二 owner因为 canonical triggerGlobalKBSourceEvent 链路已有 source event、source binding projection、ownerUserId、kbId、sourceRevision、eventSummary 和 command 幂等基础。
  • Knowledge 不适合直接复用 muse_knowledge_projection_task 作为 Events publish queue因为现有 projection task 是内部投影完成记录,不是可领取的补偿队列。
  • P1R-7c 要证明 /app-api/muse/events 对用户可见,必须把 global source event fan-out 到受影响 projection owner如果只按 source event 顶层 ownerUserId=0 发布,普通登录用户不会看到事件。
  • P1R-7c 最小用户可见事件应是 notification,而不是 done/error/chunk/quality_check
    • Knowledge source status 变化不是 AI task terminal result。
    • Knowledge 不能发布知识原文 chunk。
    • 当前 Events OpenAPI 没有专用 knowledge event type。
  • 第一轮 P1R-7c 应优先覆盖 triggerGlobalKBSourceEvent 已显式接受并规范化的 source status 事件;其他 service 直接构造 source event 的入口需要先补标准化事件合同,不能混入本轮。
  • 如果 P1R-7c 直接发布 RAGFlow parse / retrieval / GraphRAG 细节,会把外部 provider runtime 状态混进用户可见 Events不符合全局 payload 合同。

假设

  • P1R-7c 允许在 Knowledge owner 内新增独立 Events publish outbox 表,建议命名为 muse_knowledge_event_publish_outbox 或等价本域 publish outbox。
  • P1R-7c 允许 muse-module-knowledge-server 新增 muse-module-events-api direct dependency。
  • P1R-7c 只复用 Events 现有 OpenAPI notification schema不修改 docs/api-contracts/events/openapi.yaml
  • Knowledge notification 的 type 使用 Events 当前已声明的 source_status_change

目标

  • 证明 Knowledge owner 能把 canonical source status / projection summary 安全传播到统一 Events 投影。
  • 建立链路:triggerGlobalKBSourceEvent -> muse_knowledge_source_event + affected binding projections -> per-owner Knowledge publish outbox -> Knowledge worker -> EventsPublishApi -> muse_unified_event -> /app-api/muse/events SSE 可见。
  • 明确 Knowledge 内部 source/projection 事实与用户可见 notification 的边界。
  • 为后续 P1R-7d Market propagation 提供第二个 owner 的 outbox/worker 复用经验,但不抽取共享库。

非目标

  • 不实现代码;本文档只做人类审阅版设计。
  • 不修改任何 OpenAPI 合同。
  • 不修改 coverage scanner 或 coverage JSON/Markdown。
  • 不把 Knowledge 59 operations 从 completed 改成其他状态,也不把 Events / P1R-7 / Market 推进到 completed
  • 不发布 Knowledge 文档原文、chunk 内容、RAGFlow 原始响应、GraphRAG trace、授权快照或 provider 凭据。
  • 不复用 muse_knowledge_projection_task 作为 Events publish worker 队列。
  • 不把 MuseKnowledgeSourceEventDO.ownerUserId=0 直接当作 app SSE 可见 owner。
  • 不让 Events server 依赖 Knowledge server。
  • 不让统一 SSE Controller 查询 Knowledge 业务表。
  • 不把 MuseKnowledgeAccessPolicyServiceMuseKnowledgeBaseServiceMuseKnowledgeDocumentService 的直接 source event 写入入口纳入 P1R-7c 第一批。
  • 不同时改造 Market / Account / Content propagation。
  • 不把 P1R-7c 写成总 P1R-7 End-to-End Acceptance。

推荐方案

采用“Knowledge source event notification + 本域 publish outbox”的最小方案。

事件选择

第一批允许进入 Events 的 Knowledge source event 只来自 triggerGlobalKBSourceEvent canonical 入口:

Knowledge event 入口 source status action policy Events eventType notification type 用户可见 message 原则
version_changed triggerGlobalKBSourceEvent stale needs_recheck notification source_status_change 知识库版本变化,需要重新检查相关使用方
policy_changed triggerGlobalKBSourceEvent stale needs_recheck notification source_status_change 知识库访问策略变化,需要重新确认使用影响
kb_disabled triggerGlobalKBSourceEvent blocked blocked notification source_status_change 知识库已禁用,相关能力不可用
kb_enabled triggerGlobalKBSourceEvent active allowed notification source_status_change 知识库已恢复可用
status_changed triggerGlobalKBSourceEvent 按 action policy 归一化 按请求或默认值归一化 notification source_status_change 知识库状态已变化

不进入第一批:

  • MuseKnowledgeAccessPolicyService 直接写入的 access policy source event。
  • MuseKnowledgeBaseService 直接写入的 KB status / version / user KB block source event。
  • MuseKnowledgeDocumentService 直接写入的 document deletion source event。
  • document_deleted 只有在后续切片先补标准化入口后才能纳入;不能把现有 document service 入口直接当作 P1R-7c 已覆盖路径。
  • RAGFlow parse polling 内部状态。
  • retrieval / GraphRAG runtime call 细节。
  • projection rebuild heartbeat。
  • Knowledge draft conflict / decision 内部状态。
  • 文档正文或 chunk 内容。

Outbox 边界

新增 Knowledge 本域 publish outbox而不是扩展 muse_knowledge_projection_task。Outbox 粒度是 per affected owner不是 per source event

维度 muse_knowledge_projection_task P1R-7c publish outbox
当前职责 内部投影任务读模型 对外 Events 发布补偿队列
当前写入 source event 事务内同步写 completed source event 事务内按合法 affected owner fan-out 写 queued;非法 owner 不写 outbox
当前 worker 必须新增 claim/retry/dead-letter worker
可见性 管理端任务查询 SSE 用户可见 notification
payload projection result summary Events OpenAPI allowlist payload

可见性 fan-out 合同

P1R-7c 选择“per affected owner notification”不选择 admin/system-only notification

  • MuseKnowledgeSourceEventDO.ownerUserId=0 只保留为 global source fact owner。
  • Outbox 创建必须在 triggerGlobalKBSourceEvent 同一事务内,基于更新后的 muse_knowledge_source_binding_projection 查询受影响 projection。
  • 受影响 owner 集合来自 projection 的 ownerUserId,必须去重,且必须排除 null0
  • 每个受影响 owner 生成一条 outboxEventsPublishReqDTO.ownerUserId 使用该 projection owner。
  • 空受影响 owner 集合不是发布失败source event 与 projection task 仍保持成功publish outbox 不写 queued,只在 source event / projection task summary 中保留 affectedTargets=0 证据。
  • 如果 projection 行存在但 ownerUserId 缺失或非法P1R-7c 第一批保持 outbox DDL 的 target_owner_user_id > 0 严格约束:该行只记录 fan-out 审计摘要和安全日志,不创建 outbox不发布给 owner 0,不要求写入 dead_letter outbox 行。
  • Outbox 不跨 owner 合并;不同 owner 的 publish failure/retry/dead_letter 独立推进。

P1R-7c 执行版必须补 mapper 能力,能按 lastEventId 或本次 source event 关联条件读取受影响 projection owner不能用全表 scan 或从 request payload 推导 owner。

依赖方向

P1R-7c 允许:

  • muse-module-knowledge-server 直接依赖 muse-module-events-api
  • muse-server 同时装配 Knowledge server 和 Events server。

P1R-7c 禁止:

  • muse-module-knowledge-server 依赖 muse-module-events-server
  • muse-module-events-server 依赖 muse-module-knowledge-server
  • Events stream controller 查询 Knowledge 表。

Payload 合同

Knowledge outbox service 必须从 MuseKnowledgeSourceEventDO 顶层字段和 canonical summary allowlist 重建 payload

  • 允许进入 internal outbox 的 DO 顶层字段:
    • kbId
    • sourceEventId
    • sourceType
    • sourceId
    • sourceRevision
    • status
    • actionPolicy
    • commandId
    • tenantId
    • ownerUserId 仅作为 source fact owner 记录,不作为 Events publish owner
  • 允许进入 internal outbox 的 projection fan-out 字段:
    • targetOwnerUserId
    • targetWorkId
    • bindingId
    • projectionId
  • 允许从 canonical eventSummary JSON 读取的字段:
    • eventType
    • targetVersion
    • sourceStatus
    • actionPolicy
  • 允许从 canonical projection task summary JSON 读取的字段:
    • affectedTargets
    • affectedProjectionCount
  • 允许进入 Events notification payload 的字段按 Events OpenAPI 当前 schema 收敛,至少必须有:
    • type
    • message
  • 默认不写入 resourceRef;如执行版确需使用,只允许写用户已可见资源引用,禁止把内部 provider id、raw source id、授权快照 id 或不可见 KB 内部标识透出到 SSE。
  • 禁止进入 Events payload
    • 文档原文。
    • chunk 内容。
    • RAGFlow API key、token、Authorization。
    • RAGFlow raw request/response。
    • GraphRAG trace。
    • authorization snapshot 原文。
    • admin reason 原文如果包含用户输入或敏感上下文;需要归一化为安全 message。

状态策略

  • outbox 创建时:
    • payload 可映射到现有 notification schema 且 targetOwnerUserId 合法 -> queued
    • payload 缺少必需字段或无法映射 -> dead_letter,记录安全错误码。
    • 没有受影响 owner -> 不创建 queued outbox不视为失败。
  • worker claim
    • 使用 FOR UPDATE SKIP LOCKED 或等价原子领取。
    • claim 阶段递增 attempt count。
    • claim lease 过期可被重新领取。
  • publish success
    • Events accepted -> outbox published,回写 published_event_id / published_sequence_no
  • publish rejected / blocked
    • outbox dead_letter,记录 publishErrorCode
    • 验证 SSE visible query 不返回 rejected / blocked。
  • temporary failure
    • 未耗尽重试 -> retryable + next_retry_at
    • 耗尽重试 -> dead_letter

Events 幂等键

为避免 per-owner fan-out 被 V16 muse_unified_event 的 command/source tuple 唯一约束相互撞车P1R-7c 执行版必须固定以下规则:

  • outbox commandId 必须包含原 Knowledge commandId、sourceEventIdtargetOwnerUserId 和 notification type。
  • Events sourceOwner = knowledge
  • Events sourceType 必须使用 per-owner fan-out source type例如 knowledge_source_status_owner
  • Events sourceId 必须包含 sourceEventIdtargetOwnerUserId,不能只用 global KB id。
  • Events sourceRevision 使用 source event 的 sourceRevision,为空时用 Events 现有 __none__ 归一化。
  • Events eventType = notification
  • 重放同一 source event + 同一 target owner 必须返回同一 eventId/sequenceNo;不同 target owner 必须生成不同 unified event。

关键取舍

  • 选择 Knowledge不选择 Market全局计划已把 Knowledge 定位为 P1R-7c且 Knowledge 已有 source event/projection 事实Market 仍需先拆清 Account projection outbox 与 Events publish outbox 职责。
  • 选择 notification,不新增 event type当前 OpenAPI 已声明 notification,能表达用户可见状态变化;新增事件类型会触发合同变更,不是 P1R-7c 最小路径。
  • 选择 canonical triggerGlobalKBSourceEvent,不直接覆盖所有 source event 写入入口:该入口有显式 eventType、归一化 status/action policy、projection update 和 affected count其他入口当前缺少统一事件合同贸然纳入会制造伪 E2E。
  • 选择 per affected owner fan-out不选择 owner 0 系统事件P1R-7c 的证据目标是 app SSE 用户可见Events visible query 按登录用户过滤;系统 owner 0 会绕开主目标。
  • 新增 publish outbox不复用 projection taskprojection task 当前同步完成,没有 claim worker复用会把内部投影任务和用户可见发布补偿混在一起。
  • 只发布摘要不发布资料内容Knowledge 事件最容易泄露资料正文、检索内容和 RAGFlow 细节,必须用 allowlist 重建 payload。
  • 不抽共享库AI 与 Knowledge 可复制全局 outbox 合同,但不在第二 owner 就抽象 shared publisher避免过早长期抽象。

影响范围

后续执行版预计涉及:

  • muse-cloud/muse-module-knowledge/muse-module-knowledge-server/pom.xml
  • muse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/main/java/cn/iocoder/muse/module/knowledge/application/muse/MuseKnowledgeSourceEventService.java
  • muse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/main/java/cn/iocoder/muse/module/knowledge/dal/mysql/muse/MuseKnowledgeSourceBindingProjectionMapper.java
  • muse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/main/java/cn/iocoder/muse/module/knowledge/application/muse/MuseKnowledgeProjectionTaskService.java 只作为读取 affected count 的参考,不改造成 publish worker。
  • 新增 Knowledge publish outbox service / worker / DO / Mapper。
  • 新增 V18 或后续 Knowledge publish outbox migration。
  • 新增 Knowledge outbox service/worker/mapper tests。
  • 新增 P1R-7c dependency / migration / E2E gate tests。
  • 更新 docs/agent-specs/.agentdocs/memorys/ 留痕。

本审阅版不做上述实现。

风险与兼容性

  • notification type 风险:执行版必须固定使用已声明的 source_status_change,不得为 P1R-7c 偷偷新增 OpenAPI type。
  • 入口覆盖风险:本轮只覆盖 canonical triggerGlobalKBSourceEventAccessPolicy/Base/Document 直接 source event 写入入口必须被 dependency/E2E gate 明确排除,后续若纳入必须先做标准化入口合同。
  • owner 可见性风险source event owner 0 不能直接进入 Events publish执行版必须证明 outbox 按 projection owner fan-out且 owner 0 不会被普通用户 SSE 误用。
  • payload 泄露风险Knowledge event summary 可能包含 reason、kbName 或外部细节;执行版必须定义 allowlist 和敏感词/结构过滤。
  • 语义混淆风险:muse_knowledge_projection_task.status=completed 是业务任务状态,不等于 coverage completed也不等于 Events publish 成功。
  • 幂等风险Knowledge source event 的 source_event_id 当前随机 UUIDEvents source tuple 应使用稳定 source_event_id 或稳定 source revision否则 replay 语义可能依赖 commandId 而非 source fact。
  • 依赖风险Knowledge 当前依赖 content serverP1R-7c dependency gate 不能误禁既有 Knowledge -> Content 依赖,但必须禁止 Knowledge -> Events server 和 Events server -> Knowledge server。
  • 完成口径风险Knowledge operations 已是 completedP1R-7c 不能把这一事实外推成 Events / P1R-7 completed。

验收标准

审阅版通过标准:

  • 明确 P1R-7c 只做 Knowledge source owner propagation。
  • 明确 P1R-7c 第一批只覆盖 triggerGlobalKBSourceEvent canonical 入口,并排除其他直接 source event 写入入口。
  • 明确 P1R-7c 使用 affected projection owner fan-out不把 source event owner 0 当作 SSE visible owner。
  • 明确不复用 projection task 作为 Events publish queue。
  • 明确 notification payload 只使用 OpenAPI 已声明 schema。
  • 明确不发布知识资料原文、RAGFlow raw、GraphRAG trace 或授权快照。
  • 明确 Events / P1R-7 / Market / Knowledge completed 边界。

后续执行版必须包含:

  1. live git status --short --branch 和受保护文件 diff 检查。
  2. Events OpenAPI notification type 枚举复核,并固定使用已声明的 source_status_change
  3. 第一批入口矩阵:仅 triggerGlobalKBSourceEvent,并列出 version_changed / policy_changed / kb_disabled / kb_enabled / status_changed 的 source status、action policy、summary allowlist 和 notification mapping。
  4. Knowledge source event -> affected projection owner fan-out -> outbox 同事务写入策略。
  5. Knowledge outbox migration 设计,唯一键必须支持同一 source event 发布给多个 owner。
  6. Knowledge outbox mapper/service/worker 设计。
  7. dependency gateKnowledge server 有 events-api、无 events-serverEvents server 无 Knowledge server。
  8. E2E gatetriggerGlobalKBSourceEvent -> affected owner outbox -> worker -> Events publish -> unified event -> 对应 owner SSE visible。
  9. owner 可见性 gateowner 0 不可作为 app SSE 可见 owner跨 owner 不可见。
  10. 排除 gateAccessPolicy/Base/Document 直接 source event 写入入口不被本轮 E2E 伪覆盖。
  11. rejected / blocked / duplicate / retry / dead_letter 测试blocked 若无实际生产路径,只作为兼容状态不可见验证。
  12. Flyway _test 验证。
  13. 隔离副本 coverage scanner 验证,真实 worktree protected diff 为空。

待确认项

  1. P1R-7c 是否确认只覆盖 triggerGlobalKBSourceEvent canonical source status / projection notification不覆盖 RAGFlow runtime progress。
  2. P1R-7c 是否确认排除 AccessPolicy/Base/Document 直接 source event 写入入口,后续另起标准化入口切片。
  3. P1R-7c 是否确认采用 per affected owner fan-out而不是 owner 0 admin/system-only notification。
  4. P1R-7c 第一批事件是否按 version_changedpolicy_changedkb_disabledkb_enabledstatus_changed 收口。
  5. 是否允许新增 muse_knowledge_event_publish_outbox 表作为 V18 或后续 migration。

下一步

  1. 对本文档执行 fresh spec compliance review。
  2. 对本文档执行 fresh quality / feasibility review。
  3. 双 PASS 后,编写 docs/agent-specs/2026-06-06-P1R7cKnowledgeSourceOwnerPropagation执行版.md
  4. 执行版再经过 fresh spec / quality 双 review 后,才能进入实现。