9.8 KiB
P1R7c Knowledge Source Owner Propagation 真实链路
日期:2026-06-06
结论
P1R-7c Knowledge source owner propagation 主体实现、V18 SQL、focused tests、P1R mixed executable gates、V18 Flyway _test、reactor build、隔离 coverage scanner 与 P2 增强后 fresh review 已推进到 needs_verification 证据层。
当前仍不能写 completed。Rawls correctness/spec review 与 Boole data-integrity/testing review 已双 PASS,但该 PASS 只代表 Knowledge source owner terminal event -> Knowledge outbox -> worker -> EventsPublishApi -> muse_unified_event -> SSE 可见链路 evidence 推进到 needs_verification,不代表 Events / P1R-7 / Knowledge / Market completed。
本轮未修改 OpenAPI、coverage scanner 或真实 coverage 报告。
已验证事实
工作区与保护文件
- 正确 worktree:
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0。 - 分支:
dev/1.0.0。 - 受保护文件 diff 为空:
docs/api-contracts/market/openapi.yamldocs/api-contracts/ai/openapi.yamldocs/api-contracts/knowledge/openapi.yamldocs/api-contracts/events/openapi.yamlmuse-cloud/scripts/p1r-audit-api-coverage.pydocs/superpowers/reports/p1r-api-coverage.jsondocs/superpowers/reports/p1r-api-coverage.md
本轮实现范围
- Knowledge server 新增直接依赖
muse-module-events-api。 - 新增 Knowledge 本域 publish outbox:
MuseKnowledgeEventPublishOutboxDOMuseKnowledgeEventPublishOutboxMapperMuseKnowledgeEventPublishOutboxServiceMuseKnowledgeEventPublishOutboxServiceImplMuseKnowledgeEventPublishWorkerMuseKnowledgeEventsPropertiesMuseKnowledgeEventsConfiguration
MuseKnowledgeSourceEventService在 canonicaltriggerGlobalKBSourceEvent链路内创建 per target owner outbox,并将ownerFanoutSummary写入 projection task summary。MuseKnowledgeSourceBindingProjectionMapper新增按kbId + lastEventIdfan-out target 查询与 owner audit summary 查询。- 新增 V18 migration:
muse-cloud/sql/muse/V18__extend_knowledge_events_publish_outbox.sql。
Focused tests
执行:
JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o test -pl muse-module-knowledge/muse-module-knowledge-server -Dtest=MuseKnowledgeEventPublishOutboxServiceTest,MuseKnowledgeEventPublishWorkerTest,MuseKnowledgeSourceEventServiceTest -Dsurefire.failIfNoSpecifiedTests=false
结果:exit 0,15 tests pass,failures/errors/skipped 均为 0。
覆盖点:
- per distinct target owner 创建 outbox。
- 不同 owner 的
commandId/outboxId不相同。 document_deleted不写 outbox。- invalid owner 只进入 audit summary,不进入 outbox。
- worker disabled 不 claim。
- accepted -> published。
- rejected / blocked -> dead_letter。
- API error -> retryable。
- last attempt exception -> dead_letter。
- terminal status update 必须携带本次 claim attempt ownership,避免过期 worker 覆盖新终态。
- terminal status update 返回 0 时必须记录 stale claim 诊断日志,包含 tenantId、targetOwnerUserId、outboxId、sourceEventId、attempt、targetStatus、errorCode。
- source event 集成写入
ownerFanoutSummary。
P1R mixed executable gates
执行:
JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o test -pl muse-server -am -Dtest=P1rKnowledgeEventsPublishMigrationSqlTest,P1rKnowledgeEventsPublishDependencyTest,P1rKnowledgeEventsPublishEndToEndTest,P1rApiCoverageReportTest,P1rEventsRealApiGateTest,P1rEventsRouteOwnershipTest,P1rAiRealApiGateTest,P1rAiRouteOwnershipTest -Dsurefire.failIfNoSpecifiedTests=false
结果:exit 0,37 tests pass,failures/errors/skipped 均为 0。
覆盖点:
- V18 SQL 静态 migration gate。
- Knowledge server 依赖 Events API,不依赖 Events server。
- Events server 不反向依赖 AI / Knowledge / Market / Member / Content server。
- Knowledge outbox -> worker -> EventsPublishServiceImpl ->
muse_unified_eventfocused E2E。 - target owner 可见,owner 0 / 非 target owner 不可见。
- 同一 source event 不同 owner 不被合并。
- 同一 source event + owner replay 回放同一 event identity。
- stale claim terminal update 因 attempt 不匹配被忽略。
- blocked publish 进入 outbox dead_letter 且不可见。
Flyway IT 当前状态
新增:
muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rKnowledgeEventsPublishFlywayMigrationIT.java
安全方法执行:
JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o test -pl muse-server -am -Dtest='P1rKnowledgeEventsPublishFlywayMigrationIT#should_rejectNonTestDatabaseWhenQueryContainsSlashTestSuffix+should_rejectCredentialQueryParameters' -Dsurefire.failIfNoSpecifiedTests=false
结果:exit 0,2 tests pass。
真实库准备:
- 测试库
muse_p1r7c_events_publish_test已确认/创建。 psql可连接目标库,输出判断为psql_target_db_connect=true。
真实 Flyway _test:
JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o test -pl muse-server -am -Dtest=P1rKnowledgeEventsPublishFlywayMigrationIT -Dflyway.postgresql.transactional.lock=false -Dp1r.flyway.locations=filesystem:sql/muse -Dp1r.flyway.url=jdbc:postgresql://<host>:5433/muse_p1r7c_events_publish_test -Dp1r.flyway.user=<user> -Djava.net.useSystemProxies=false -DsocksProxyHost= -DsocksProxyPort= -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort= -Dsurefire.failIfNoSpecifiedTests=false
结果:exit 0,4 tests pass,failures/errors/skipped 均为 0。P2 修复后新增真实负向 insert 约束探针已纳入全量 Flyway IT。
关键输出:
flyway_success=true
migrations_executed=18
successful_migration_count=18
target_schema_version=18
flyway_latest=18:extend knowledge events publish outbox
v18_table=muse_knowledge_event_publish_outbox
JDBC EOF 根因:
psql_target_db_connect=true
socksProxyHost_initial=127.0.0.1
jdbc_default=false ... cause=java.io.EOFException:null
socksProxyHost_cleared=null
jdbc_no_proxy=true db=muse_p1r7c_events_publish_test
结论:V18 SQL 已通过真实 PostgreSQL / Flyway 验收;早前 EOF 是 Java 全局 SOCKS/HTTP/HTTPS 代理属性影响 PostgreSQL JDBC 连接链路,不是 V18 SQL 失败。
P2 增强:
singleLiteralCheck已从 substring 判断改为精确单表达式匹配,避免未来误接受event_type='notification' OR ...。P1rKnowledgeEventsPublishFlywayMigrationIT新增真实 PostgreSQL 负向 insert 探针,验证 event_type、notification_type、publish_status、target_owner_user_id check 会拒绝非法行。- 纯函数 RED/GREEN:
should_rejectBroadSingleLiteralConstraintExpression先失败,修复后 1/1 pass。 - Worker RED/GREEN:
should_logWhenAcceptedTerminalUpdateIsSkippedByStaleClaim先失败,修复后 1/1 pass。 - 一次并行 Maven 验证因两个命令同时触碰 Knowledge
target,出现 testCompile 找不到已存在类;串行重跑 worker 测试通过,判定为并发构建污染,不作为代码缺陷。
Reactor build
执行:
JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o clean install -DskipTests -Dspring-boot.repackage.skip=true
结果:exit 0,BUILD SUCCESS,62/62 modules success。
Coverage scanner
scanner 只在隔离副本运行。
最终干净隔离副本:
/tmp/p1r7c-final-coverage-scan.2HXo1Z
执行:
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check
结果:
coverage_exit=0
真实 worktree 受保护 coverage JSON/Markdown diff 仍为空。
推断
基于 focused tests、P1R mixed executable gates、V18 Flyway _test、reactor build、隔离 coverage scanner、protected diff 以及 Rawls/Boole fresh review,可以判断 P1R-7c Knowledge source owner propagation 的应用层链路已具备收口到 needs_verification 的证据。
由于本轮证据只覆盖 Knowledge source owner propagation 第一批 canonical source status / projection summary 链路,不能推断 Events / P1R-7 / Knowledge / Market 已完成,也不能推进 completed。
假设
~/.config/muse-repo/infra.env是当前项目允许用于本地 P1R_test数据库准备的配置来源。- 后续提交将按实现与测试/文档分组,避免把状态推进、coverage 口径和真实实现混成一笔。
风险与未完成
- P2 增强后 focused / mixed / Flyway / reactor / coverage / protected diff 已重跑,fresh review 已重新派发并双 PASS:Rawls correctness/spec PASS,Boole data-integrity/testing PASS。
- fresh implementation review 历史:Sagan correctness PASS,Dalton testing evidence PASS,Halley data integrity FAIL。
- Halley 的 P1 已验证并修复:outbox claim 后终态回写原先缺少本次 claim 所有权保护,过期 worker 可能覆盖新 claim 终态;已先写 RED 测试
should_guardTerminalStatusUpdatesWithClaimAttemptOwnership,再把markPublished/markRetryable/markDeadLetter补为publish_status='running' AND attempt_count=#{claimedAttemptCount},并由 worker 传入 claim 返回的attemptCount。 - 修复后 fresh review 第一轮:Kuhn correctness/spec PASS,Herschel data integrity PASS。Herschel 的两个 P2 已被纳入本轮增强,并已由 Rawls/Boole P2 后 fresh review 复核。
- Boole 非阻塞风险:V18
ON CONFLICT DO NOTHING可能静默丢弃非法 duplicate source/owner 行,当前由 focused replay gate 覆盖第一批行为;worker 默认关闭,启用前仍需要运行配置与运维监控确认。 - 不得修改 OpenAPI、scanner、coverage report 来绕过缺口。
- 不得把 coverage
needs_verification改成completed。
下一步
- 提交前复核
git status --short --branch与 protected diff。 - 按逻辑分组准备提交:实现一组,测试/规格/留痕一组。
- 提交和 push 前仍不得推进 completed,不得修改 OpenAPI、scanner、coverage report。