oh-my-muse/docs/memorys/2026-06-06-P1R7cKnowledgeSourceOwnerPropagation真实链路.md

9.8 KiB
Raw Blame History

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.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

本轮实现范围

  • Knowledge server 新增直接依赖 muse-module-events-api
  • 新增 Knowledge 本域 publish outbox
    • MuseKnowledgeEventPublishOutboxDO
    • MuseKnowledgeEventPublishOutboxMapper
    • MuseKnowledgeEventPublishOutboxService
    • MuseKnowledgeEventPublishOutboxServiceImpl
    • MuseKnowledgeEventPublishWorker
    • MuseKnowledgeEventsProperties
    • MuseKnowledgeEventsConfiguration
  • MuseKnowledgeSourceEventService 在 canonical triggerGlobalKBSourceEvent 链路内创建 per target owner outbox并将 ownerFanoutSummary 写入 projection task summary。
  • MuseKnowledgeSourceBindingProjectionMapper 新增按 kbId + lastEventId fan-out target 查询与 owner audit summary 查询。
  • 新增 V18 migrationmuse-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 015 tests passfailures/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 037 tests passfailures/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_event focused 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 02 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 04 tests passfailures/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/GREENshould_rejectBroadSingleLiteralConstraintExpression 先失败,修复后 1/1 pass。
  • Worker RED/GREENshould_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 0BUILD SUCCESS62/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 已重新派发并双 PASSRawls correctness/spec PASSBoole data-integrity/testing PASS。
  • fresh implementation review 历史Sagan correctness PASSDalton testing evidence PASSHalley 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 PASSHerschel 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

下一步

  1. 提交前复核 git status --short --branch 与 protected diff。
  2. 按逻辑分组准备提交:实现一组,测试/规格/留痕一组。
  3. 提交和 push 前仍不得推进 completed不得修改 OpenAPI、scanner、coverage report。