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

20 KiB
Raw Blame History

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

flowchart TB
    Start["当前 coverage<br/>Account 33 dedicated / needs_verification"] --> Review["Account completed approval 审阅版<br/>冻结证据标准"]
    Review --> Split{"是否整域 33/33 completed?"}
    Split -->|否,推荐| OpLevel["按证据切片 operation-level approval"]
    Split -->|是,不推荐| DomainLevel["domain-level approval<br/>需 New-API/FileService/Market/Attribution 全闭环"]
    OpLevel --> Exec["执行版<br/>列出可审批 operation 与保留 needs_verification operation"]
    Exec --> FreshReview["fresh spec/scope review<br/>fresh quality/feasibility review"]
    FreshReview --> UserApproval{"用户明确批准<br/>Account 状态推进?"}
    UserApproval -->|否| Stay["保持 Account 33 needs_verification"]
    UserApproval -->|是| Change["最小修改 scanner/report/gates<br/>运行 focused + P1R + _test + XML 防空跑"]

当前事实状态

工作区:

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

当前分支与远端同步HEAD 为:

df26bd9 test(p1r): 收口 Meta remaining 5 completed approval 门禁

当前 coverage summary

total=233
completed=117
needsVerification=116
incomplete=0
genericPersistence=0
ssePlaceholder=0

当前按 domain 聚合:

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

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

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

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 testsfailures/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

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。

关键缺口

缺口 1New-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 口径。

缺口 2FileService / 导出下载真实交付未闭合

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 / 对象存储成功路径、失败路径、下载字节、凭证一次性消费和审计证据。

缺口 3Call attribution 外部来源未闭合

AccountAttributionServiceImpl 的 create 路径只建立 job 队列事实,并明确真实归因执行由后续 job/transition 路径接管。外部归因来源不可用时会形成失败或补偿建议,而不是 completed-grade 归因成功。

因此以下 operation 不能整批 completed

  • adminCreateCallAttributionJob
  • adminGetCallAttributionJob

执行版必须证明真实 attribution source 或明确 operation completed 口径只覆盖“创建 queued job + 可查询失败关闭状态”,否则应保持 needs_verification

缺口 4Market 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

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 mapController、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 gate7 个 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 执行版。