# P1R7 Completed Approval 执行版 日期:2026-06-09 ## 结论 本执行版只推进 P1R-7 Events End-to-End Acceptance 的 completed approval 执行准备,审批对象唯一: ```text events:streamEvents / GET /app-api/muse/events ``` 推荐实现方式是 operation-level approval:保留既有 AI / Knowledge domain-level completed,新增 `events:streamEvents` 单项 operation-level completed。禁止把整个 `events` domain 加入 completed 白名单,禁止连带推进 Market、Account、Content、Meta 或总 P1R-7 completed。 本执行版当前只允许进入 fresh execution review;双 PASS 前不得实现、不得修改 scanner、不得修改 coverage report、不得提交或 push。执行版双 PASS 后,仍必须由用户单独明确批准,才允许在真实 worktree 更新 scanner / report / gate。 ## Review 前置状态 审阅版: - `docs/agent-specs/2026-06-09-P1R7CompletedApproval审阅版.md` 审阅版 fresh review gate: - Curie fresh quality/feasibility review:PASS,无 P0/P1/P2/P3 blocker。 - Lorentz fresh final spec/scope review:PASS,无 P0/P1 blocker。 - Descartes 超时关闭,不计入 gate。 - Godel 返回空结果,不计入 gate。 - Gibbs 对旧版 PASS 后提出的非阻塞反馈已修订到审阅版,不计入最终新版本 PASS gate。 审阅版双 PASS 只代表可以编写本执行版,不代表用户已经批准真实 coverage 状态推进。 ## 当前已验证事实 ### 工作区 - 正确 worktree:`/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0`。 - 当前分支:`dev/1.0.0`。 - `git pull --ff-only origin dev/1.0.0` 已返回 `Already up to date.`。 - 当前最新提交: ```text f84c18f test(p1r): 收口 Content 事件传播真实链路门禁 ``` - 当前未提交变更只应来自 completed approval 文档: - `docs/agent-specs/.agent` - `docs/agent-specs/2026-06-09-P1R7CompletedApproval审阅版.md` - `docs/agent-specs/2026-06-09-P1R7CompletedApproval执行版.md` ### 当前 coverage 当前真实 coverage summary: ```text totalOperations 233 completedOperations 100 needsVerificationOperations 133 incompleteOperations 0 genericPersistenceOperations 0 ssePlaceholderOperations 0 ``` 当前 domain 状态: ```text account 33 dedicated/needs_verification:33 ai 41 dedicated/completed:41 content 51 dedicated/needs_verification:51 events 1 dedicated/needs_verification:1 knowledge 59 dedicated/completed:59 market 32 dedicated/needs_verification:32 meta 16 dedicated/needs_verification:16 ``` Events 当前唯一 operation: ```text events streamEvents GET /app-api/muse/events dedicated needs_verification P1R-7 End-to-End Acceptance ``` ### P1R-7 evidence 现状 - P1R-7a Events SSE:`streamEvents` 已从 `sse_placeholder / incomplete` 推进到 `dedicated / needs_verification`。 - P1R-7b AI:AI terminal event -> AI outbox -> worker -> Events -> SSE evidence 已收口。 - P1R-7c Knowledge:Knowledge source owner event -> Knowledge outbox -> worker -> Events -> SSE evidence 已收口。 - P1R-7d Market:Market governance terminal fact -> Market outbox -> worker -> Events -> SSE evidence 已收口。 - P1R-7e Account:Account quota adjustment terminal fact -> Account outbox -> worker -> Events -> SSE evidence 已收口。 - P1R-7f Content:Content `saveBlock` 首次成功 -> Content outbox -> worker -> Events -> SSE evidence 已收口。 这些 evidence 支撑 `events:streamEvents` completed approval,但不支撑 Market / Account / Content / Meta domain completed。 ## 范围 本执行版允许的后续实现范围: - 修改 `muse-cloud/scripts/p1r-audit-api-coverage.py`。 - 修改 `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java`。 - 在用户明确批准后,重新生成: - `docs/superpowers/reports/p1r-api-coverage.json` - `docs/superpowers/reports/p1r-api-coverage.md` - 新增 completed approval 真实推进留痕: - `docs/memorys/2026-06-09-P1R7CompletedApproval状态推进.md` - 更新: - `docs/agent-specs/.agent` 本执行版禁止: - 修改任何 OpenAPI: - `docs/api-contracts/account/openapi.yaml` - `docs/api-contracts/ai/openapi.yaml` - `docs/api-contracts/content/openapi.yaml` - `docs/api-contracts/events/openapi.yaml` - `docs/api-contracts/knowledge/openapi.yaml` - `docs/api-contracts/market/openapi.yaml` - `docs/api-contracts/meta/openapi.yaml` - 修改业务实现代码。 - 修改 Events source owner propagation 实现。 - 把 `events` 整个 domain 加入 approved domain。 - 推进 Market 32 operations completed。 - 推进 Account 33 operations completed。 - 推进 Content 51 operations completed。 - 推进 Meta 16 operations completed。 - 把 P1R-7f 或任一 owner evidence 直接写成该 owner domain completed。 - 宣称总 P1R / 全业务域 completed。 ## 目标状态 用户明确批准并完成实现后,coverage summary 必须变成: ```text totalOperations 233 completedOperations 101 needsVerificationOperations 132 incompleteOperations 0 genericPersistenceOperations 0 ssePlaceholderOperations 0 ``` domain 状态必须变成: ```text account 33 dedicated/needs_verification:33 ai 41 dedicated/completed:41 content 51 dedicated/needs_verification:51 events 1 dedicated/completed:1 knowledge 59 dedicated/completed:59 market 32 dedicated/needs_verification:32 meta 16 dedicated/needs_verification:16 ``` 唯一新增 completed operation 必须是: ```text events streamEvents GET /app-api/muse/events dedicated completed P1R-7 End-to-End Acceptance ``` ## 实现设计 ### Scanner approval 模型 当前 scanner 使用: ```python APPROVED_COMPLETED_DOMAINS = {"ai", "knowledge"} ``` 后续实现必须保留该集合,并新增 operation-level 白名单: ```python APPROVED_COMPLETED_OPERATIONS = {"events:streamEvents"} ``` 推荐新增 helper: ```python def operation_key(domain: str, operation_id: str) -> str: return f"{domain}:{operation_id}" ``` `dedicated_status_for` 必须从只接收 `domain` 改为至少接收 `domain` 与 `operation_id`: ```python def dedicated_status_for(domain: str, operation_id: str) -> tuple[str, str]: if domain in APPROVED_COMPLETED_DOMAINS or operation_key(domain, operation_id) in APPROVED_COMPLETED_OPERATIONS: return ( "completed", "Dedicated entry exists; user-approved P1R acceptance evidence allows this operation to advance to completed coverage.", ) return ( "needs_verification", "Dedicated entry exists; later P1R stage must verify DTO, state machine, persistence, and real external closure.", ) ``` `classify_implementation` 调用点必须传入 `operation_id`: ```python dedicated_completion, dedicated_notes = dedicated_status_for(domain, operation_id) ``` `approved_completed_operation(operation)` 必须允许 approved domain 或 approved operation key: ```python def approved_completed_operation(operation: dict[str, Any]) -> bool: if operation["implementationStatus"] != "dedicated": return False if operation["domain"] in APPROVED_COMPLETED_DOMAINS: return True return operation_key(operation["domain"], operation["operationId"]) in APPROVED_COMPLETED_OPERATIONS ``` 中文注释必须说明:AI / Knowledge 是历史 domain-level 用户批准;Events 本次只批准 `streamEvents`,不得给未来 Events operation 自动继承 completed。 ### Report gate approval 模型 `P1rApiCoverageReportTest` 必须同步新增 operation-level 白名单: ```java /** 已获用户批准、并有 P1R 外部端到端验收证据支撑的 completed operation。 */ private static final Set APPROVED_COMPLETED_OPERATIONS = Set.of( "events:streamEvents" ); ``` 推荐新增 helper: ```java private static String operationKey(JsonNode operation) { return operation.path("domain").asText() + ":" + operation.path("operationId").asText(); } ``` `should_only_mark_approved_dedicated_operations_as_completed` 必须改为: ```java assertTrue( APPROVED_COMPLETED_DOMAINS.contains(operation.path("domain").asText()) || APPROVED_COMPLETED_OPERATIONS.contains(operationKey(operation)), operationId + " 只有已批准 domain 或 operation 可以标记为 completed" ); ``` 必须新增测试断言 completed summary 与非目标 domain: ```java @Test void should_only_promote_events_stream_events_for_p1r7_completed_approval() throws IOException { JsonNode operations = readOperations(); int completed = 0; for (JsonNode operation : operations) { if ("completed".equals(operation.path("completionStatus").asText())) { completed++; } } assertEquals(101, completed, "P1R-7 completed approval 后 completed 总数只能从 100 增至 101"); assertOperationStatus("events", "streamEvents", "dedicated", "completed"); assertDomainStatusCount("market", "dedicated", "needs_verification", 32); assertDomainStatusCount("account", "dedicated", "needs_verification", 33); assertDomainStatusCount("content", "dedicated", "needs_verification", 51); assertDomainStatusCount("meta", "dedicated", "needs_verification", 16); } ``` helper 可以按本测试类现有风格实现,不做长期抽象。 ### Coverage report 生成 用户明确批准前: - 只能在 `/tmp` 隔离副本验证 scanner 修改后的报告输出。 - 真实 worktree 的 `docs/superpowers/reports/p1r-api-coverage.json` 和 `.md` 必须保持无 diff。 用户明确批准后: - 才允许在真实 worktree 执行: ```bash python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check ``` 并把真实 report 更新纳入本阶段提交。 ## 执行步骤 ### Task 0:preflight 执行位置: ```bash cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0 ``` 命令: ```bash pwd git status --short --branch git log --oneline -5 git pull --ff-only origin dev/1.0.0 git diff --name-only -- docs/api-contracts/account/openapi.yaml docs/api-contracts/ai/openapi.yaml docs/api-contracts/content/openapi.yaml docs/api-contracts/events/openapi.yaml docs/api-contracts/knowledge/openapi.yaml docs/api-contracts/market/openapi.yaml docs/api-contracts/meta/openapi.yaml muse-cloud/scripts/p1r-audit-api-coverage.py docs/superpowers/reports/p1r-api-coverage.json docs/superpowers/reports/p1r-api-coverage.md git diff --cached --name-only -- docs/api-contracts/account/openapi.yaml docs/api-contracts/ai/openapi.yaml docs/api-contracts/content/openapi.yaml docs/api-contracts/events/openapi.yaml docs/api-contracts/knowledge/openapi.yaml docs/api-contracts/market/openapi.yaml docs/api-contracts/meta/openapi.yaml muse-cloud/scripts/p1r-audit-api-coverage.py docs/superpowers/reports/p1r-api-coverage.json docs/superpowers/reports/p1r-api-coverage.md ``` 期望: - `pwd` 是正确 worktree。 - `git pull` 为 fast-forward 或 already up to date。 - protected staged / unstaged diff 为空。 - 若存在非本文档范围的 dirty 变更,必须停止并先确认来源。 ### Task 1:执行版 review gate 本文件写完后必须派发: - fresh execution spec/scope review。 - fresh execution quality/feasibility review。 双 PASS 前不得实现 Task 2 之后任何内容。 ### Task 2:用户 completed 推进批准 执行版双 PASS 后,必须让用户明确批准以下三项: 1. 本轮只审批 `events:streamEvents / GET /app-api/muse/events`。 2. 采用 operation-level approval,不采用 `events` domain-level 白名单。 3. 允许在真实 worktree 修改 scanner、coverage gate test 与 coverage report,把 completed summary 从 `100/133` 推进到 `101/132`。 没有这三项明确批准,不得进入 Task 3。 ### Task 3:修改 scanner 与 report gate 允许修改: - `muse-cloud/scripts/p1r-audit-api-coverage.py` - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java` - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rEventsRealApiGateTest.java` - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRealApiGateTest.java` - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rKnowledgeRealApiGateTest.java` - `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMarketRealApiGateTest.java` 必须做到: - 新增 `APPROVED_COMPLETED_OPERATIONS = {"events:streamEvents"}`。 - `dedicated_status_for` 支持 operation-level approval。 - `approved_completed_operation` 支持 approved domain 或 approved operation key。 - JUnit gate 同步支持 operation-level approval。 - JUnit gate 新增 `events:streamEvents` 唯一新增 completed 的断言。 - JUnit gate 明确断言 Market / Account / Content / Meta 仍为 `dedicated / needs_verification`。 - 既有 RealApi gate 只允许同步本轮 approved coverage 口径: - `completedOperations = 101` - `needsVerificationOperations = 132` - `events:streamEvents = dedicated / completed` - `summary.ssePlaceholderOperations = 0` - 非目标 Market / Account / Content / Meta 仍为 `dedicated / needs_verification` 不得修改: - OpenAPI。 - 业务实现。 - P1R owner propagation 代码。 ### Task 4:隔离 scanner 预验证 在真实 report 更新前,必须先隔离验证: ```bash tmpdir=$(mktemp -d /tmp/p1r7-completed-approval-impl-scan.XXXXXX) rsync -a --delete --exclude .git --exclude 'muse-cloud/**/target' ./ "$tmpdir"/ cd "$tmpdir" python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check jq -r '.summary | [.totalOperations,.completedOperations,.needsVerificationOperations,.incompleteOperations,.genericPersistenceOperations,.ssePlaceholderOperations] | @tsv' docs/superpowers/reports/p1r-api-coverage.json jq -r '.operations | group_by(.domain)[] | [.[0].domain, (length|tostring), ([group_by(.implementationStatus + "/" + .completionStatus)[] | (.[0].implementationStatus + "/" + .[0].completionStatus + ":" + (length|tostring))] | join(", "))] | @tsv' docs/superpowers/reports/p1r-api-coverage.json jq -r '.operations[] | select(.domain == "events") | [.domain,.operationId,.method,.path,.implementationStatus,.completionStatus,.targetStage] | @tsv' docs/superpowers/reports/p1r-api-coverage.json ``` 期望 summary: ```text 233 101 132 0 0 0 ``` 期望 domain: ```text account dedicated/needs_verification:33 ai dedicated/completed:41 content dedicated/needs_verification:51 events dedicated/completed:1 knowledge dedicated/completed:59 market dedicated/needs_verification:32 meta dedicated/needs_verification:16 ``` 期望 Events: ```text events streamEvents GET /app-api/muse/events dedicated completed P1R-7 End-to-End Acceptance ``` 回到真实 worktree 后,必须确认真实 report 仍无 diff: ```bash cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0 git diff --name-only -- docs/superpowers/reports/p1r-api-coverage.json docs/superpowers/reports/p1r-api-coverage.md ``` ### Task 5:真实 report 更新 只有 Task 2 用户批准后才允许执行: ```bash python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check ``` 随后必须核对: ```bash jq -r '.summary | [.totalOperations,.completedOperations,.needsVerificationOperations,.incompleteOperations,.genericPersistenceOperations,.ssePlaceholderOperations] | @tsv' docs/superpowers/reports/p1r-api-coverage.json jq -r '.operations | group_by(.domain)[] | [.[0].domain, (length|tostring), ([group_by(.implementationStatus + "/" + .completionStatus)[] | (.[0].implementationStatus + "/" + .[0].completionStatus + ":" + (length|tostring))] | join(", "))] | @tsv' docs/superpowers/reports/p1r-api-coverage.json jq -r '.operations[] | select(.domain == "events") | [.domain,.operationId,.method,.path,.implementationStatus,.completionStatus,.targetStage] | @tsv' docs/superpowers/reports/p1r-api-coverage.json ``` 输出必须等于 Task 4 期望。 ### Task 6:P1R focused gates 从 `muse-cloud` 执行: ```bash JAVA_HOME=$(/usr/libexec/java_home -v 21) mvn -o test \ -pl muse-server -am \ -Dtest=P1rContentEventsPublishMigrationSqlTest,P1rContentEventsPublishDependencyTest,P1rContentEventsPublishEndToEndTest,P1rAccountEventsPublishMigrationSqlTest,P1rAccountEventsPublishDependencyTest,P1rAccountEventsPublishEndToEndTest,P1rMarketEventsPublishMigrationSqlTest,P1rMarketEventsPublishDependencyTest,P1rMarketEventsPublishEndToEndTest,P1rKnowledgeEventsPublishMigrationSqlTest,P1rKnowledgeEventsPublishDependencyTest,P1rKnowledgeEventsPublishEndToEndTest,P1rAiEventsPublishMigrationSqlTest,P1rAiEventsPublishDependencyTest,P1rAiEventsPublishEndToEndTest,P1rApiCoverageReportTest,P1rEventsRealApiGateTest,P1rEventsRouteOwnershipTest,P1rAiRealApiGateTest,P1rAiRouteOwnershipTest,P1rKnowledgeRealApiGateTest,P1rKnowledgeRouteOwnershipTest,P1rMarketRealApiGateTest,P1rMarketRouteOwnershipTest,P1rAccountRealApiGateTest,P1rAccountRouteOwnershipTest,P1rContentRealApiGateTest,P1rMetaRealApiGateTest \ -Dsurefire.failIfNoSpecifiedTests=false ``` 目标测试类和静态 test count 下限: | 测试类 | 最少 tests | |---|---:| | `P1rContentEventsPublishMigrationSqlTest` | 3 | | `P1rContentEventsPublishDependencyTest` | 2 | | `P1rContentEventsPublishEndToEndTest` | 5 | | `P1rAccountEventsPublishMigrationSqlTest` | 3 | | `P1rAccountEventsPublishDependencyTest` | 2 | | `P1rAccountEventsPublishEndToEndTest` | 4 | | `P1rMarketEventsPublishMigrationSqlTest` | 3 | | `P1rMarketEventsPublishDependencyTest` | 2 | | `P1rMarketEventsPublishEndToEndTest` | 4 | | `P1rKnowledgeEventsPublishMigrationSqlTest` | 3 | | `P1rKnowledgeEventsPublishDependencyTest` | 2 | | `P1rKnowledgeEventsPublishEndToEndTest` | 5 | | `P1rAiEventsPublishMigrationSqlTest` | 4 | | `P1rAiEventsPublishDependencyTest` | 2 | | `P1rAiEventsPublishEndToEndTest` | 4 | | `P1rApiCoverageReportTest` | 6 | | `P1rEventsRealApiGateTest` | 5 | | `P1rEventsRouteOwnershipTest` | 4 | | `P1rAiRealApiGateTest` | 7 | | `P1rAiRouteOwnershipTest` | 7 | | `P1rKnowledgeRealApiGateTest` | 8 | | `P1rKnowledgeRouteOwnershipTest` | 6 | | `P1rMarketRealApiGateTest` | 6 | | `P1rMarketRouteOwnershipTest` | 4 | | `P1rAccountRealApiGateTest` | 4 | | `P1rAccountRouteOwnershipTest` | 4 | | `P1rContentRealApiGateTest` | 5 | | `P1rMetaRealApiGateTest` | 4 | 合计最少 `108` tests,failures/errors/skipped 必须均为 0。 执行后必须用 XML 计数脚本确认每个目标类实际运行,禁止空跑: ```bash python3 - <<'PY' from pathlib import Path import xml.etree.ElementTree as ET expected = { "P1rContentEventsPublishMigrationSqlTest": 3, "P1rContentEventsPublishDependencyTest": 2, "P1rContentEventsPublishEndToEndTest": 5, "P1rAccountEventsPublishMigrationSqlTest": 3, "P1rAccountEventsPublishDependencyTest": 2, "P1rAccountEventsPublishEndToEndTest": 4, "P1rMarketEventsPublishMigrationSqlTest": 3, "P1rMarketEventsPublishDependencyTest": 2, "P1rMarketEventsPublishEndToEndTest": 4, "P1rKnowledgeEventsPublishMigrationSqlTest": 3, "P1rKnowledgeEventsPublishDependencyTest": 2, "P1rKnowledgeEventsPublishEndToEndTest": 5, "P1rAiEventsPublishMigrationSqlTest": 4, "P1rAiEventsPublishDependencyTest": 2, "P1rAiEventsPublishEndToEndTest": 4, "P1rApiCoverageReportTest": 6, "P1rEventsRealApiGateTest": 5, "P1rEventsRouteOwnershipTest": 4, "P1rAiRealApiGateTest": 7, "P1rAiRouteOwnershipTest": 7, "P1rKnowledgeRealApiGateTest": 8, "P1rKnowledgeRouteOwnershipTest": 6, "P1rMarketRealApiGateTest": 6, "P1rMarketRouteOwnershipTest": 4, "P1rAccountRealApiGateTest": 4, "P1rAccountRouteOwnershipTest": 4, "P1rContentRealApiGateTest": 5, "P1rMetaRealApiGateTest": 4, } report_dir = Path("muse-server/target/surefire-reports") total = 0 for cls, minimum in expected.items(): path = report_dir / f"TEST-cn.iocoder.muse.server.framework.api.{cls}.xml" if not path.exists(): raise SystemExit(f"missing surefire XML: {cls}") root = ET.parse(path).getroot() tests = int(root.attrib.get("tests", "0")) failures = int(root.attrib.get("failures", "0")) errors = int(root.attrib.get("errors", "0")) skipped = int(root.attrib.get("skipped", "0")) print(f"{cls}\t{tests}\t{failures}\t{errors}\t{skipped}") if tests < minimum or failures or errors or skipped: raise SystemExit(f"invalid surefire result: {cls}") total += tests if total < 108: raise SystemExit(f"total tests too small: {total}") print(f"p1r_completed_approval_gate_tests={total}") PY ``` ### Task 7:protected diff 与 whitespace 执行: ```bash git diff --check git diff --name-only -- docs/api-contracts/account/openapi.yaml docs/api-contracts/ai/openapi.yaml docs/api-contracts/content/openapi.yaml docs/api-contracts/events/openapi.yaml docs/api-contracts/knowledge/openapi.yaml docs/api-contracts/market/openapi.yaml docs/api-contracts/meta/openapi.yaml git diff --cached --name-only -- docs/api-contracts/account/openapi.yaml docs/api-contracts/ai/openapi.yaml docs/api-contracts/content/openapi.yaml docs/api-contracts/events/openapi.yaml docs/api-contracts/knowledge/openapi.yaml docs/api-contracts/market/openapi.yaml docs/api-contracts/meta/openapi.yaml ``` 同时必须执行最终 allowed-diff gate,防止业务实现、OpenAPI、非目标配置、非目标测试或未跟踪文件混入: ```bash python3 - <<'PY' from pathlib import Path import subprocess import sys allowed_exact = { "muse-cloud/scripts/p1r-audit-api-coverage.py", "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java", "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rEventsRealApiGateTest.java", "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRealApiGateTest.java", "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rKnowledgeRealApiGateTest.java", "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMarketRealApiGateTest.java", "docs/superpowers/reports/p1r-api-coverage.json", "docs/superpowers/reports/p1r-api-coverage.md", "docs/agent-specs/.agent", "docs/agent-specs/2026-06-09-P1R7CompletedApproval审阅版.md", "docs/agent-specs/2026-06-09-P1R7CompletedApproval执行版.md", "docs/memorys/2026-06-09-P1R7CompletedApproval状态推进.md", } def changed(args): out = subprocess.check_output(["git", "-c", "core.quotePath=false", *args], text=True) return {line.strip() for line in out.splitlines() if line.strip()} paths = ( changed(["diff", "--name-only"]) | changed(["diff", "--cached", "--name-only"]) | changed(["ls-files", "--others", "--exclude-standard"]) ) unexpected = sorted(path for path in paths if path not in allowed_exact) if unexpected: print("unexpected_paths=" + ",".join(unexpected)) sys.exit(1) print("allowed_diff_gate=PASS") PY ``` 期望: - `git diff --check` 无输出。 - OpenAPI staged / unstaged diff 为空。 - allowed-diff gate 输出 `allowed_diff_gate=PASS`。 - `git status --short --untracked-files=all` 只能显示 allowed-diff gate 允许的路径。 如果本阶段已经在用户批准后修改 scanner/report,则 `muse-cloud/scripts/p1r-audit-api-coverage.py` 与 `docs/superpowers/reports/*` 允许有本阶段目标 diff;但 OpenAPI 仍必须为空。 任何 allowed-diff 之外的路径都必须停止并说明来源;不得把额外业务实现、配置、测试或 OpenAPI 改动混入本阶段。 ### Task 8:留痕 用户批准并完成真实推进后,新增: ```text docs/memorys/2026-06-09-P1R7CompletedApproval状态推进.md ``` 必须记录: - 用户批准点。 - old summary:`233 100 133 0 0 0`。 - new summary:`233 101 132 0 0 0`。 - 唯一新增 completed:`events:streamEvents`。 - Market / Account / Content / Meta 仍为 `dedicated / needs_verification`。 - scanner/test/report 修改文件。 - `git diff --stat` 与关键 diff 摘要,证明唯一状态推进来自 `events:streamEvents` operation-level approval。 - OpenAPI diff 为空。 - allowed-diff gate 结果。 - P1R focused gates 与 XML 计数。 - fresh implementation review 结果。 同时更新 `docs/agent-specs/.agent`。 ### Task 9:fresh implementation review 实现和验证完成后,必须派发: - fresh implementation spec/correctness review。 - fresh implementation quality/data-integrity/testing review。 双 PASS 前不得提交、push 或宣称 completed 已完成。 ## 完成条件 只有全部满足,才可说 P1R-7 Events completed approval 已完成: 1. 用户明确批准 Task 2 三项。 2. operation-level approval 已落地,未使用 `events` domain-level 白名单。 3. coverage summary 为 `233 / 101 / 132 / 0 / 0 / 0`。 4. `events:streamEvents` 是唯一新增 completed operation。 5. Market / Account / Content / Meta 仍为 `dedicated / needs_verification`。 6. OpenAPI diff 为空。 7. scanner `--check`、P1R focused gates、XML 计数、`git diff --check`、allowed-diff gate 与 `git status --short --untracked-files=all` 通过。 8. completed approval 状态推进留痕已写入 `docs/memorys`。 9. fresh implementation 双 review PASS。 10. 提交 / push 仍需用户明确指令。 ## 回滚策略 如果 scanner 或 gates 失败: - 不运行真实 report 更新,或回退本阶段 report diff。 - 保留审阅版 / 执行版文档与失败留痕。 - 修正 scanner/test 后重新跑 `/tmp` 隔离 scanner。 如果用户未批准 Task 2: - 保持 `events:streamEvents = dedicated / needs_verification`。 - 不修改 scanner、coverage report 或 gate test。 如果误推进非目标 domain: - 立即停止。 - 将 Market / Account / Content / Meta 恢复为 `dedicated / needs_verification`。 - 重跑 scanner、P1R gate、protected diff。