oh-my-muse/docs/agent-specs/2026-06-09-P1R7CompletedApproval执行版.md
zizi 85c5422cb8 test(p1r): 收口 P1R-7 completed approval 门禁
仅将 events:streamEvents 按用户批准推进为 completed,并保留 Events 其它 operation 与 Account/Content/Market/Meta 的 needs_verification 边界。
2026-06-10 10:34:15 +08:00

26 KiB
Raw Blame History

P1R7 Completed Approval 执行版

日期2026-06-09

结论

本执行版只推进 P1R-7 Events End-to-End Acceptance 的 completed approval 执行准备,审批对象唯一:

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 reviewPASS无 P0/P1/P2/P3 blocker。
  • Lorentz fresh final spec/scope reviewPASS无 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.
  • 当前最新提交:
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

totalOperations              233
completedOperations          100
needsVerificationOperations  133
incompleteOperations         0
genericPersistenceOperations 0
ssePlaceholderOperations     0

当前 domain 状态:

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

events streamEvents GET /app-api/muse/events dedicated needs_verification P1R-7 End-to-End Acceptance

P1R-7 evidence 现状

  • P1R-7a Events SSEstreamEvents 已从 sse_placeholder / incomplete 推进到 dedicated / needs_verification
  • P1R-7b AIAI terminal event -> AI outbox -> worker -> Events -> SSE evidence 已收口。
  • P1R-7c KnowledgeKnowledge source owner event -> Knowledge outbox -> worker -> Events -> SSE evidence 已收口。
  • P1R-7d MarketMarket governance terminal fact -> Market outbox -> worker -> Events -> SSE evidence 已收口。
  • P1R-7e AccountAccount quota adjustment terminal fact -> Account outbox -> worker -> Events -> SSE evidence 已收口。
  • P1R-7f ContentContent 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 必须变成:

totalOperations              233
completedOperations          101
needsVerificationOperations  132
incompleteOperations         0
genericPersistenceOperations 0
ssePlaceholderOperations     0

domain 状态必须变成:

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 必须是:

events streamEvents GET /app-api/muse/events dedicated completed P1R-7 End-to-End Acceptance

实现设计

Scanner approval 模型

当前 scanner 使用:

APPROVED_COMPLETED_DOMAINS = {"ai", "knowledge"}

后续实现必须保留该集合,并新增 operation-level 白名单:

APPROVED_COMPLETED_OPERATIONS = {"events:streamEvents"}

推荐新增 helper

def operation_key(domain: str, operation_id: str) -> str:
    return f"{domain}:{operation_id}"

dedicated_status_for 必须从只接收 domain 改为至少接收 domainoperation_id

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

dedicated_completion, dedicated_notes = dedicated_status_for(domain, operation_id)

approved_completed_operation(operation) 必须允许 approved domain 或 approved operation key

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 白名单:

/** 已获用户批准、并有 P1R 外部端到端验收证据支撑的 completed operation。 */
private static final Set<String> APPROVED_COMPLETED_OPERATIONS = Set.of(
        "events:streamEvents"
);

推荐新增 helper

private static String operationKey(JsonNode operation) {
    return operation.path("domain").asText() + ":" + operation.path("operationId").asText();
}

should_only_mark_approved_dedicated_operations_as_completed 必须改为:

assertTrue(
        APPROVED_COMPLETED_DOMAINS.contains(operation.path("domain").asText())
                || APPROVED_COMPLETED_OPERATIONS.contains(operationKey(operation)),
        operationId + " 只有已批准 domain 或 operation 可以标记为 completed"
);

必须新增测试断言 completed summary 与非目标 domain

@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 执行:
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check

并把真实 report 更新纳入本阶段提交。

执行步骤

Task 0preflight

执行位置:

cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0

命令:

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 更新前,必须先隔离验证:

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

233 101 132 0 0 0

期望 domain

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

events streamEvents GET /app-api/muse/events dedicated completed P1R-7 End-to-End Acceptance

回到真实 worktree 后,必须确认真实 report 仍无 diff

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 用户批准后才允许执行:

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

输出必须等于 Task 4 期望。

Task 6P1R focused gates

muse-cloud 执行:

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 testsfailures/errors/skipped 必须均为 0。

执行后必须用 XML 计数脚本确认每个目标类实际运行,禁止空跑:

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 7protected diff 与 whitespace

执行:

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、非目标配置、非目标测试或未跟踪文件混入

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/reportmuse-cloud/scripts/p1r-audit-api-coverage.pydocs/superpowers/reports/* 允许有本阶段目标 diff但 OpenAPI 仍必须为空。 任何 allowed-diff 之外的路径都必须停止并说明来源;不得把额外业务实现、配置、测试或 OpenAPI 改动混入本阶段。

Task 8留痕

用户批准并完成真实推进后,新增:

docs/memorys/2026-06-09-P1R7CompletedApproval状态推进.md

必须记录:

  • 用户批准点。
  • old summary233 100 133 0 0 0
  • new summary233 101 132 0 0 0
  • 唯一新增 completedevents: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 9fresh 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。