# P1R0 基线门禁收口留痕 ## 任务背景 本次执行 `docs/superpowers/plans/2026-05-25-P1R-0-baseline-gate.md`,目标是为 P1R 真实 API 改造建立可重复运行的基线门禁。 P1R-0 不负责实现真实业务 API,不修改生产 Controller、Service、Mapper 或 DDL。它只回答: - OpenAPI 合同里到底有多少 operation。 - 当前 `muse-cloud/` 后端对每个 operation 是真实专用入口、catch-all 合同入口、通用持久化入口、SSE 占位入口,还是缺入口。 - 哪些 operation 绝不能在 P1R-0 阶段被误判为完成。 - 后续 P1R-1 到 P1R-7 应该基于哪份机器可读矩阵继续推进。 ## 计划原始目标 计划要求新增一套 API 覆盖矩阵门禁: - 新增 `muse-cloud/scripts/p1r-audit-api-coverage.py`。 - 解析 `docs/api-contracts/*/openapi.yaml`。 - 扫描 `muse-cloud/` Java 源码。 - 生成: - `docs/superpowers/reports/p1r-api-coverage.json` - `docs/superpowers/reports/p1r-api-coverage.md` - 新增 Maven 测试: - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java` - 保证 P1R-0 不把 catch-all、generic persistence、SSE placeholder、missing 这类非真实实现标记为完成。 ## 实际完成内容 P1R-0 在独立 worktree 中完成: ```text /Users/qingse/.config/superpowers/worktrees/oh-my-muse/feature-p1r-0-baseline-gate ``` 分支: ```text feature/p1r-0-baseline-gate ``` 关键提交: ```text 97f1f3a chore(p1r): 生成 API 覆盖基线矩阵 7d35ce7 fix(p1r): 修正 API 覆盖矩阵识别规则 4084fce fix(p1r): 收紧 API 覆盖矩阵路由匹配 0d16c21 fix(p1r): 修正 API 覆盖矩阵必填与入口归属 9a32e3d fix(p1r): 强化覆盖矩阵完成状态校验 83d7df1 test(p1r): 增加 API 覆盖矩阵门禁 19e673c fix(p1r): 对齐基线门禁验证规则 ``` 实际产物: - 审计脚本:`muse-cloud/scripts/p1r-audit-api-coverage.py` - JSON 报告:`docs/superpowers/reports/p1r-api-coverage.json` - Markdown 报告:`docs/superpowers/reports/p1r-api-coverage.md` - Maven 门禁:`muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java` - 规格与计划命令同步更新: - `docs/superpowers/specs/2026-05-25-P1R-0-baseline-gate-design.md` - `docs/superpowers/plans/2026-05-25-P1R-0-baseline-gate.md` ## 关键结果 最终报告统计: ```text totalOperations=233 completedOperations=0 catchAllOperations=36 genericPersistenceOperations=180 ssePlaceholderOperations=2 missingOperations=0 ``` `completedOperations=0` 是预期结果。P1R-0 是基线审计,不跑领域真实验收,所以不能宣称任何 operation 已完成。 非真实实现状态规则已经统一到脚本、Maven 测试、规格和计划: - `catch_all` - `generic_persistence` - `sse_placeholder` - `missing` 这些 implementationStatus 对应的 completionStatus 只能是: - `incomplete` - `blocked` 不能是 `completed`,也不能是 `needs_verification`。 ## Maven 行为结论 计划原始命令是: ```bash cd muse-cloud mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest ``` 实测该命令会失败在上游模块,例如 `muse-common`: ```text No tests matching pattern "P1rApiCoverageReportTest" were executed! ``` 根因: - `-pl muse-server -am` 会把 `muse-server` 的上游 reactor 模块一起拉入构建。 - `-Dtest=P1rApiCoverageReportTest` 是全局 surefire 参数。 - 上游模块没有这个测试类,默认会因为“指定测试不存在”失败。 正确行为不是修改父 POM。父 POM 全局关闭 `failIfNoSpecifiedTests` 会改变全仓测试语义,容易掩盖测试名拼写错误。 正确的局部命令是: ```bash cd muse-cloud JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \ mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest -Dsurefire.failIfNoSpecifiedTests=false ``` 含义: - 运行环境必须是 Java 21。 - 上游 reactor 模块没有 `P1rApiCoverageReportTest` 不应失败。 - 真正需要执行目标门禁测试的是 `muse-server`。 ## 验证记录 执行过的验证: ```bash python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check ``` 结果: ```text Generated docs/superpowers/reports/p1r-api-coverage.json Generated docs/superpowers/reports/p1r-api-coverage.md ``` 报告一致性验证: ```bash python3 - <<'PY' import json from pathlib import Path report = json.loads(Path("docs/superpowers/reports/p1r-api-coverage.json").read_text()) summary = report["summary"] count = len(report["operations"]) assert summary["totalOperations"] == count, (summary["totalOperations"], count) assert summary["completedOperations"] == 0, summary["completedOperations"] for op in report["operations"]: assert op["completionStatus"] != "completed", op["operationId"] if op["implementationStatus"] in {"catch_all", "generic_persistence", "sse_placeholder", "missing"}: assert op["completionStatus"] in {"incomplete", "blocked"}, op["operationId"] print("P1R-0 report consistency OK:", count, "operations") PY ``` 结果: ```text P1R-0 report consistency OK: 233 operations ``` 脚本负例验证: - 将内存中的 non-real operation 临时改成 `needs_verification`。 - 调用 `validate_report(report)`。 - 结果按预期失败,说明脚本会拒绝 non-real `needs_verification`。 输出: ```text P1R-0 negative validate_report OK: adminCreateCallAttributionJob ``` Maven 门禁: ```bash cd muse-cloud JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \ mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest -Dsurefire.failIfNoSpecifiedTests=false ``` 结果: ```text Running cn.iocoder.muse.server.framework.api.P1rApiCoverageReportTest Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 BUILD SUCCESS ``` ## 当前集成状态 截至本留痕创建时: - P1R-0 已在 `feature/p1r-0-baseline-gate` 分支完成并提交。 - 用户曾要求合并到 `main`,但随后中断该回合并改为“进行总结留痕”。 - 因此当前记录只确认 P1R-0 分支完成,不确认已经合并到 `main`。 - 主工作区 `/Users/qingse/Sync/local-git/oh-my-muse` 当时仍在 `feature/p1-muse-cloud-backend-20260524`,且有其他未提交或未跟踪内容,不能当作干净 main 合并面。 后续如果要继续合并,需要重新执行: ```bash cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/feature-p1r-0-baseline-gate git status --short git branch --show-current ``` 确认干净后,再按实际 base 分支执行 merge / PR 流程。 ## 下个阶段 下个阶段是: ```text P1R-1 Content Real API spec + plan ``` P1R-1 不应该继续做基线扫描,而应该基于 P1R-0 报告开始真实业务 API 改造设计。 建议步骤: 1. 从 `docs/superpowers/reports/p1r-api-coverage.json` 筛出 Content 域 operation。 2. 分清哪些 Content operation 仍是 `catch_all` 或 `generic_persistence`。 3. 写 P1R-1 Content Real API 规格,明确真实 Controller、Service、DTO、持久化、幂等、权限和审计闭环。 4. 写 P1R-1 执行计划。 5. 再进入实现,不要直接从 catch-all 适配拼接到另一个临时 spec。 P1R-1 的核心目标是把 Content 域从“合同可响应”推进到“真实业务 API 可验收”。