# P1R Account Completed Approval 审阅版 日期:2026-06-11 ## 结论 不建议把 Account 33 个 operation 一次性整域推进 `completed`。 推荐把 Account Completed Approval 拆成 operation-level 或证据切片推进:先审批 Account 本域已经形成闭环的读写与审计切片;New-API、FileService/download、call attribution 外部来源、Market purchase/license/publish projection 等跨 owner 链路继续保持 `dedicated / needs_verification`,直到有真实 runtime 或明确验收替代边界。 本审阅版只冻结 Account completed approval 的范围判断、证据缺口、推荐审批粒度和后续执行版要求。不修改 OpenAPI,不修改 scanner,不修改 coverage report,不修改业务实现,也不把 Account 或其它 domain 推进 `completed`。 ```mermaid flowchart TB Start["当前 coverage
Account 33 dedicated / needs_verification"] --> Review["Account completed approval 审阅版
冻结证据标准"] Review --> Split{"是否整域 33/33 completed?"} Split -->|否,推荐| OpLevel["按证据切片 operation-level approval"] Split -->|是,不推荐| DomainLevel["domain-level approval
需 New-API/FileService/Market/Attribution 全闭环"] OpLevel --> Exec["执行版
列出可审批 operation 与保留 needs_verification operation"] Exec --> FreshReview["fresh spec/scope review
fresh quality/feasibility review"] FreshReview --> UserApproval{"用户明确批准
Account 状态推进?"} UserApproval -->|否| Stay["保持 Account 33 needs_verification"] UserApproval -->|是| Change["最小修改 scanner/report/gates
运行 focused + P1R + _test + XML 防空跑"] ``` ## 当前事实状态 工作区: ```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 total=233 completed=117 needsVerification=116 incomplete=0 genericPersistence=0 ssePlaceholder=0 ``` 当前按 domain 聚合: ```text account total=33 completed=0 needsVerification=33 ai total=41 completed=41 needsVerification=0 content total=51 completed=0 needsVerification=51 events total=1 completed=1 needsVerification=0 knowledge total=59 completed=59 needsVerification=0 market total=32 completed=0 needsVerification=32 meta total=16 completed=16 needsVerification=0 ``` Account 33 个 operation 当前全部为 `dedicated / needs_verification`: | operationId | Method | Path | 当前状态 | |---|---|---|---| | `adminCreateCallAttributionJob` | `POST` | `/admin-api/muse/account/call-attribution-jobs` | `dedicated / needs_verification` | | `adminGetCallAttributionJob` | `GET` | `/admin-api/muse/account/call-attribution-jobs/{jobId}` | `dedicated / needs_verification` | | `adminGetIntegrationCallByCorrelation` | `GET` | `/admin-api/muse/account/integration-calls/by-correlation/{correlationId}` | `dedicated / needs_verification` | | `adminListNewApiBindings` | `GET` | `/admin-api/muse/account/new-api-bindings` | `dedicated / needs_verification` | | `adminListPurchaseRecords` | `GET` | `/admin-api/muse/account/purchase-records` | `dedicated / needs_verification` | | `adminListUsageRecords` | `GET` | `/admin-api/muse/account/usage-records` | `dedicated / needs_verification` | | `adminListAccountUsers` | `GET` | `/admin-api/muse/account/users` | `dedicated / needs_verification` | | `adminGetBalanceSnapshots` | `GET` | `/admin-api/muse/account/users/{userId}/balance-snapshots` | `dedicated / needs_verification` | | `adminGetUserEntitlements` | `GET` | `/admin-api/muse/account/users/{userId}/entitlements` | `dedicated / needs_verification` | | `adminCreateNewApiBinding` | `POST` | `/admin-api/muse/account/users/{userId}/new-api-binding` | `dedicated / needs_verification` | | `adminListQuotaAdjustments` | `GET` | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `dedicated / needs_verification` | | `adminCreateQuotaAdjustment` | `POST` | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `dedicated / needs_verification` | | `adminCreateQuotaRequest` | `POST` | `/admin-api/muse/account/users/{userId}/quota-requests` | `dedicated / needs_verification` | | `getAppBalanceSnapshots` | `GET` | `/app-api/muse/account/balance-snapshots` | `dedicated / needs_verification` | | `appDownloadExport` | `GET` | `/app-api/muse/account/downloads/{credentialId}` | `dedicated / needs_verification` | | `getAppEntitlements` | `GET` | `/app-api/muse/account/entitlements` | `dedicated / needs_verification` | | `appCreateExportTask` | `POST` | `/app-api/muse/account/export-tasks` | `dedicated / needs_verification` | | `appGetExportTask` | `GET` | `/app-api/muse/account/export-tasks/{taskId}` | `dedicated / needs_verification` | | `appGetIntegrationCallByCorrelation` | `GET` | `/app-api/muse/account/integration-calls/by-correlation/{correlationId}` | `dedicated / needs_verification` | | `appListLicenses` | `GET` | `/app-api/muse/account/licenses` | `dedicated / needs_verification` | | `getAppNewApiBinding` | `GET` | `/app-api/muse/account/new-api-binding` | `dedicated / needs_verification` | | `appRecheckNewApiBinding` | `POST` | `/app-api/muse/account/new-api-binding/recheck` | `dedicated / needs_verification` | | `appListPublishRecords` | `GET` | `/app-api/muse/account/publish-records` | `dedicated / needs_verification` | | `appListPurchases` | `GET` | `/app-api/muse/account/purchases` | `dedicated / needs_verification` | | `appCreateQuotaRequest` | `POST` | `/app-api/muse/account/quota-requests` | `dedicated / needs_verification` | | `appGetQuotaRequest` | `GET` | `/app-api/muse/account/quota-requests/{requestId}` | `dedicated / needs_verification` | | `appListSecurityEvents` | `GET` | `/app-api/muse/account/security-events` | `dedicated / needs_verification` | | `appGetSecurityEvent` | `GET` | `/app-api/muse/account/security-events/{eventId}` | `dedicated / needs_verification` | | `appAcknowledgeSecurityEvent` | `POST` | `/app-api/muse/account/security-events/{eventId}/acknowledge` | `dedicated / needs_verification` | | `getAppUsage` | `GET` | `/app-api/muse/account/usage` | `dedicated / needs_verification` | | `getCurrentUser` | `GET` | `/app-api/muse/me` | `dedicated / needs_verification` | | `getProfile` | `GET` | `/app-api/muse/profile` | `dedicated / needs_verification` | | `updateProfile` | `PATCH` | `/app-api/muse/profile` | `dedicated / needs_verification` | ## 已验证实现证据 ### Account owner 与入口 Account owner 当前位于 `muse-module-member` 的 Account 子域,没有独立 `muse-module-account`。 现有 dedicated Controller 覆盖 Account 33 个 operation: - `AdminAccountNewApiController` - `AdminAccountUserController` - `AdminAccountUsageController` - `AdminAccountPurchaseController` - `AppAccountNewApiController` - `AppAccountEntitlementController` - `AppAccountMarketRecordController` - `AppAccountExportController` - `AppAccountSecurityController` - `AppAccountProfileController` 这些 Controller 均通过 `AccountApiVersionGuard.requireVersion(...)` 校验 `X-API-Version`,并调用 Account 子域 Service,不再走旧 `MuseContractPersistenceService` 兜底。 管理端入口使用 `@PreAuthorize` 绑定 `muse:account:*` 权限;App 端入口使用 `getLoginUserId()` 作为当前 owner。 ### Account 本域服务与持久化 Account 已有本域 Service / Guard / DAL: - `AccountProfileServiceImpl` - `AccountEntitlementServiceImpl` - `AccountQuotaServiceImpl` - `AccountUsageServiceImpl` - `AccountNewApiBindingServiceImpl` - `AccountAttributionServiceImpl` - `AccountMarketRecordServiceImpl` - `AccountExportServiceImpl` - `AccountSecurityServiceImpl` - `AccountCommandServiceImpl` - `AccountAuditServiceImpl` - `AccountEventPublishOutboxServiceImpl` - `AccountEventPublishWorker` - `AccountApiVersionGuard` - `AccountOwnerGuard` - `AccountDownloadGuard` - `AccountQuotaGuard` - Account DO / Mapper / Convert 文件 P1R-3 已把 Account 从 `generic_persistence / incomplete` 推进为 `dedicated / needs_verification`,并删除旧 Account 合同兜底 Controller。 ### 数据库与迁移证据 V11 Account Real API schema 已存在: - `muse-cloud/sql/muse/V11__extend_account_real_api_schema.sql` V11 追加 Account owner 自有事实,包括: - `muse_account_command` - `muse_account_audit` - `muse_account_profile` - `muse_account_balance_snapshot` - `muse_account_quota_request` - `muse_account_integration_call` - `muse_account_call_attribution_job` - `muse_account_call_attribution_item` - `muse_account_export_task` - `muse_account_download_credential` - `muse_account_security_event_ack` - `muse_account_record_projection` 历史留痕记录 V11 已在真实 PostgreSQL test 库通过 Flyway: ```text PostgreSQL 17.10 flyway_success=true migrations_executed=11 target_schema_version=11 flyway_latest=11:extend account real api schema v11_tables=12 account_index_count=47 ``` V20 Account Events publish outbox 已存在: - `muse-cloud/sql/muse/V20__extend_account_events_publish_outbox.sql` 历史留痕记录 V20 已在真实 `_test` 库通过 Flyway: ```text flyway_success=true migrations_executed=20 successful_migration_count=20 target_schema_version=20 flyway_latest=20:extend account events publish outbox v20_table=muse_account_event_publish_outbox ``` 这些迁移证据证明 DDL / Flyway 可执行性和 outbox schema 约束,不等同于 Account 33 个 API 全部具备 completed-grade runtime 证据。 ### P1R-7e Account quota alert 证据 P1R-7e 已形成 Account quota adjustment terminal fact 到 Events SSE 的 needs-verification evidence: ```text AccountQuotaServiceImpl.adminCreateQuotaAdjustment -> muse_member_entitlement_audit_log(change_type=quota_adjustment) -> muse_account_event_publish_outbox -> AccountEventPublishWorker -> EventsPublishApi -> muse_unified_event -> /app-api/muse/events 对 accountUserId 可见 ``` 历史验证包括: - Member focused tests 36/36 pass。 - P1R mixed executable gates 73/73 pass。 - Account focused + P1R mixed XML 合计 109 tests,failures/errors/skipped 均为 0。 - `P1rAccountEventsPublishFlywayMigrationIT` 4/4 pass。 - Dependency tree gate 证明 Member server 依赖 `muse-module-events-api`,不依赖 `muse-module-events-server`。 当前 worktree 可见的 Surefire XML 只覆盖部分 Account P1R gate: ```text P1rAccountRealApiGateTest 4/4 P1rAccountRouteOwnershipTest 4/4 P1rAccountEventsPublishMigrationSqlTest 3/3 P1rAccountEventsPublishDependencyTest 2/2 P1rAccountEventsPublishEndToEndTest 4/4 ``` `P1rAccountEventsPublishFlywayMigrationIT` 与 Member focused tests 的 XML 是历史留痕证据,当前 worktree 不能直接引用为 fresh Account completed approval 证据。后续执行版必须重新运行并读取 XML,不能复用历史 XML 口径。 该证据可支持后续把 `adminCreateQuotaAdjustment` 作为 Account operation-level completed approval 的第一候选,但不能自动覆盖全部 Account 33 个 operation。 ## 关键缺口 ### 缺口 1:New-API runtime 未闭合 `NewApiAccountFacade` 定义了绑定和 recheck 的外部边界;默认 `UnavailableNewApiAccountFacade` 抛出 `ACCOUNT_NEW_API_UNAVAILABLE`,注释明确当前 worktree 没有真实 New-API runtime 配置,不能伪造绑定成功或重验任务。 因此以下 operation 不能仅凭当前 dedicated 实现直接 completed: - `adminListNewApiBindings` - `adminCreateNewApiBinding` - `getAppNewApiBinding` - `appRecheckNewApiBinding` - `adminCreateQuotaRequest` - `appCreateQuotaRequest` - `appGetQuotaRequest` - `adminGetIntegrationCallByCorrelation` - `appGetIntegrationCallByCorrelation` 其中读侧 operation 可能有本地投影读取证据,但 create/recheck/request/correlation 相关 completed approval 必须说明真实 New-API runtime、失败关闭、超时、重试、correlation 与 attribution 口径。 ### 缺口 2:FileService / 导出下载真实交付未闭合 `AccountFileServiceFacade` 默认返回 unavailable;注释明确 Account 只定义任务、凭证和下载校验,不接管真实文件生成或存储。 `AccountExportServiceImpl` 已有 fail-closed 行为: - 高敏导出缺少可信 step-up proof 时拒绝。 - FileService 异常收敛为 unavailable。 - completed 必须有 fileRef、downloadExpiresAt 和 Account HMAC secret。 - 下载凭证消费具备 owner、过期、撤销、consumed、sourceBlocked 原子门禁。 但这仍不能证明真实文件或对象存储交付。因此以下 operation 暂不应 completed: - `appCreateExportTask` - `appGetExportTask` - `appDownloadExport` 除非执行版补齐真实 FileService / 对象存储成功路径、失败路径、下载字节、凭证一次性消费和审计证据。 ### 缺口 3:Call attribution 外部来源未闭合 `AccountAttributionServiceImpl` 的 create 路径只建立 job 队列事实,并明确真实归因执行由后续 job/transition 路径接管。外部归因来源不可用时会形成失败或补偿建议,而不是 completed-grade 归因成功。 因此以下 operation 不能整批 completed: - `adminCreateCallAttributionJob` - `adminGetCallAttributionJob` 执行版必须证明真实 attribution source 或明确 operation completed 口径只覆盖“创建 queued job + 可查询失败关闭状态”,否则应保持 `needs_verification`。 ### 缺口 4:Market purchase/license/publish projection 依赖跨 owner 一致性 P1R-3 已固定 Account 视角使用 `muse_account_record_projection(record_type=purchase/license/publish)` 作为查询读模型;`muse_market_account_projection` 只是 Market 侧 sync/outbox 状态,不是 Account 查询读模型。 以下 operation 需要 Market 主流程和 Account projection 一致性证据: - `adminListPurchaseRecords` - `appListPurchases` - `appListLicenses` - `appListPublishRecords` 它们不能用 Market 事件传播或 Account projection 表存在来直接 completed。执行版必须证明 purchase/license/publish 上游 owner 写入、projection 同步、tenant/owner 隔离和 stale projection 风险。 ### 缺口 5:安全事件与高敏导出源事实不足 `MemberSecurityEventDO` 有读侧、详情、ack 和脱敏转换;但 P1R-7e 审阅已验证,高敏导出生产安全事件路径当前被 `normalizeRequest` fail-closed 阻断,不能作为第一切片 source fact。 以下 operation 若要 completed,必须证明安全事件真实生产路径,而不是只证明读侧和 ack: - `appListSecurityEvents` - `appGetSecurityEvent` - `appAcknowledgeSecurityEvent` ### 缺口 6:缺少本轮 fresh Account completed approval gate 当前 `P1rAccountRealApiGateTest` 仍明确禁止 Account operation 标记为 `completed`,并要求 33 个 operation 保持 `dedicated / needs_verification`。 当前 scanner 的 completed 白名单没有包含 Account domain 或 Account operation;已批准范围仍限于 AI / Knowledge domain,以及 Events / Meta 的 operation-level allowlist。未获批准的 Account completed 会被 scanner 拒绝。 后续执行版必须先明确用户批准范围,再把 gate 改成审批后口径: - 仅允许 approved operation 从 `needs_verification` 变为 `completed`。 - 未批准 operation 必须继续 `dedicated / needs_verification`。 - Account 不能自动加入 domain-level completed allowlist。 - Market / Content 仍不能被连带推进。 ## 推荐审批粒度 ### 推荐:Account operation-level approval 第一批候选不应超过以下本域闭合较强的 operation: ```text getCurrentUser getProfile updateProfile adminListAccountUsers adminGetUserEntitlements getAppEntitlements adminGetBalanceSnapshots getAppBalanceSnapshots getAppUsage adminListUsageRecords adminCreateQuotaAdjustment adminListQuotaAdjustments ``` 其中 `adminCreateQuotaAdjustment` 证据最强,因为 P1R-7e 已额外证明 quota adjustment terminal fact 可以进入 Account outbox 并发布到 Events。 但上述候选仍必须由执行版逐项验证 Controller、Service、DAL、权限、owner/tenant 隔离、幂等、审计、错误路径、XML 防空跑和真实 `_test` 证据。审阅版不直接批准这些 operation completed。 ### 不推荐:Account domain-level approval 除非执行版能一次性补齐: - 真实 New-API binding / recheck / quota request runtime。 - 真实 FileService / 对象存储导出下载。 - 真实 call attribution source 或明确可验收替代口径。 - Market purchase/license/publish 到 Account projection 的端到端一致性。 - security event 生产路径和 ack 的 owner/tenant 证据。 否则 Account 33/33 domain-level completed 会把外部闭环缺口包装成已完成。 ## 非目标 - 不修改 7 个 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` - 不修改 `muse-cloud/scripts/p1r-audit-api-coverage.py`。 - 不修改 `docs/superpowers/reports/p1r-api-coverage.json`。 - 不修改 `docs/superpowers/reports/p1r-api-coverage.md`。 - 不修改 Account 业务实现。 - 不把 Account 33 个 operation 推进 `completed`。 - 不把 Account 加入 domain-level completed allowlist。 - 不推进 Market / Content / 总 P1R completed。 - 不把 P1R-7e quota alert source owner evidence 当作 Account 整域 completed 证据。 ## 后续执行版必须包含 1. Account 33 operation 的完整清单、当前状态和目标审批状态。 2. 第一批候选 operation 的逐项 evidence map:Controller、Service、DAL、权限、版本头、owner/tenant 隔离、审计、幂等、失败路径。 3. 明确哪些 operation 继续 `needs_verification`,以及原因。 4. scanner approval 模型:只允许 operation-level allowlist,不允许 Account domain-level allowlist,除非执行版证明 33/33 全闭环。 5. `P1rAccountRealApiGateTest` 从禁止 completed 到审批后 partial completed gate 的修改策略。 6. `P1rApiCoverageReportTest` summary 期望变更策略,必须只提升用户批准的 Account operation 数。 7. Account focused tests 的 required class 清单与最低 XML tests 数;执行版必须 fresh rerun `P1rAccountEventsPublishFlywayMigrationIT` 与 Member focused tests,不能只引用历史留痕。 8. P1R mixed gates:包含 Account gate、coverage report gate,以及用于证明非目标 Market / Content 不被推进的 gate。 9. 真实 PostgreSQL `_test`:至少覆盖 V1-V20 clean migrate;如新增 Account completed approval Flyway IT,应验证 V11/V20 表、索引、约束、trigger、非法 insert 拒绝。 10. 外部 runtime 验收:New-API / FileService / Market projection / attribution source 对应 operation 若不具备真实验收,必须保持 `needs_verification`。 11. protected diff gate:7 个 OpenAPI 在批准前后都必须保持空 diff。 12. allowed-diff gate:覆盖 unstaged、staged、untracked,并使用 `git -c core.quotePath=false`。 13. rollback 策略:撤回 scanner allowlist、coverage report、gate test 和新增 memory,恢复目标 operation 为 `dedicated / needs_verification`。 ## 验收标准 本审阅版可以视为完成的条件: 1. 文件写入 `docs/agent-specs/2026-06-11-P1RAccountCompletedApproval审阅版.md`。 2. `.agent` 记录 Account completed approval 审阅版状态。 3. `git diff --check` 通过。 4. OpenAPI、scanner、coverage report 无 diff。 5. 文档只定义审阅路线,不进入执行版或实现。 6. fresh spec/scope review PASS。 7. fresh quality/feasibility review PASS。 ## 待确认项 1. 是否确认 Account 第一轮不做 domain-level 33/33 completed approval。 2. 是否确认优先走 operation-level approval,并从本域闭合较强的 profile / entitlement / usage / quota adjustment 切片开始。 3. 是否确认 New-API、FileService/download、call attribution external source、Market projection、安全事件生产路径在没有真实 runtime 证据前继续保持 `needs_verification`。 4. 是否确认审阅版 fresh 双 review PASS 后,再写 Account completed approval 执行版。