9 篇工作已完成的过程文档(P1R解锁3篇+agent基建交付+superpowers报告2篇+P1R任务memory+已合并object-storage计划+已折入总览的completion brainstorm)移至 docs/archive/。保留:design-docs(SSOT)、主台账、现状基线、对抗复盘/P0冻结令(知识网根基,被AGENTS/.agents/台账引用)、meta-schema当前2篇、p1r-api-coverage.json(被引数据)、memorys/README。归档非删除,git 可恢复。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
28 KiB
P1R Account Stage A New-API / Quota / Integration 解锁执行版
日期:2026-06-14
结论
本执行版只用于 Stage A 的 implementation plan 审阅,不是 implementation 授权,也不是 completed approval 授权。
Stage A 覆盖 Account 剩余 21 个 operation 中的 9 个 New-API / quota / integration operation。当前仓库已经具备 dedicated Controller、Service、Mapper 和部分单元测试,但仍缺两类关键闭环:
NewApiAccountFacade的默认 fail-closed Bean 仍以@Component注册,真实 facade 与 unavailable facade 并存时存在静默选错或启动歧义风险。- 已验证的 New-API 外部证据只覆盖 OpenAI-compatible chat runtime,不覆盖 Account 绑定、重验、额度请求管理端点;不能凭空写 HTTP adapter 并把它当 completed 证据。
推荐路线:
A0 先做 facade 装配硬化和本地 HTTP+DB 闭环准备
A1 查证 New-API Account 管理端点合同
A2/A3 在合同查证后实现 binding runtime 与 quota submit worker
A4 用 Stage A HTTP+DB + opt-in live acceptance 形成 unlock evidence
之后另起 operation-level completed approval
当前事实基线
工作区:
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
本轮 final review 起点基线:
main...origin/main
HEAD=862fe9e docs(p1r): 收敛 Account Stage A 解锁计划
origin/main=862fe9e
origin/dev/1.0.0=862fe9e
当前 coverage summary:
total=233
completed=147
needsVerification=86
incomplete=0
genericPersistence=0
ssePlaceholder=0
当前 Account 状态:
total=33
completed=12
needsVerification=21
Stage A 范围
Stage A 只覆盖以下 9 个 operation:
| operation | method | path | commandId |
|---|---|---|---|
account:adminListNewApiBindings |
GET | /admin-api/muse/account/new-api-bindings |
no |
account:adminCreateNewApiBinding |
POST | /admin-api/muse/account/users/{userId}/new-api-binding |
yes |
account:getAppNewApiBinding |
GET | /app-api/muse/account/new-api-binding |
no |
account:appRecheckNewApiBinding |
POST | /app-api/muse/account/new-api-binding/recheck |
yes |
account:adminCreateQuotaRequest |
POST | /admin-api/muse/account/users/{userId}/quota-requests |
yes |
account:appCreateQuotaRequest |
POST | /app-api/muse/account/quota-requests |
yes |
account:appGetQuotaRequest |
GET | /app-api/muse/account/quota-requests/{requestId} |
no |
account:adminGetIntegrationCallByCorrelation |
GET | /admin-api/muse/account/integration-calls/by-correlation/{correlationId} |
no |
account:appGetIntegrationCallByCorrelation |
GET | /app-api/muse/account/integration-calls/by-correlation/{correlationId} |
no |
本执行版不覆盖:
- Account FileService / export / download 3 个 operation。
- Account usage / attribution 4 个 operation。
- Market projection 4 个 operation。
- security ack / session revoke 1 个 operation。
- Account domain-level completed。
- scanner、coverage report、OpenAPI 合同变更。
已验证代码事实
当前 Stage A 相关主文件:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountNewApiBindingServiceImpl.javamuse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountQuotaServiceImpl.javamuse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountUsageServiceImpl.javamuse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/NewApiAccountFacade.javamuse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/UnavailableNewApiAccountFacade.java
当前行为事实:
AccountNewApiBindingServiceImpl.adminCreateNewApiBinding已通过NewApiAccountFacade.createOrRefreshBinding写入MemberNewApiBindingDO和AccountIntegrationCallDO;外部不可用时通过REQUIRES_NEW写入 failed/unavailable integration call 后抛错。AccountNewApiBindingServiceImpl.appRecheckNewApiBinding已通过NewApiAccountFacade.createRecheckJob创建 recheck job,并要求 job status 只能是queued或processing。UnavailableNewApiAccountFacade当前有@Component,会作为默认 Bean 进入容器;这与已有AccountFileServiceFacadeAutoConfiguration、MarketAccountProjectionFacadeAutoConfiguration的@ConditionalOnMissingBean模式不一致。NewApiAccountFacade当前只有 binding sync 与 recheck job 两组方法,没有 quota submit 方法。AccountQuotaServiceImpl.adminCreateQuotaRequest与appCreateQuotaRequest当前只创建本地AccountIntegrationCallDO(status=pending_attribution)和AccountQuotaRequestDO(status=queued),没有提交真实 New-API runtime。AccountUsageServiceImpl当前直接读取AccountIntegrationCallDO,admin/detail 不做 owner guard,app/detail 做 owner guard;状态映射包含pending -> pending_attribution、unavailable -> failed、未知状态归一为failed。- OpenAPI 中
QuotaRequestResult.status只允许queued、processing、idempotent_hit;QuotaRequestStatus.status允许queued、processing、completed、failed、idempotent_hit。 - 现有外部验收留痕只证明 New-API
/v1/chat/completionslive acceptance,不证明 Account binding / quota management endpoint 可用。
架构边界
Stage A 必须保持以下边界:
flowchart LR
Admin["Admin/App Account API"] --> Account["Account Service<br/>command / audit / local facts"]
Account --> Binding["muse_member_new_api_binding"]
Account --> Quota["muse_account_quota_request"]
Account --> Call["muse_account_integration_call"]
Account --> Facade["NewApiAccountFacade"]
Facade --> Runtime["Verified New-API Account Runtime"]
Runtime -. "callback or worker result" .-> Account
规则:
- Account 子域持有 Account API、本地 command、audit、binding、quota request、integration call 事实。
- New-API 只能通过
NewApiAccountFacade或其明确拆分后的同 owner facade 接入,不能由 Account service 直接散落 HTTP 调用。 - 没有查证的 New-API Account 管理端点不得被写进真实 adapter。
- unavailable facade 必须 fail closed,不能返回伪造成功。
- quota request 推荐采用 Account 接收、审计、入队,再由 worker/submitter 提交 New-API;不要在 HTTP 请求事务中直接等待外部调用完成。
- Stage A 默认不新增 Events outbox;command、audit、quota request、integration call 是本阶段审计边界。
执行切片
A0:facade 装配硬化
目标:先消除 UnavailableNewApiAccountFacade @Component 带来的真实 facade 装配风险。
允许在用户批准 implementation 后修改:
- Modify:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/UnavailableNewApiAccountFacade.java - Create:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/autoconfigure/member/account/NewApiAccountFacadeAutoConfiguration.java - Modify:
muse-cloud/muse-module-member/muse-module-member-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - Create:
muse-cloud/muse-module-member/muse-module-member-server/src/test/java/cn/iocoder/muse/module/member/application/account/facade/NewApiAccountFacadeConfigurationTest.java
必须实现的测试事实:
- 无真实
NewApiAccountFacadeBean 时,容器只有 1 个 facade,类型为UnavailableNewApiAccountFacade。 - 有真实
NewApiAccountFacadeBean 时,unavailable fallback 不注册,context.getBean(NewApiAccountFacade.class)返回真实 Bean。 AutoConfiguration.imports包含NewApiAccountFacadeAutoConfiguration。- fallback 调用
createOrRefreshBinding、createRecheckJob时均 fail closed;若 A3 扩展 quota 方法,quota fallback 也必须 fail closed。
A1:New-API Account 管理端点合同查证
目标:在实现真实 HTTP adapter 前,查证 Account 绑定、重验、额度请求的真实 New-API 管理端点。
查证来源优先级:
- 本机或远端
new-api代码、OpenAPI、README、路由表。 - 当前部署
http://100.64.0.8:3000的只读管理接口或健康接口。 - 用户提供的系统管理令牌与端点说明。
必须形成的证据:
- binding create/refresh 端点:method、path、auth、request、response、错误码。
- binding recheck 端点:method、path、auth、request、response、job status 枚举、错误码。
- quota submit 端点:method、path、auth、request、response、request/job id、状态枚举、错误码。
- timeout、5xx、401/403、409、业务错误的失败分类。
- 哪些字段允许写入
requestSummary/responseSummary,哪些必须脱敏。
如果 A1 无法查证上述端点,Stage A implementation 只能完成 A0 和本地闭环测试准备,不能实现 HttpNewApiAccountFacade,不能把 9 个 operation 推进 completed。
A2:binding runtime adapter
只有 A1 查证通过后,才允许实现真实 binding adapter。
候选文件:
- Create:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/framework/config/MuseAccountNewApiProperties.java - Create:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/framework/config/MuseAccountNewApiConfiguration.java - Create:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/HttpNewApiAccountFacade.java - Modify:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/NewApiAccountFacade.java
属性命名建议:
muse.account.new-api.enabled
muse.account.new-api.base-url
muse.account.new-api.token
muse.account.new-api.connect-timeout-seconds
muse.account.new-api.read-timeout-seconds
muse.account.new-api.max-attempts
muse.account.new-api.retry-backoff-seconds
合同要求:
- 关闭
enabled时不注册真实 facade,回落 A0 fallback。 - token 不写日志、不写测试报告、不进入
requestSummary/responseSummary。 - adapter 必须带 correlationId、commandId、accountUserId、bindingId。
createOrRefreshBinding只有在 New-API 返回非空newApiUserId后才能写本地bound。createRecheckJob只有在 New-API 返回非空jobId且 status 属于queued/processing后才能成功。- timeout、认证失败、不可用、未知 response 均映射为 fail closed,不伪造 job 或 binding。
A3:quota submit worker
目标:补齐 adminCreateQuotaRequest、appCreateQuotaRequest、appGetQuotaRequest 和 integration detail 的 runtime 闭环。
推荐设计:
AccountQuotaServiceImpl继续负责 HTTP create:校验 user、requestType、command 幂等,创建AccountQuotaRequestDO(status=queued)和AccountIntegrationCallDO(status=pending_attribution)。- 新增
AccountQuotaRequestWorker或AccountQuotaRequestSubmitter负责把 queued request 提交给NewApiAccountFacade。 NewApiAccountFacade增加 quota submit 合同,而不是在AccountQuotaServiceImpl内直接写 HTTP。
候选接口扩展:
NewApiAccountFacade.submitQuotaRequest(QuotaSubmitCommand)
NewApiAccountFacade.QuotaSubmitResult
QuotaSubmitCommand 必须包含:
accountUserIdrequestIdcommandIdcorrelationIdrequestTyperequestedAmountside
QuotaSubmitResult 必须包含:
externalCallIdstatusresponseSummaryfailureCodefailureMessage
状态规则:
- create API 初始只返回 OpenAPI 允许的
queued或processing,不能返回completed。 - worker claim 后可把 quota request 更新为
processing。 - New-API 接受成功但异步执行时,
appGetQuotaRequest返回processing。 - New-API 明确终态成功时,
appGetQuotaRequest返回completed。 - New-API 明确失败或不可恢复错误时,
appGetQuotaRequest返回failed,并写failureReason。 - integration call 对应更新
status、externalCallId、responseSummary、errorCode、errorMessage、finishedAt。
并发与幂等要求:
- 不新增 SQL migration 时,worker 必须复用现有字段承载重试:
muse_account_integration_call.retry_count、next_retry_at、status、errorCode、errorMessage。 - worker claim 必须使用 tenant 范围内的条件更新,并冻结为单一路径:初次 claim 只允许
quota_request.status=queued;retry / lease 恢复 claim 只允许quota_request.status=processing且对应integration_call.next_retry_at <= now且 integration call 未 terminal。claim 成功后 quota request 统一保持或进入processing,并同步把 integration call 改为retrying或等价运行态。 - lease 超时恢复必须由
integration_call.next_retry_at表达;crash 后只扫描next_retry_at <= now且未 terminal 的记录。 - retry budget 必须由 stage implementation 固定,默认
maxAttempts=3;达到上限后 quota request 必须进入failed,integration call 必须进入failed并写失败原因。 - tenant context 必须在 claim、submit、terminal update 前显式设置,推荐使用
TenantContextHolder.setTenantId(...)并在 finally 中 clear。 - terminal update 必须带状态条件,只允许
queued/processing进入completed/failed,不得覆盖已 terminal 的 request。 - command replay 不能重复创建 quota request 或 integration call。
- 同 commandId 不同 request hash 必须冲突并 no-write。
- worker 重试不得覆盖已 terminal 的 request。
- 如果上述状态机需要新增字段或索引,必须先退出当前 Stage A unlock,另起 SQL migration 审批并把 V22 schema、mapper、rollback 写入新的 allowed diff。
worker 事务边界必须冻结为短事务模型:
claimNext独立事务:用 tenant + request/call status +next_retry_at条件原子 claim 一条 quota request;初次 claim 匹配queued,重试和 crash 恢复只匹配processing + next_retry_at <= now,并同步把 quota request 置为processing、integration call 置为运行态,同时递增或记录本轮 attempt。该事务提交后才能调用外部 New-API。- 外部 New-API submit 不得包在数据库事务内;调用前后必须保留可审计日志,日志只能包含 requestId/correlationId/tenantId/attempt/status/errorCode,不得写 token、secret 或完整外部响应。
finalizeSuccess独立事务:仅在 quota request 仍为processing且 integration call 仍为本轮运行态时写completed、externalCallId、responseSummary、finishedAt,并清空next_retry_at;若条件更新为 0,必须记录 conflict 日志并停止覆盖。finalizeFailure独立事务:不可恢复失败或 maxAttempts 用状态条件写 quota requestfailed、integration callfailed、errorCode、errorMessage、finishedAt,并清空next_retry_at。finalizeRetryable独立事务:runtime unavailable、timeout 或外部 5xx 等可重试错误只更新 integration callerrorCode/errorMessage/retry_count/next_retry_at,quota request 必须保持processing,不得回写queued;下一轮 claim 必须由processing + next_retry_at <= now驱动;达到maxAttempts=3后必须走finalizeFailure。- 外部 submit 成功但 finalize 失败时,不得二次提交同一外部请求;后续恢复只能先查 integration call / externalCallId / correlationId 的已有结果,再决定 finalize 或 fail closed。
- Stage A HTTP+DB / focused tests 必须按
queued -> processing -> completed/failed唯一路径覆盖:double-claim 只有一个 worker 成功、runtime unavailable 只产生 allowed-delta 且 request 保持processing、finalize conflict 不覆盖 terminal fact、processing + next_retry_at <= now可恢复、maxAttempts 后 terminal failed。
A4:HTTP+DB unlock gate
Stage A implementation 必须新增 HTTP+DB _test 主证据,但该证据只证明 Muse Account 侧真实 HTTP 入口、真实服务、真实 mapper、真实 PostgreSQL 和 facade 合同可闭合;如果使用 test-local facade,不得把它写成外部 New-API completed 证据。
推荐新增:
- Create:
muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountStageANewApiQuotaIntegrationUnlockIT.java
必须覆盖:
- V1-V21 clean migrate,数据库名包含
_test。 adminCreateNewApiBindingsuccess、replay、command conflict、New-API unavailable failed integration call。adminListNewApiBindings能读取真实member_user+muse_member_new_api_binding。getAppNewApiBindingowner summary,不暴露 token、provider authority 或 supplier route。appRecheckNewApiBindingsuccess、invalid job status fail closed、missing binding、replay、command conflict。adminCreateQuotaRequest和appCreateQuotaRequestsuccess、replay、command conflict、invalid requestType、missing user。- quota worker success / failure / unavailable,验证 quota request 与 integration call 状态转移。
appGetQuotaRequestowner guard、missing、terminal completed/failed、createdAt/completedAt。adminGetIntegrationCallByCorrelation和appGetIntegrationCallByCorrelationno-write、owner guard、敏感字段 allowlist、status/requestType/retryGroup 映射。- 参数校验、幂等冲突、越权、cross tenant、missing resource 必须使用全表 no-write snapshot,至少覆盖
muse_member_new_api_binding、muse_account_quota_request、muse_account_integration_call、muse_account_command、muse_account_audit、muse_account_event_publish_outbox。 - runtime unavailable 不属于全表 no-write:只允许新增或更新一条
failed/unavailableintegration call;必须用 allowed-delta snapshot 证明 binding/quota request、command succeeded fact、audit succeeded fact 和 outbox 均未产生成功事实。
可选 live acceptance:
- Create:
muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountStageANewApiLiveAcceptanceIT.java - 默认跳过,仅在显式环境变量开启并提供真实 New-API Account 管理端点配置时运行。
- 只有该类使用已查证的外部 New-API Account runtime;它不能依赖 test-local facade。
验证命令
Maven root:
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0/muse-cloud
A0 facade wiring:
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -pl muse-module-member/muse-module-member-server -am -Dtest=NewApiAccountFacadeConfigurationTest \
-Dsurefire.failIfNoSpecifiedTests=false test
Stage A focused member tests:
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -pl muse-module-member/muse-module-member-server -am \
-Dtest=AccountNewApiBindingServiceTest,AccountQuotaServiceTest,AccountUsageServiceTest \
-Dsurefire.failIfNoSpecifiedTests=false test
Stage A HTTP+DB _test:
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0/muse-cloud
export P1R_ACCOUNT_STAGE_A_DB_NAME="muse_p1r_account_stage_a_test"
export P1R_ACCOUNT_STAGE_A_JDBC_URL="jdbc:postgresql://127.0.0.1:5432/${P1R_ACCOUNT_STAGE_A_DB_NAME}"
export P1R_ACCOUNT_STAGE_A_DB_USER="${P1R_ACCOUNT_STAGE_A_DB_USER:?set test db user}"
export P1R_ACCOUNT_STAGE_A_DB_PASSWORD="${P1R_ACCOUNT_STAGE_A_DB_PASSWORD:?set test db password}"
export P1R_FLYWAY_PASSWORD="${P1R_FLYWAY_PASSWORD:-${P1R_ACCOUNT_STAGE_A_DB_PASSWORD}}"
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -pl muse-server -am -Dtest=P1rAccountStageANewApiQuotaIntegrationUnlockIT \
-Dsurefire.failIfNoSpecifiedTests=false test \
-Dp1r.flyway.locations=filesystem:sql/muse \
-Dp1r.flyway.url="${P1R_ACCOUNT_STAGE_A_JDBC_URL}" \
-Dp1r.flyway.user="${P1R_ACCOUNT_STAGE_A_DB_USER}" \
-Dp1r.account.stage-a.jdbc-url="${P1R_ACCOUNT_STAGE_A_JDBC_URL}" \
-Dp1r.account.stage-a.jdbc-user="${P1R_ACCOUNT_STAGE_A_DB_USER}"
Stage A HTTP+DB IT 必须只从环境变量读取密码,禁止读取或传递 p1r.*password JVM system property。IT 内必须包含:
assertNoPasswordSystemProperties():拒绝p1r.flyway.password、p1r.account.stage-a.jdbc-password等 password system property。assertNoCredentialQuery():拒绝 JDBC URL query、日志或 evidence summary 中出现 password。_testURL 断言:数据库名必须包含_test。
P1R mixed gates 仍不得推进 completed:
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0/muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -pl muse-server -am \
-Dtest=P1rApiCoverageReportTest,P1rAccountRealApiGateTest,P1rEventsRealApiGateTest,P1rAiRealApiGateTest,P1rKnowledgeRealApiGateTest,P1rMarketRealApiGateTest,P1rContentRealApiGateTest,P1rMetaRealApiGateTest \
-Dsurefire.failIfNoSpecifiedTests=false test
coverage check 仍应保持当前值,并且必须在 repo root 运行:
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
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
期望仍为:
233 147 86 0 0 0
XML 防空跑
Stage A implementation 后必须检查这些 XML,具体文件名以实际类名为准:
muse-cloud/muse-module-member/muse-module-member-server/target/surefire-reports/TEST-cn.iocoder.muse.module.member.application.account.facade.NewApiAccountFacadeConfigurationTest.xml
muse-cloud/muse-module-member/muse-module-member-server/target/surefire-reports/TEST-cn.iocoder.muse.module.member.application.account.AccountNewApiBindingServiceTest.xml
muse-cloud/muse-module-member/muse-module-member-server/target/surefire-reports/TEST-cn.iocoder.muse.module.member.application.account.AccountQuotaServiceTest.xml
muse-cloud/muse-module-member/muse-module-member-server/target/surefire-reports/TEST-cn.iocoder.muse.module.member.application.account.AccountUsageServiceTest.xml
muse-cloud/muse-server/target/surefire-reports/TEST-cn.iocoder.muse.server.framework.api.P1rAccountStageANewApiQuotaIntegrationUnlockIT.xml
muse-cloud/muse-server/target/surefire-reports/TEST-cn.iocoder.muse.server.framework.api.P1rAccountRealApiGateTest.xml
muse-cloud/muse-server/target/surefire-reports/TEST-cn.iocoder.muse.server.framework.api.P1rApiCoverageReportTest.xml
所有目标 XML 必须满足:
tests > 0
failures = 0
errors = 0
skipped = 0
allowed diff
当前文档阶段只允许 Account Remaining21 与 Stage A 文档变更:
docs/agent-specs/.agent
docs/agent-specs/2026-06-14-P1RAccountRemaining21解锁审阅版.md
docs/agent-specs/2026-06-14-P1RAccountRemaining21解锁执行版.md
docs/agent-specs/2026-06-14-P1RAccountStageA-NewAPIQuotaIntegration解锁执行版.md
后续用户明确批准 Stage A implementation 后,默认只允许以下类别:
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/autoconfigure/member/account/NewApiAccountFacadeAutoConfiguration.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/facade/**
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/framework/config/MuseAccountNewApi*.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountQuotaServiceImpl.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountQuotaRequestWorker.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/AccountQuotaRequestSubmitter.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/dal/mysql/account/AccountQuotaRequestMapper.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/dal/mysql/account/AccountIntegrationCallMapper.java
muse-cloud/muse-module-member/muse-module-member-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
muse-cloud/muse-module-member/muse-module-member-server/src/test/java/cn/iocoder/muse/module/member/application/account/**
muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountStageANewApiQuotaIntegrationUnlockIT.java
docs/agent-specs/.agent
docs/memorys/**
始终禁止:
docs/api-contracts/**
muse-cloud/scripts/p1r-audit-api-coverage.py
docs/superpowers/reports/**
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
如 implementation 必须修改禁止路径,必须停止 Stage A unlock,另起 OpenAPI 合同变更审批或 completed approval 审批。
Stage A diff gate 必须覆盖 tracked、cached 和 untracked 文件,不能只用 git diff --name-only:
cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
{
git -c core.quotePath=false diff --name-only
git -c core.quotePath=false diff --cached --name-only
git -c core.quotePath=false ls-files --others --exclude-standard
} | sort -u > /tmp/p1r-account-stage-a.diff-files
python3 - <<'PY'
from pathlib import Path
allowed = (
"docs/agent-specs/",
"docs/memorys/",
"muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/autoconfigure/member/account/NewApiAccountFacadeAutoConfiguration.java",
"muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/application/account/",
"muse-cloud/muse-module-member/muse-module-member-server/src/main/java/cn/iocoder/muse/module/member/framework/config/MuseAccountNewApi",
"muse-cloud/muse-module-member/muse-module-member-server/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
"muse-cloud/muse-module-member/muse-module-member-server/src/test/java/cn/iocoder/muse/module/member/application/account/",
"muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountStageANewApiQuotaIntegrationUnlockIT.java",
)
protected = (
"docs/api-contracts/",
"muse-cloud/scripts/p1r-audit-api-coverage.py",
"docs/superpowers/reports/",
"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",
)
files = [line.strip() for line in Path("/tmp/p1r-account-stage-a.diff-files").read_text().splitlines() if line.strip()]
violations = [path for path in files if path.startswith(protected) or not path.startswith(allowed)]
if violations:
raise SystemExit("diff gate violation:\n" + "\n".join(violations))
print("diff_gate=pass")
PY
回滚策略
- A0 可通过恢复
NewApiAccountFacadeAutoConfiguration/AutoConfiguration.imports/UnavailableNewApiAccountFacade的最小 diff 回滚。 - A2/A3 必须保留
muse.account.new-api.enabled=falseruntime switch;关闭后回到 fail-closed 或 queued-only。 - 已写入的 command、quota request、integration call 不做物理删除;通过状态和失败原因表达补偿。
- scanner/report 回滚只属于后续 completed approval,不属于 Stage A unlock。
当前完成条件
本 Stage A 执行版自身完成条件:
- 文档写入本文件。
.agent记录 Stage A 计划状态。- 不修改 OpenAPI、scanner、coverage report、Account 业务实现、SQL migration 或测试代码。
git diff --check通过。- protected diff 为空。
- fresh spec/scope review PASS。
- fresh quality/feasibility/testing review PASS。
通过后的下一步:
- 用户明确批准 Stage A implementation。
- implementation 先做 A0 RED/GREEN,再进入 A1 合同查证。
- A1 查证失败则停止在 A0,不实现伪造 HTTP adapter。
- A1 查证成功后继续 A2/A3/A4。
- Stage A implementation fresh 双 review PASS 后,再决定是否另起 9 个 operation 的 completed approval。