oh-my-muse/docs/agent-specs/2026-06-11-P1RAccountCompletedApproval执行版.md
zizi f18116a1f5 test(p1r): 收口 Account 第一批 completed approval 门禁
Account first-batch approval promotes only the 10 verified profile, entitlement, balance snapshot, and quota adjustment operations to completed while keeping the rest of Account in needs_verification.
2026-06-11 13:47:13 +08:00

507 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# P1R Account Completed Approval 执行版
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` to implement this plan task-by-task after the explicit approval gate. Steps use checkbox syntax for tracking.
日期2026-06-11
## 结论
本执行版推荐第一轮只做 Account operation-level completed approval不做 Account domain-level 33/33 completed。
第一轮推荐审批 10 个 Account 本域闭合较强的 operation
```text
account:getCurrentUser
account:getProfile
account:updateProfile
account:adminListAccountUsers
account:adminGetUserEntitlements
account:getAppEntitlements
account:adminGetBalanceSnapshots
account:getAppBalanceSnapshots
account:adminCreateQuotaAdjustment
account:adminListQuotaAdjustments
```
审批后目标 coverage summary 为:
```text
total=233
completed=127
needsVerification=106
incomplete=0
genericPersistence=0
ssePlaceholder=0
```
Account 域目标状态为:
```text
account total=33
completed=10
needsVerification=23
```
本执行版只定义实现前置批准项、允许变更范围、TDD 顺序、验证命令、XML 防空跑和回滚策略。当前不得直接实现,不得修改 OpenAPI、scanner、coverage report、业务实现或 gate test。
```mermaid
flowchart TB
Current["当前 Account<br/>33 dedicated / needs_verification"] --> Exec["执行版<br/>锁定第一批 10 个 operation"]
Exec --> Review["fresh execution spec/scope review<br/>fresh execution quality/feasibility review"]
Review --> Approval{"用户明确批准 4 项<br/>operation list / operation-level / allowed diff / legacy gates"}
Approval -->|否| Stay["保持当前 coverage<br/>233/117/116"]
Approval -->|是| Red["TDD RED<br/>先改 Account/Coverage gates<br/>旧 report 必须失败"]
Red --> Green["TDD GREEN<br/>scanner operation allowlist + regenerate report"]
Green --> Verify["focused + P1R mixed + Flyway _test<br/>XML 防空跑 + protected diff"]
Verify --> FreshReview["fresh implementation review"]
```
## 当前事实
正确 worktree
```text
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
```
当前 HEAD
```text
df26bd9 test(p1r): 收口 Meta remaining 5 completed approval 门禁
```
当前 coverage summary
```text
233 117 116 0 0 0
```
当前 Account 事实:
- Account 33 个 operation 全部为 `dedicated / needs_verification`
- `APPROVED_COMPLETED_DOMAINS` 当前只包含 `ai``knowledge`
- `APPROVED_COMPLETED_OPERATIONS` 当前只包含 `events:streamEvents` 与 Meta 16 个 operation。
- `P1rAccountRealApiGateTest` 当前明确禁止 Account operation 标记为 `completed`
- `P1rApiCoverageReportTest` 当前断言 summary `completed=117`,并断言 Account 33 个 operation 继续 `needs_verification`
- `P1rEventsRealApiGateTest``P1rAiRealApiGateTest``P1rKnowledgeRealApiGateTest``P1rMarketRealApiGateTest` 仍硬编码当前 summary 或 Account needs_verification 口径;实现前必须把这些 legacy mixed gate 同步列入单独批准项。
## 执行边界
### 必须先获用户明确批准
实现前必须同时获得以下 4 项批准:
1. 批准第一轮 Account completed operation 精确清单为本执行版列出的 10 个 operation。
2. 批准只走 operation-level approval不把 `account` 加入 domain-level completed allowlist。
3. 批准按本执行版修改 scanner、coverage report、Account/Coverage gate、必要的 legacy mixed gate 和 memory。
4. 批准同步 4 个 legacy mixed gate 文件的 summary / Account 状态断言:
- `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`
未获 4 项批准前,不得实施本执行版。
### 本轮允许变更
获批后只允许修改以下路径:
- `muse-cloud/scripts/p1r-audit-api-coverage.py`
- `docs/superpowers/reports/p1r-api-coverage.json`
- `docs/superpowers/reports/p1r-api-coverage.md`
- `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/P1rAccountRealApiGateTest.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`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountEventsPublishFlywayMigrationIT.java`,仅当需要扩展 V11 Account 表/索引/约束 fresh assertion 时允许修改。
- `docs/agent-specs/.agent`
- `docs/agent-specs/2026-06-11-P1RAccountCompletedApproval审阅版.md`
- `docs/agent-specs/2026-06-11-P1RAccountCompletedApproval执行版.md`
- `docs/memorys/2026-06-11-P1RAccount状态推进.md`
如 implementation 发现必须修改 Account 业务实现、OpenAPI、Content/Market/Meta gate、数据库迁移或其它文件必须停下说明原因并重新取得用户批准。
### 本轮禁止变更
- 不修改 7 个 OpenAPI。
- 不修改 Account 业务实现来掩盖 coverage 缺口。
- 不新增或修改 Account domain-level completed allowlist。
- 不推进 `getAppUsage``adminListUsageRecords`
- 不推进 New-API、FileService/download、call attribution external source、Market projection、安全事件生产路径相关 operation。
- 不推进 Market、Content 或总 P1R completed。
## 第一轮审批清单
| operation key | Method | Path | 目标状态 | 完成证据边界 |
|---|---|---|---|---|
| `account:getCurrentUser` | `GET` | `/app-api/muse/me` | `dedicated / completed` | App 当前登录用户 owner、Member user + Account profile 读模型、缺 profile fallback、无写入副作用 |
| `account:getProfile` | `GET` | `/app-api/muse/profile` | `dedicated / completed` | App 当前登录用户 owner、Profile 读模型、缺 profile fallback、敏感联系字段不泄露 |
| `account:updateProfile` | `PATCH` | `/app-api/muse/profile` | `dedicated / completed` | `X-API-Version``X-Command-Id`、command replay、expectedVersion、审计、profile optimistic update |
| `account:adminListAccountUsers` | `GET` | `/admin-api/muse/account/users` | `dedicated / completed` | 管理端权限、分页、用户查询、Account DTO 转换 |
| `account:adminGetUserEntitlements` | `GET` | `/admin-api/muse/account/users/{userId}/entitlements` | `dedicated / completed` | 管理端权限、指定 userId、entitlement + balance 本域读模型 |
| `account:getAppEntitlements` | `GET` | `/app-api/muse/account/entitlements` | `dedicated / completed` | App 当前 owner、entitlement + balance 本域读模型 |
| `account:adminGetBalanceSnapshots` | `GET` | `/admin-api/muse/account/users/{userId}/balance-snapshots` | `dedicated / completed` | 管理端权限、指定 userId、balance snapshot 分页 |
| `account:getAppBalanceSnapshots` | `GET` | `/app-api/muse/account/balance-snapshots` | `dedicated / completed` | App 当前 owner、balance snapshot 分页 |
| `account:adminCreateQuotaAdjustment` | `POST` | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `dedicated / completed` | 管理端权限、`X-Command-Id`、quota guard、command replay、entitlement audit log、Account outbox、P1R-7e Events publish 证据 |
| `account:adminListQuotaAdjustments` | `GET` | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `dedicated / completed` | 同一 quota ledger 读侧、changeType allowlist、分页、非法 source filter 拒绝 |
## 保持 needs_verification 的 Account operation
以下 23 个 operation 必须保持 `dedicated / needs_verification`
```text
account:adminCreateCallAttributionJob
account:adminGetCallAttributionJob
account:adminGetIntegrationCallByCorrelation
account:adminListNewApiBindings
account:adminListPurchaseRecords
account:adminListUsageRecords
account:adminCreateNewApiBinding
account:adminCreateQuotaRequest
account:appDownloadExport
account:appCreateExportTask
account:appGetExportTask
account:appGetIntegrationCallByCorrelation
account:appListLicenses
account:getAppNewApiBinding
account:appRecheckNewApiBinding
account:appListPublishRecords
account:appListPurchases
account:appCreateQuotaRequest
account:appGetQuotaRequest
account:appListSecurityEvents
account:appGetSecurityEvent
account:appAcknowledgeSecurityEvent
account:getAppUsage
```
其中 `getAppUsage``adminListUsageRecords` 虽有 dedicated 实现和 focused tests但仍依赖 `muse_account_integration_call` / attribution source 的上游事实质量;本轮先不把 usage 读模型算作 completed避免绕过 New-API / attribution runtime 缺口。
## 证据矩阵
| 证据类型 | 必跑或必查内容 | 目的 |
|---|---|---|
| Account focused tests | Profile、Entitlement、Quota、Audit、Command、Guard、Controller tests | 证明 10 个 operation 的本域读写、owner、权限、审计、幂等、失败路径 |
| P1R Account gates | `P1rAccountRealApiGateTest``P1rApiCoverageReportTest` | 证明 only 10 Account operation completed23 个继续 needs_verification |
| P1R mixed gates | Events、AI、Knowledge、Market、Content、Meta、Account、Coverage gates | 防止非目标 domain 被连带推进 |
| Flyway `_test` | `P1rAccountEventsPublishFlywayMigrationIT` fresh rerun必要时扩展 V11 assertion | 证明 V1-V20 clean migrate 和 Account V11/V20 schema 可执行 |
| Coverage scanner | `python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check` | 证明 scanner/report 与 allowlist 口径一致 |
| XML 防空跑 | 逐个读取 surefire XML检查 tests、failures、errors、skipped | 防止 Maven 未跑目标类或旧 XML 假绿 |
| Protected diff | OpenAPI staged/unstaged diff 必须为空 | 证明没有通过改合同掩盖缺口 |
| Allowed diff | staged、unstaged、untracked 均必须落在允许清单 | 证明没有顺手扩大 scope |
## TDD 执行步骤
### Task 0实现前现场确认
- [ ] 确认 worktree
```bash
pwd
git -c core.quotePath=false status --short --branch
git log --oneline -5
jq -r '.summary | [.totalOperations,.completedOperations,.needsVerificationOperations,.incompleteOperations,.genericPersistenceOperations,.ssePlaceholderOperations] | @tsv' docs/superpowers/reports/p1r-api-coverage.json
```
预期:
```text
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
233 117 116 0 0 0
```
- [ ] 确认 Account 33 个 operation 仍全部是 `dedicated / needs_verification`
```bash
jq -r '.operations[] | select(.domain=="account") | [.operationId,.implementationStatus,.completionStatus] | @tsv' docs/superpowers/reports/p1r-api-coverage.json
```
- [ ] 确认 OpenAPI 与业务实现未在实施前有相关 diff
```bash
git diff -- docs/api-contracts
git diff -- muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member
```
### Task 1TDD RED先改 gate 期望
获批后先修改:
- `P1rApiCoverageReportTest.java`
- `P1rAccountRealApiGateTest.java`
- 必要的 4 个 legacy mixed gate
RED 期望:
- `P1rApiCoverageReportTest` 期望 completed `127`,但旧 report 仍是 `117`,必须失败。
- `P1rAccountRealApiGateTest` 期望 10 个 Account operation 为 `completed`,但旧 report 仍是 `needs_verification`,必须失败。
- 4 个 legacy mixed gate 期望 `completed=127``needsVerification=106`、Account `completed=10`、Account `needsVerification=23`,旧 report 下必须失败。
运行:
```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,P1rAccountRealApiGateTest,P1rEventsRealApiGateTest,P1rAiRealApiGateTest,P1rKnowledgeRealApiGateTest,P1rMarketRealApiGateTest \
-Dsurefire.failIfNoSpecifiedTests=false
```
预期:至少一个失败点来自旧 report 的 `117/116` 或 Account 10 个 operation 尚未 completed。若直接通过必须停下排查假绿。
### Task 2TDD GREEN最小 scanner/report 状态推进
只修改 `muse-cloud/scripts/p1r-audit-api-coverage.py`
- 不修改 `APPROVED_COMPLETED_DOMAINS`
- 只向 `APPROVED_COMPLETED_OPERATIONS` 追加 10 个 `account:*` operation key。
- 保持 completed 必须仍是 `dedicated` 的校验。
生成 report
```bash
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check
```
预期 summary
```text
total=233
completed=127
needsVerification=106
incomplete=0
genericPersistence=0
ssePlaceholder=0
```
预期 Account
```text
completed=10
needsVerification=23
```
### Task 3Account focused verification
运行 Account 本域 focused tests
```bash
cd muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -o test -pl muse-module-member/muse-module-member-server,muse-server -am \
-Dtest=AccountProfileServiceTest,AccountEntitlementServiceTest,AccountQuotaServiceTest,AccountAuditServiceTest,AccountCommandServiceTest,AccountOwnerGuardTest,AccountApiVersionGuardTest,AccountQuotaGuardTest,AdminAccountUserControllerTest,AppAccountProfileControllerTest,AppAccountEntitlementControllerTest,P1rAccountEventsPublishMigrationSqlTest,P1rAccountEventsPublishDependencyTest,P1rAccountEventsPublishEndToEndTest,P1rAccountRealApiGateTest,P1rApiCoverageReportTest \
-Dsurefire.failIfNoSpecifiedTests=false
```
必须读取以下 XML 并检查 `failures=0``errors=0``skipped=0`
| Test class | 最低 tests |
|---|---:|
| `AccountProfileServiceTest` | 19 |
| `AccountEntitlementServiceTest` | 8 |
| `AccountQuotaServiceTest` | 17 |
| `AccountAuditServiceTest` | 7 |
| `AccountCommandServiceTest` | 15 |
| `AccountOwnerGuardTest` | 3 |
| `AccountApiVersionGuardTest` | 3 |
| `AccountQuotaGuardTest` | 4 |
| `AdminAccountUserControllerTest` | 22 |
| `AppAccountProfileControllerTest` | 7 |
| `AppAccountEntitlementControllerTest` | 9 |
| `P1rAccountEventsPublishMigrationSqlTest` | 3 |
| `P1rAccountEventsPublishDependencyTest` | 2 |
| `P1rAccountEventsPublishEndToEndTest` | 4 |
| `P1rAccountRealApiGateTest` | 4 |
| `P1rApiCoverageReportTest` | 6 |
如实现修改了 Account gate 测试数量XML 检查的最低 tests 可高于上表,但不能低于上表。
### Task 4真实 PostgreSQL `_test` Flyway gate
fresh rerun `P1rAccountEventsPublishFlywayMigrationIT`。使用独立 `_test` 库,不能使用生产库或非 `_test` 库:
```bash
source ~/.config/muse-repo/infra.env
export P1R_FLYWAY_PASSWORD="$MUSE_POSTGRES_PASSWORD"
export P1R_ACCOUNT_TEST_DB=muse_p1r_account_completed_approval_test
psql "postgresql://$MUSE_POSTGRES_USERNAME:$MUSE_POSTGRES_PASSWORD@$MUSE_POSTGRES_HOST:$MUSE_POSTGRES_PORT/postgres" \
-tc "SELECT 1 FROM pg_database WHERE datname = '$P1R_ACCOUNT_TEST_DB'" | grep -q 1 || \
psql "postgresql://$MUSE_POSTGRES_USERNAME:$MUSE_POSTGRES_PASSWORD@$MUSE_POSTGRES_HOST:$MUSE_POSTGRES_PORT/postgres" \
-c "CREATE DATABASE $P1R_ACCOUNT_TEST_DB"
cd muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -o test -pl muse-server -am \
-Dtest=P1rAccountEventsPublishFlywayMigrationIT \
-Dflyway.postgresql.transactional.lock=false \
-Dp1r.flyway.locations=filesystem:sql/muse \
-Dp1r.flyway.url="jdbc:postgresql://$MUSE_POSTGRES_HOST:$MUSE_POSTGRES_PORT/$P1R_ACCOUNT_TEST_DB" \
-Dp1r.flyway.user="$MUSE_POSTGRES_USERNAME" \
-Djava.net.useSystemProxies=false \
-DsocksProxyHost= -DsocksProxyPort= \
-Dhttp.proxyHost= -Dhttp.proxyPort= \
-Dhttps.proxyHost= -Dhttps.proxyPort= \
-Dsurefire.failIfNoSpecifiedTests=false
```
必须检查 XML
| Test class | 最低 tests |
|---|---:|
| `P1rAccountEventsPublishFlywayMigrationIT` | 4 |
如果 reviewer 认为 V11 Account schema 对本轮 10 个 operation 的 evidence 不足,允许在该 IT 内补充 V11 表、索引、约束 assertion但不得新增迁移或修改业务实现。
### Task 5P1R mixed gate
运行 mixed gates
```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,P1rAccountRealApiGateTest,P1rEventsRealApiGateTest,P1rAiRealApiGateTest,P1rKnowledgeRealApiGateTest,P1rMarketRealApiGateTest,P1rContentRealApiGateTest,P1rMetaRealApiGateTest \
-Dsurefire.failIfNoSpecifiedTests=false
```
必须读取以下 XML
| Test class | 最低 tests |
|---|---:|
| `P1rApiCoverageReportTest` | 6 |
| `P1rAccountRealApiGateTest` | 4 |
| `P1rEventsRealApiGateTest` | 5 |
| `P1rAiRealApiGateTest` | 7 |
| `P1rKnowledgeRealApiGateTest` | 8 |
| `P1rMarketRealApiGateTest` | 6 |
| `P1rContentRealApiGateTest` | 5 |
| `P1rMetaRealApiGateTest` | 4 |
每个 XML 均必须 `failures=0``errors=0``skipped=0`
### Task 6报告与 diff gate
检查 summary
```bash
jq -r '.summary | [.totalOperations,.completedOperations,.needsVerificationOperations,.incompleteOperations,.genericPersistenceOperations,.ssePlaceholderOperations] | @tsv' docs/superpowers/reports/p1r-api-coverage.json
```
预期:
```text
233 127 106 0 0 0
```
检查 Account 10/23
```bash
python3 - <<'PY'
import json
from collections import Counter
from pathlib import Path
data = json.loads(Path("docs/superpowers/reports/p1r-api-coverage.json").read_text())
counter = Counter(op["completionStatus"] for op in data["operations"] if op["domain"] == "account")
print(counter)
PY
```
预期:
```text
Counter({'needs_verification': 23, 'completed': 10})
```
检查 OpenAPI protected diff
```bash
git diff --quiet -- docs/api-contracts
git diff --cached --quiet -- docs/api-contracts
```
检查 business implementation 不被修改:
```bash
git diff --quiet -- muse-cloud/muse-module-member/muse-module-member-server/src/main/java
git diff --cached --quiet -- muse-cloud/muse-module-member/muse-module-member-server/src/main/java
```
检查 whitespace
```bash
git diff --check
```
检查 allowed diff
```bash
git -c core.quotePath=false status --short
```
输出只能包含本执行版允许路径。若出现 OpenAPI、业务实现、迁移或非批准 gate 文件,必须停止。
### Task 7memory 与 `.agent`
实现通过后新增:
- `docs/memorys/2026-06-11-P1RAccount状态推进.md`
内容必须记录:
- 批准的 10 个 Account operation。
- 保持 `needs_verification` 的 23 个 Account operation 及原因。
- scanner/report/gate 修改范围。
- 所有验证命令、结果、XML 计数、Flyway `_test` 库名。
- protected diff 与 allowed diff 结果。
- 明确说明不代表 Account 33/33 completed不代表 Market/Content/总 P1R completed。
同时更新 `docs/agent-specs/.agent`,但只能记录事实,不写未验证结论。
### Task 8fresh implementation review
实现、验证和文档留痕后,必须派发两类 fresh reviewer
- spec/correctness reviewer检查 10 个 operation 是否严格匹配本执行版23 个 operation 是否仍 needs_verificationAccount domain allowlist 是否未新增。
- quality/data-integrity/testing reviewer检查 scanner/report/gate、XML 防空跑、Flyway `_test`、protected diff、allowed diff、rollback 是否可靠。
双 PASS 前不得提交、push 或宣称 Account completed approval 已收口。
## 回滚策略
如实现后需要撤回:
1.`APPROVED_COMPLETED_OPERATIONS` 移除 10 个 `account:*` key。
2. 重新运行:
```bash
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check
```
3. 恢复 gate 期望:
```text
summary completed=117
summary needsVerification=116
account completed=0
account needsVerification=33
```
4. 删除或修订本轮 memory保留失败原因。
5. 重新运行 Account/P1R focused gates 和 `git diff --check`
## 验收标准
执行版本身可以进入实现前批准点的条件:
1. 本文件已写入 `docs/agent-specs/2026-06-11-P1RAccountCompletedApproval执行版.md`
2. `.agent` 记录执行版当前状态。
3. `git diff --check` 通过。
4. OpenAPI、scanner、coverage report、业务实现当前无新增 diff。
5. fresh execution spec/scope review PASS。
6. fresh execution quality/feasibility review PASS。
实现完成条件必须等用户批准后另行满足,不由本执行版写入自动成立。