# P1R 外部验收依赖留痕 ## 结论 本次留痕的优先目标是保存 P1R-4 / P1R-5 外部验收过程依赖,避免后续会话只看到 `needs_verification` 状态,却丢失服务地址、凭据来源、模型选择、已跑通过的 smoke 和剩余缺口。 当前结论: - P1R-4 New-API:`MiniMax-M2.5` 已有真实 New-API `/v1/chat/completions` 成功证据,并且新增的 Muse AI runtime client live acceptance 已通过,可以作为申请 AI operations 进入 `completed` 的关键外部依赖证据之一。 - P1R-4 仍未直接修改 coverage;是否推进 `completed` 还需要补齐 Muse API 层真实触发、Muse DB task/job/runtime_call/audit 落库和失败路径证据,并经用户批准。 - P1R-5 RAGFlow:新增的 Muse Knowledge runtime client live acceptance 已通过,覆盖 health、create dataset、upload document、parse polling、list chunks、retrieval;可以作为申请 Knowledge operations 进入 `completed` 的关键外部依赖证据之一。 - P1R-5 仍未直接修改 coverage;是否推进 `completed` 还需要补齐 Muse API 层真实触发、Muse DB dataset/document/task/runtime_call/audit 落库和失败路径证据,并经用户批准。 - P1R-5 新增事实:用户后续提供的 `ragflow-*` API key 已通过 RAGFlow `/api/v1/datasets` 鉴权;早先复用的 New-API 系统管理令牌对 RAGFlow API 返回 `code=109 Authentication error`,不能作为 RAGFlow 验收凭据。 ## 可执行依赖 P1R 外部验收 env 已记录在: ```bash muse-cloud/scripts/dev/p1r-external-acceptance.env ``` 加载方式: ```bash set -a . muse-cloud/scripts/dev/p1r-external-acceptance.env set +a ``` 该 env 文件包含: - `NEW_API_SYSTEM_MANAGEMENT_TOKEN`:New-API 系统管理令牌,用于管理接口或渠道配置核查。 - `MUSE_AI_NEW_API_BASE_URL=http://100.64.0.8:3000`:New-API OpenAI-compatible 调用地址。 - `MUSE_AI_NEW_API_TOKEN`:大模型调用令牌。 - `MUSE_AI_NEW_API_DEFAULT_MODEL_KEY=MiniMax-M2.5`:本次已验收成功的模型。 - `MUSE_AI_NEW_API_*_TIMEOUT_SECONDS`:与 P1R-4 runtime adapter 默认策略对齐的 smoke 超时配置。 - `MUSE_KNOWLEDGE_RAGFLOW_BASE_URL=http://100.64.0.8`:RAGFlow Knowledge runtime 调用地址。 - `MUSE_KNOWLEDGE_RAGFLOW_API_KEY`:用户提供且已通过 `/api/v1/datasets` 鉴权的 RAGFlow API key。 - `MUSE_KNOWLEDGE_RAGFLOW_GRAPHRAG_ATTRIBUTION_READY=false`:GraphRAG attribution 与 Muse 侧引用链路尚未验收,不能用作 completed 证据。 说明:上述凭据按用户明确授权明文记录并允许提交;它们只适用于当前内网验收上下文。若仓库未来同步到更大范围,必须先轮换 New-API 令牌。 ## 已验证事实 ### New-API 部署状态 运行位置:Tabby SSH 到 `100.64.0.8`。 已确认: - `new-api` 容器运行中,端口 `3000`,Docker health 为 healthy。 - `GET http://127.0.0.1:3000/api/status` 可达。 - New-API DB 运行在 `infra-postgres` 容器内,外部宿主机端口为 `100.64.0.8:5433`,应用容器内 DSN 使用 `infra-postgres:5432/new-api`。 ### New-API 数据库取证路径 远端 runtime 配置: - 文件:`/opt/new-api/.env.runtime` - 配置项:`SQL_DSN` - DSN 解析事实:`database=new-api`、`user=root`、Docker 内网 `host=infra-postgres`、`port=5432`、密码存在。 可用查询方式: ```bash eval "$(python3 - <<'PY' from pathlib import Path import urllib.parse, shlex line = next(l for l in Path('/opt/new-api/.env.runtime').read_text(errors='replace').splitlines() if l.startswith('SQL_DSN=')) v = line.split('=',1)[1].strip().strip('"').strip("'") u = urllib.parse.urlparse(v) print('PGUSER=' + shlex.quote(urllib.parse.unquote(u.username or ''))) print('PGPASSWORD=' + shlex.quote(urllib.parse.unquote(u.password or ''))) print('PGDATABASE=' + shlex.quote(u.path.lstrip('/'))) PY )" docker exec -e PGPASSWORD="$PGPASSWORD" infra-postgres \ psql -h 127.0.0.1 -U "$PGUSER" -d "$PGDATABASE" -qAtc 'select current_database(), current_user, now();' ``` 已验证结果摘要: - DB 查询返回 `new-api | root | `。 - token 表存在 `muse`、`muse-long-lived`、`rag` 等 token。 - `muse-long-lived` token 指纹:`len=48 sha256=7b03ff4b23ea`。 ### MiniMax-M2.5 chat smoke 运行位置:Tabby SSH 到 `100.64.0.8`。 请求摘要: - endpoint:`http://127.0.0.1:3000/v1/chat/completions` - token:`muse-long-lived`,仅记录指纹,不在日志摘要中展开。 - model:`MiniMax-M2.5` - prompt:`只输出 OK` - `stream=false` - `temperature=0` - request id:`p1r4-minimax-m25-20260602141936` 响应摘要: - HTTP 200 - `choices=1` - `finish=stop` - `content_prefix='OK'` - usage:`prompt_tokens=41`、`completion_tokens=87`、`total_tokens=128` - 响应耗时约 `6.6s` New-API 日志摘要: - `record consume log` - `model_name=MiniMax-M2.5` - `token_name=muse-long-lived` - `request_path=/v1/chat/completions` - `POST /v1/chat/completions` HTTP 200 ### P1R-4 Muse runtime client live acceptance 运行位置:`/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0/muse-cloud`。 命令: ```bash set -a . scripts/dev/p1r-external-acceptance.env set +a MUSE_P1R_EXTERNAL_ACCEPTANCE=true JAVA_HOME=$(/usr/libexec/java_home -v 21) \ mvn -pl muse-module-ai/muse-module-ai-server \ -Dtest=P1rNewApiLiveAcceptanceIT#shouldCallNewApiThroughMuseRuntimeClientAndPrintRedactedEvidence test ``` 已验证结果摘要: - `Tests run: 1, Failures: 0, Errors: 0, Skipped: 0` - `BUILD SUCCESS` - endpoint:`http://100.64.0.8:3000/v1/chat/completions` - token:`len=51 sha256Prefix=0c1de5374f1a` - model:`MiniMax-M2.5` - `summaryNormalized=OK` - `finishReason=stop` - usage:`promptTokens=139`、`completionTokens=85`、`totalTokens=224` - `providerRequestIdPresent=true` New-API 远端日志摘要: - `new-api` 容器为 `Up healthy`。 - `POST /v1/chat/completions` HTTP 200。 - `model_name=MiniMax-M2.5`。 - `token_name=muse`。 - `prompt_tokens=139`、`completion_tokens=85`。 - `request_path=/v1/chat/completions`。 - use time 约 `2s`,GIN relay 耗时约 `1.63s`。 ### P1R coverage 状态 本次没有修改 coverage。 当前基线仍应保持: - AI 41:`dedicated / needs_verification` - Knowledge 59:`dedicated / needs_verification` - completed operations:`0` - 唯一 `sse_placeholder`:P1R-7 `events / streamEvents / GET /app-api/muse/events` ### RAGFlow API 鉴权与初始数据集状态 运行位置:本机 worktree,直连 `100.64.0.8`。 已验证: - `GET http://100.64.0.8/v1/system/healthz`:HTTP 200,`status/db/doc_engine/redis/storage = ok`。 - `GET http://100.64.0.8:9380/v1/system/healthz`:HTTP 200,`status/db/doc_engine/redis/storage = ok`。 - 使用 New-API 系统管理令牌请求 `GET /api/v1/datasets`:HTTP 200 业务返回 `code=109 Authentication error: API key is invalid!`。 - 使用用户提供的 RAGFlow API key 请求 `GET /api/v1/datasets?page=1&page_size=10`:HTTP 200,业务返回 `code=0`。 - 首次验收前 RAGFlow tenant 下 `dataset_count=0`、`total=0`,说明鉴权可用但没有可复用验收 dataset/document。 ### P1R-5 Muse runtime client live acceptance 运行位置:`/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0/muse-cloud`。 命令: ```bash set -a . scripts/dev/p1r-external-acceptance.env set +a MUSE_P1R_EXTERNAL_ACCEPTANCE=true JAVA_HOME=$(/usr/libexec/java_home -v 21) \ mvn -pl muse-module-knowledge/muse-module-knowledge-server \ -Dtest=P1rRagFlowLiveAcceptanceIT#shouldCallRagFlowThroughMuseRuntimeClientAndPrintRedactedEvidence test ``` 已验证结果摘要: - `Tests run: 1, Failures: 0, Errors: 0, Skipped: 0` - `BUILD SUCCESS` - datasetName:`p1r-live-1780424506407` - datasetId:`e8145fb65eaf11f199d5dd203c62e4a2` - documentId:`e818cb1e5eaf11f199d5dd203c62e4a2` - health:`SUCCEEDED` - createDataset:`SUCCEEDED` - uploadDocuments:`SUCCEEDED` - startParseDocuments:`ACCEPTED` - pollDocumentStatuses:`SUCCEEDED` - document status:`museStatus=searchable`、`ragflowRun=DONE`、`progress=1` - listChunks:`SUCCEEDED` - retrieveChunks:`SUCCEEDED` - `retrievalChunksCount=1` - GraphRAG:`FAILED / ATTRIBUTION_NOT_CONFIGURED`,这是 attribution 未配置时的预期 fail-closed 行为,不作为 GraphRAG completed 证据。 RAGFlow 远端日志摘要: - `ragflow` 容器为 `Up healthy`。 - 依赖容器 `infra-mysql`、`infra-redis`、`infra-minio`、`infra-ragflow-infinity`、`infra-nginx` 为 healthy。 - 日志出现 `POST /api/v1/datasets` HTTP 200。 - 日志出现 `POST /api/v1/datasets/{datasetId}/documents` HTTP 200。 - 日志出现 `POST /api/v1/datasets/{datasetId}/chunks` HTTP 200。 - 日志出现 `GET /api/v1/datasets/{datasetId}/documents` HTTP 200。 - 日志出现 `GET /api/v1/datasets/{datasetId}/documents/{documentId}/chunks` HTTP 200。 - 日志出现 `POST /api/v1/retrieval` HTTP 200。 - parse 日志显示生成 1 个 chunk、完成 Embedding、Indexing done、Task done。 ### RAGFlow create dataset 兼容性修复 已验证事实: - 真实 RAGFlow `POST /api/v1/datasets` 带 `config:{}` 时返回 `code=101 Extra inputs are not permitted`。 - 真实 RAGFlow `POST /api/v1/datasets` 只发送 `name` 时返回 `code=0 data.id`。 - Muse adapter 已调整为 createDataset 只发送 `name`;`updateDatasetConfig` 仍保留独立提交 config 的能力。 - `pollDocumentStatuses` 已调整为使用真实支持的 `?id=`;多 document id 会在 Muse adapter 内 fail closed 为 `VALIDATION_ERROR`,避免生成 RAGFlow 不支持的批量查询。 ## 推断 - New-API 服务、认证、模型路由、上游 LLM 调用、消费日志链路已经对 `MiniMax-M2.5` 跑通。 - P1R-4 之前阻塞的“New-API chat/completions 未验收成功”已解除。 - RAGFlow 服务、鉴权、dataset/document/chunk/retrieval 链路已经通过 Muse Knowledge runtime client 跑通。 - 仅凭 runtime client live acceptance 还不足以证明 Muse 自身 AI 41 个 operation 和 Knowledge 59 个 operation 已完成端到端验收;还需要 Muse API 触发、任务状态、runtime call、job 和审计链路证据。 ## 剩余缺口 P1R-4 仍需补齐: 1. 通过 Muse dedicated AI API 触发一次真实 AI task,而不是只调用 runtime client。 2. 验证 Muse DB 中 task/job/runtime_call/event/audit 记录形成成功态。 3. 验证失败路径仍 fail closed,不因配置了真实 New-API 而伪造 success。 4. 经用户批准后,才可以申请把对应 AI operations 从 `needs_verification` 推进到 `completed`。 P1R-5 仍需补齐: 1. 通过 Muse dedicated Knowledge API 触发真实 dataset/document/retrieval 流程,而不是只调用 runtime client。 2. 验证 Muse DB 中 dataset/document/task/runtime_call/audit 记录形成成功态。 3. 验证失败路径仍 fail closed,不因配置了真实 RAGFlow 而伪造 success。 4. GraphRAG 需要确认默认 chat model、New-API 归因和 token 预算后再测。 5. 经用户批准后,才可以申请把对应 Knowledge operations 从 `needs_verification` 推进到 `completed`。 ## 推荐下一步命令 加载 New-API 验收配置: ```bash set -a . muse-cloud/scripts/dev/p1r-external-acceptance.env set +a ``` 直接重跑 New-API chat smoke: ```bash curl --noproxy '*' -sS -m 150 \ -H "Authorization: Bearer ${MUSE_AI_NEW_API_TOKEN}" \ -H 'Content-Type: application/json' \ --data '{"model":"MiniMax-M2.5","messages":[{"role":"user","content":"只输出 OK"}],"stream":false,"temperature":0}' \ "${MUSE_AI_NEW_API_BASE_URL}/v1/chat/completions" ``` Muse runtime adapter 方向应优先验证: ```bash cd muse-cloud set -a . scripts/dev/p1r-external-acceptance.env set +a MUSE_P1R_EXTERNAL_ACCEPTANCE=true JAVA_HOME=$(/usr/libexec/java_home -v 21) \ mvn -pl muse-module-ai/muse-module-ai-server \ -Dtest=P1rNewApiLiveAcceptanceIT#shouldCallNewApiThroughMuseRuntimeClientAndPrintRedactedEvidence test MUSE_P1R_EXTERNAL_ACCEPTANCE=true JAVA_HOME=$(/usr/libexec/java_home -v 21) \ mvn -pl muse-module-knowledge/muse-module-knowledge-server \ -Dtest=P1rRagFlowLiveAcceptanceIT#shouldCallRagFlowThroughMuseRuntimeClientAndPrintRedactedEvidence test ``` 注意:上面的 Maven 测试是 runtime client live acceptance,不等价于 Muse API 端到端 completed 证据。真正 completed 证据必须包含 Muse API 层触发、Muse 运行时对 New-API/RAGFlow 的真实调用、Muse 侧落库链路、审计记录和失败路径。 ## 新增 live acceptance harness 2026-06-02 新增两个默认跳过的 opt-in JUnit 验收入口,用于把当前 Muse runtime client 直接接到外部 New-API / RAGFlow,并输出脱敏 JSON 证据摘要: - P1R-4:`muse-module-ai/muse-module-ai-server/src/test/java/cn/iocoder/muse/module/ai/application/muse/facade/P1rNewApiLiveAcceptanceIT.java` - P1R-5:`muse-module-knowledge/muse-module-knowledge-server/src/test/java/cn/iocoder/muse/module/knowledge/application/muse/facade/P1rRagFlowLiveAcceptanceIT.java` 默认未设置 `MUSE_P1R_EXTERNAL_ACCEPTANCE=true` 时只跳过,不失败: ```bash cd muse-cloud JAVA_HOME=/Users/qingse/Library/Java/JavaVirtualMachines/corretto-21.0.7/Contents/Home \ mvn -pl muse-module-ai/muse-module-ai-server -Dtest=P1rNewApiLiveAcceptanceIT test JAVA_HOME=/Users/qingse/Library/Java/JavaVirtualMachines/corretto-21.0.7/Contents/Home \ mvn -pl muse-module-knowledge/muse-module-knowledge-server -Dtest=P1rRagFlowLiveAcceptanceIT test ``` 真实外部验收命令: ```bash cd muse-cloud set -a . scripts/dev/p1r-external-acceptance.env set +a export MUSE_P1R_EXTERNAL_ACCEPTANCE=true JAVA_HOME=/Users/qingse/Library/Java/JavaVirtualMachines/corretto-21.0.7/Contents/Home \ mvn -pl muse-module-ai/muse-module-ai-server -Dtest=P1rNewApiLiveAcceptanceIT test JAVA_HOME=/Users/qingse/Library/Java/JavaVirtualMachines/corretto-21.0.7/Contents/Home \ mvn -pl muse-module-knowledge/muse-module-knowledge-server -Dtest=P1rRagFlowLiveAcceptanceIT test ``` 说明: - 当前 `muse-cloud` checkout 没有 `./mvnw`,本机验证使用 `mvn`;如果后续补回 Maven Wrapper,可把命令中的 `mvn` 替换为 `./mvnw`。 - harness 输出只打印 endpoint、模型、dataset/document id、状态、耗时、usage、token/key 长度和 sha256 前 12 位,不打印完整 token/key。 - P1R-5 RAGFlow smoke 会创建唯一 `p1r-live-时间戳` dataset 并保留,不做删除,便于外部验收取证。 - GraphRAG 默认不作为 completed 证据;`MUSE_KNOWLEDGE_RAGFLOW_GRAPHRAG_ATTRIBUTION_READY=false` 时只验证 Muse adapter fail closed 为 `ATTRIBUTION_NOT_CONFIGURED`。真实 GraphRAG run/trace 需要额外设置 `MUSE_KNOWLEDGE_RAGFLOW_GRAPHRAG_ATTRIBUTION_READY=true` 和 `MUSE_KNOWLEDGE_RAGFLOW_GRAPHRAG_DATASET_ID`。 - 该 harness 只提供外部依赖 live evidence,不等价于 coverage completed;coverage 仍需 Muse API 端到端调用、落库、任务状态、审计和失败路径证据后再单独申请更新。