27 KiB
P1R7c Knowledge Source Owner Propagation 审阅版
结论
推荐进入 P1R-7c,但只进入 Knowledge source owner propagation 的第二 owner 切片,不进入 Events / P1R-7 / Knowledge / Market completed approval。
推荐方案:
- P1R-7c 只选择
MuseKnowledgeSourceEventService.triggerGlobalKBSourceEvent这一条 canonical source status / projection summary 链路,使用 Events 现有notificationevent type。 - 在 Knowledge owner 内新增独立 publish outbox / worker 语义,outbox 按受影响
muse_knowledge_source_binding_projection.ownerUserIdfan-out,worker 只依赖muse-module-events-api调用EventsPublishApi。 - 不复用
muse_knowledge_projection_task作为 Events publish 队列;它当前是内部投影任务读模型,且在现有链路里被同步写为completed。 - 本轮不覆盖
MuseKnowledgeAccessPolicyService、MuseKnowledgeBaseService、MuseKnowledgeDocumentService中直接构造MuseKnowledgeSourceEventDO的入口;这些入口缺少统一eventType/ affected count 合同,必须另起后续切片或先做标准化入口设计。 muse_knowledge_source_event.ownerUserId=0只代表全局来源事实,不能直接作为 SSE 可见 owner;Events publish 请求的ownerUserId必须来自受影响 projection owner。- 不发布知识资料原文、RAGFlow 原始返回、GraphRAG 细节、授权快照或 provider/error raw detail。
- 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 = 233completedOperations = 100needsVerificationOperations = 133incompleteOperations = 0genericPersistenceOperations = 0ssePlaceholderOperations = 0
- Knowledge 59 operations 当前为
dedicated / completed。 - Events 当前唯一 operation
streamEvents GET /app-api/muse/events为dedicated / needs_verification,target 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-7b:AI terminal event 第一 owner 切片。
- P1R-7c:Knowledge source status / projection event propagation。
- P1R-7d:Market lifecycle / account projection / governance event propagation。
- P1R-7e:Account(Member) security / entitlement / usage notification propagation。
- P1R-7f:Content canonical change / block saved / export task event propagation。
- 全局执行版要求每个 owner 保持 source owner 自治:事实归 owner,发布补偿归 owner,统一可见投影归 Events。
- 全局执行版要求 source owner server 可以依赖
muse-module-events-api,不得依赖muse-module-events-server;Events 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必填字段包括commandId、tenantId、ownerUserId、sourceOwner、sourceType、sourceId、eventType、payloadSummary、emittedAt。EventsPublishRespDTO返回eventId、sequenceNo、publishStatus、publishErrorCode、duplicate。EventsPublishServiceImpl现有 OpenAPI payload schema 校验只接受chunk、quality_check、done、error、notification。notificationpayload 要求type是已声明类型,且message是字符串。- Events OpenAPI 与
EventsPublishServiceImpl当前已声明notification.type包括source_status_change、knowledge_projection_done、governance_action、quota_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-apimuse-module-infra-apimuse-module-content-server- web / security / tenant / mybatis / validation / test starter
- Knowledge server 当前没有
muse-module-events-api依赖。 muse_knowledge_source_event已存在,字段包括source_event_id、source_owner、source_type、source_id、source_revision、owner_user_id、kb_id、status、action_policy、command_id、event_summary、error_code、error_message、tenant_id。muse_knowledge_source_event约束 status 只允许active、stale、revoked、recalled、delisted、blocked、owner_missing、unauthorized。muse_knowledge_source_event约束 action policy 只允许allowed、read_only、blocked、needs_recheck。MuseKnowledgeSourceEventService.triggerGlobalKBSourceEvent当前在一个事务中:- 校验 global KB。
- 预占 Knowledge command。
- 写入
muse_knowledge_source_event。 - 同步更新
muse_knowledge_source_binding_projection。 - 写入
muse_knowledge_projection_task。 - 记录 command completed。
MuseKnowledgeSourceEventService.createProjectionTask当前明确把 projection task 写为completed,代码注释写明 projection 已在当前事务同步更新,避免制造无执行者的 queued task。muse_knowledge_projection_task有status、attempt_no、retry_count、retryable、next_retry_at、result_summary、error_code、error_message、started_at、finished_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 taskcompleted记录和非法事件不写事实。MuseKnowledgeSourceEventService当前把eventType写入eventSummary/ projection summary JSON,把affectedTargets/affectedProjectionCount写入 projection task summary JSON;这些不是MuseKnowledgeSourceEventDO顶层字段。muse_knowledge_source_binding_projection当前有owner_user_id、work_id、kb_id、binding_id、status、action_policy、last_event_id和projection_summary字段,并有(tenant_id, owner_user_id, source_owner, source_type, source_id, kb_id)唯一约束。- Events SSE visible query 只返回同租户、同
ownerUserId、publishStatus=accepted、未删除、已到visibleFrom且 sequence 大于 cursor 的事件。 triggerGlobalKBSourceEvent当前写入MuseKnowledgeSourceEventDO.ownerUserId=0;该值代表 global KB 来源事实 owner,不代表普通用户 SSE 可见 owner。
其他 Knowledge source event 入口
MuseKnowledgeAccessPolicyService会写MuseKnowledgeSourceEventDO,用于 policy publish 后 source event 记录;该入口当前写sourceType=access_policy、status=active、actionPolicy=allowed,event summary 只有policyId和kbId,没有标准化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-apidirect dependency。 - P1R-7c 只复用 Events 现有 OpenAPI
notificationschema,不修改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/eventsSSE 可见。 - 明确 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 业务表。
- 不把
MuseKnowledgeAccessPolicyService、MuseKnowledgeBaseService、MuseKnowledgeDocumentService的直接 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,必须去重,且必须排除null与0。 - 每个受影响 owner 生成一条 outbox;
EventsPublishReqDTO.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,不发布给 owner0,不要求写入dead_letteroutbox 行。 - 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 顶层字段:
kbIdsourceEventIdsourceTypesourceIdsourceRevisionstatusactionPolicycommandIdtenantIdownerUserId仅作为 source fact owner 记录,不作为 Events publish owner
- 允许进入 internal outbox 的 projection fan-out 字段:
targetOwnerUserIdtargetWorkIdbindingIdprojectionId
- 允许从 canonical
eventSummaryJSON 读取的字段:eventTypetargetVersionsourceStatusactionPolicy
- 允许从 canonical projection task summary JSON 读取的字段:
affectedTargetsaffectedProjectionCount
- 允许进入 Events
notificationpayload 的字段按 Events OpenAPI 当前 schema 收敛,至少必须有:typemessage
- 默认不写入
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 可映射到现有
notificationschema 且targetOwnerUserId合法 ->queued。 - payload 缺少必需字段或无法映射 ->
dead_letter,记录安全错误码。 - 没有受影响 owner -> 不创建
queuedoutbox,不视为失败。
- payload 可映射到现有
- worker claim:
- 使用
FOR UPDATE SKIP LOCKED或等价原子领取。 - claim 阶段递增 attempt count。
- claim lease 过期可被重新领取。
- 使用
- publish success:
- Events
accepted-> outboxpublished,回写published_event_id/published_sequence_no。
- Events
- publish rejected / blocked:
- outbox
dead_letter,记录publishErrorCode。 - 验证 SSE visible query 不返回 rejected / blocked。
- outbox
- 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、sourceEventId、targetOwnerUserId和 notification type。 - Events
sourceOwner = knowledge。 - Events
sourceType必须使用 per-owner fan-out source type,例如knowledge_source_status_owner。 - Events
sourceId必须包含sourceEventId与targetOwnerUserId,不能只用 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 按登录用户过滤;系统 owner0会绕开主目标。 - 新增 publish outbox,不复用 projection task:projection task 当前同步完成,没有 claim worker;复用会把内部投影任务和用户可见发布补偿混在一起。
- 只发布摘要,不发布资料内容:Knowledge 事件最容易泄露资料正文、检索内容和 RAGFlow 细节,必须用 allowlist 重建 payload。
- 不抽共享库:AI 与 Knowledge 可复制全局 outbox 合同,但不在第二 owner 就抽象 shared publisher,避免过早长期抽象。
影响范围
后续执行版预计涉及:
muse-cloud/muse-module-knowledge/muse-module-knowledge-server/pom.xmlmuse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/main/java/cn/iocoder/muse/module/knowledge/application/muse/MuseKnowledgeSourceEventService.javamuse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/main/java/cn/iocoder/muse/module/knowledge/dal/mysql/muse/MuseKnowledgeSourceBindingProjectionMapper.javamuse-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/.agent与docs/memorys/留痕。
本审阅版不做上述实现。
风险与兼容性
- notification type 风险:执行版必须固定使用已声明的
source_status_change,不得为 P1R-7c 偷偷新增 OpenAPI type。 - 入口覆盖风险:本轮只覆盖 canonical
triggerGlobalKBSourceEvent;AccessPolicy/Base/Document 直接 source event 写入入口必须被 dependency/E2E gate 明确排除,后续若纳入必须先做标准化入口合同。 - owner 可见性风险:source event owner
0不能直接进入 Events publish;执行版必须证明 outbox 按 projection owner fan-out,且 owner0不会被普通用户 SSE 误用。 - payload 泄露风险:Knowledge event summary 可能包含 reason、kbName 或外部细节;执行版必须定义 allowlist 和敏感词/结构过滤。
- 语义混淆风险:
muse_knowledge_projection_task.status=completed是业务任务状态,不等于 coverage completed,也不等于 Events publish 成功。 - 幂等风险:Knowledge source event 的
source_event_id当前随机 UUID;Events source tuple 应使用稳定source_event_id或稳定 source revision,否则 replay 语义可能依赖 commandId 而非 source fact。 - 依赖风险:Knowledge 当前依赖 content server;P1R-7c dependency gate 不能误禁既有 Knowledge -> Content 依赖,但必须禁止 Knowledge -> Events server 和 Events server -> Knowledge server。
- 完成口径风险:Knowledge operations 已是
completed,P1R-7c 不能把这一事实外推成 Events / P1R-7 completed。
验收标准
审阅版通过标准:
- 明确 P1R-7c 只做 Knowledge source owner propagation。
- 明确 P1R-7c 第一批只覆盖
triggerGlobalKBSourceEventcanonical 入口,并排除其他直接 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 边界。
后续执行版必须包含:
- live
git status --short --branch和受保护文件 diff 检查。 - Events OpenAPI notification type 枚举复核,并固定使用已声明的
source_status_change。 - 第一批入口矩阵:仅
triggerGlobalKBSourceEvent,并列出version_changed/policy_changed/kb_disabled/kb_enabled/status_changed的 source status、action policy、summary allowlist 和 notification mapping。 - Knowledge source event -> affected projection owner fan-out -> outbox 同事务写入策略。
- Knowledge outbox migration 设计,唯一键必须支持同一 source event 发布给多个 owner。
- Knowledge outbox mapper/service/worker 设计。
- dependency gate:Knowledge server 有 events-api、无 events-server;Events server 无 Knowledge server。
- E2E gate:
triggerGlobalKBSourceEvent-> affected owner outbox -> worker -> Events publish -> unified event -> 对应 owner SSE visible。 - owner 可见性 gate:owner
0不可作为 app SSE 可见 owner;跨 owner 不可见。 - 排除 gate:AccessPolicy/Base/Document 直接 source event 写入入口不被本轮 E2E 伪覆盖。
- rejected / blocked / duplicate / retry / dead_letter 测试;blocked 若无实际生产路径,只作为兼容状态不可见验证。
- Flyway
_test验证。 - 隔离副本 coverage scanner 验证,真实 worktree protected diff 为空。
待确认项
- P1R-7c 是否确认只覆盖
triggerGlobalKBSourceEventcanonical source status / projection notification,不覆盖 RAGFlow runtime progress。 - P1R-7c 是否确认排除 AccessPolicy/Base/Document 直接 source event 写入入口,后续另起标准化入口切片。
- P1R-7c 是否确认采用 per affected owner fan-out,而不是 owner
0admin/system-only notification。 - P1R-7c 第一批事件是否按
version_changed、policy_changed、kb_disabled、kb_enabled、status_changed收口。 - 是否允许新增
muse_knowledge_event_publish_outbox表作为 V18 或后续 migration。
下一步
- 对本文档执行 fresh spec compliance review。
- 对本文档执行 fresh quality / feasibility review。
- 双 PASS 后,编写
docs/agent-specs/2026-06-06-P1R7cKnowledgeSourceOwnerPropagation执行版.md。 - 执行版再经过 fresh spec / quality 双 review 后,才能进入实现。