# STRING PPI Task 7:真实 9010 E2E 日期:2026-07-21 目标:`job_1784552755238_b8762f` / `Sv.HKL` 结果:**PASSED — 真实 Ortholog → PPI 主链与最终 9 项矩阵通过** ## 结论 最终 attempt 5 已通过真实 9010 API 完成 `preflight → PPI-owned Ortholog → ready_reference_mapping → PPI`。PPI 使用 STRING TaxID `4555` 查询、本地 normalization label `string_taxon_4555`,解析 6/6 个基因并获得 15 条互作;scoped Manifest 为 `success`,stage status 为 `completed`,6 个 artifacts 均存在且哈希匹配。 下文保留 attempt 1–4 的失败过程与原始证据;这些失败促成了 scope identity、owner TaxID 和 normalization label 的最小修订,不代表最终状态。最终 9 项只读矩阵也已通过,证明 Os direct、Sv/Ft/第二 unsupported 植物、未知身份、At fallback 以及 PPI/KaKs 数据依赖隔离均符合计划。 ## 基线 - Scope:`workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json` - Scope SHA256:`31d8f69ef697c9c802cc929cd2383aca8e700a6c7fc52a57db408156384ed711` - Target config:`Sv / Setaria_viridis`;显式树 TaxID `4556` - 提交前没有 Ortholog/PPI 文件,五条 `plantai_4090_9010.*` 队列均为 0。 - 9010 PIDs:Web `2523340`;workers `2523309, 2523315, 2523323, 2523330, 2523341`。 - STRING snapshot:v12.0,ID `ede47d546d853d0ec30ee75066976a35c08fd2412e6e5fc7866bbd205fc2eeb3`,source-manifest SHA `46fd3d72d7e2086682d7cb3723c668b6bb629087ad4c8ce1e1aac9480131c6e7`。 ## 1. 未确认与确认 preflight 真实请求:`POST /api/ppi/species-resolution`。核心请求体: ```json { "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "scopeFile": "workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "ppiSpecies": "auto", "targetSpecies": ["Sv"], "geneFamily": "HKL", "targetScientificName": "Setaria viridis", "ppiTargetTreeTaxonId": "4556", "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": false, "dependencyOwner": "ppi", "requestedStages": ["ppi"] } ``` 未确认结果为 `confirmation_required / ppi_reference_confirmation_required`,provenance 为 `required=true, confirmed=false`。把唯一确认字段改为 `true` 后,HTTP 200 返回: ```text status=needs_reference_data issue_code=ppi_reference_data_missing selected_taxon_id=4555 reference_species=string_taxon_4555 required_files=[pep] missing_required=[pep] ``` 没有 CDS 或 Ka/Ks 要求,确认后的 provenance 为 `required=true, confirmed=true`。 ## 2. 真实 reference bundle 下载 请求:`POST /api/reference-bundle/download` ```json { "job_id": "job_1784552755238_b8762f", "speciesCode": "string_taxon_4555", "speciesName": "Setaria italica", "taxonId": "4555", "requestedStages": ["ppi"], "includeRecommended": false, "timeoutSec": 600, "asyncMode": true } ``` - Task ID:`d9cdbb88-1eb0-4109-947d-f6e14f7f5eb4` - `/api/task/{id}`:`success`,progress 100 - Assembly:`GCF_000263155.2` - 下载:9,242,771 bytes - `requested_file_types=[pep]` - PEP records:35,844;CDS records:0 - PEP:[string_taxon_4555.pep.fasta](../../input/job_1784552755238_b8762f/string_taxon_4555/string_taxon_4555.pep.fasta),SHA `2c037fe5e3e17e6afe9dd7134c7a5ed4a6eb5e12c54c1cc1b29978b2f90bd926` - Manifest:`input/job_1784552755238_b8762f/string_taxon_4555/string_taxon_4555.reference_bundle_download.manifest.json` ## 3. 真实 PPI-owned Ortholog 第一次 direct request 错误地额外携带了普通 `referenceSpecies/refSpeciesList=[string_taxon_4555]`,入口按 config 物种校验并返回 HTTP 400,没有 task_id、队列或文件副作用。修正请求仅保留 owner 字段: ```json { "stage": "ortholog", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "blastEvalue": 0.00001, "scopeFile": "workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` - Task ID:`0a20a621-ca10-47fe-a4c3-da1d334303d2` - Queue:`plantai_4090_9010.medium`,CPU 4 - 结果:success,6 pairs - Log:`workspace/job_1784552755238_b8762f/logs/20260721_082842_ortholog.log` - Mapping:`workspace/job_1784552755238_b8762f/final/Sv.HKL.orthologs.txt`,SHA `cdce241cfa9217549ec3a940cd22bf69ca610e647d3b8f3cc204eef12a9aa677` - Sidecar:`workspace/job_1784552755238_b8762f/final/Sv.HKL.orthologs.txt.identity.json` - Manifest:`workspace/job_1784552755238_b8762f/final/Sv.HKL.ortholog.manifest.json` - Manifest/sidecar 均记录 reference TaxID `4555`、storage key `string_taxon_4555`、PEP SHA、target/member/mapping identity 与 mapping path。 ## 4. 阻断:post-Ortholog preflight 再次发送已确认的真实 preflight,HTTP 200 返回: ```text status=needs_ortholog decision=needs_reference_ortholog issue_code=stale_ortholog_identity_conflict message=Existing Ortholog mapping identity is stale or unverifiable: ppi_owner_mapping_sidecar_identity_mismatch. ``` 逐字段重算结果: | 字段 | Expected | Actual | 结果 | |---|---|---|---| | reference TaxID | `4555` | `4555` | 相同 | | storage key | `string_taxon_4555` | `string_taxon_4555` | 相同 | | reference PEP SHA | `2c037f…bd926` | `2c037f…bd926` | 相同 | | query path | `Target.Sv.HKL.curated_members.pep.fa` | 同左 | 相同 | | query SHA | `5da2e0…bc3a1` | 同左 | 相同 | | target identity | `c59de0…6f847` | 同左 | 相同 | | mapping path/SHA | `Sv.HKL.orthologs.txt` / `cdce24…677` | 同左 | 相同 | | member-set input | 空字符串 | 空字符串 | 相同 | | scope ID | `…target_only` | `…target_plus_reference` | **不同** | | member identity | `d29df1…d49e` | `6ba954…bb1f` | **不同** | | mapping identity | `a8f853…b060` | `f288bd…0568` | **不同** | 复算 `target_plus_reference` scope 精确得到 sidecar actual 的两项 identity,证明根因是 scope 身份分叉。 调用路径: - preflight:`_ppi_mapping_identity_matches_current_inputs` → 从传入的原 `target_only` scope 调 `build_scope_id` → `build_ortholog_run_identity`。 - producer:`run_stage(stage="ortholog")` 的 request context 把执行 scope 指向已有 `target_plus_reference` scope;PPI owner override 再替换 reference 为 `string_taxon_4555`,随后写 sidecar/manifest。 ## 停止边界与安全 按“任一步失败立即报告”的要求,阻断后没有提交 PPI,没有运行 API species matrix,没有构造 Bn backend job。最终没有任何 PPI 文件,default/medium 队列均为 0,也没有删除任何用户结果。 9000 五个 worker PID 保持 `3588799, 3588807, 3588814, 3588821, 3588830`。本任务没有向 9000 或 19000 发送请求/信号。只读终检发现先前的 19000 PID `2483131` 已由外部机制替换为 `2526118`(启动时间 08:28:48);该进程仅被观察,未被本任务操作。 结构化证据见 [JSON](./2026-07-21-string-ppi-task7-live-e2e.json)。 ## Attempt 2:scope 修复后的真实 9010 复验 9010 在受控重启后使用的新模块 SHA: - `apps/web/vue3/main.py`: `72261549d622e70a90a43f8795e3c9cf0eccf499899c62233e1f7c25768fd3e1` - `tasks.py`: `89b434ccd7e2a4c997efc87cbec954fbfd63857931752b2daa0549279f13fc08` - `gfa_core/mas/tools/stage_tools.py`: `ffda6ec77256e8ef23c2635210f5624db550c2e657aaaf8b38b0c3b820d5f1a9` - `apps/web/pipeline_backend.py`: `32b4391ec4d3fda87d78180b923bcb1c5d4066588980bbc61e73d5fe153b5d17` - `gfa_core/ortholog_materialize.py`: `a0a70088f230eb0560355c7a68cb05a9b4933c72cc626c9ebef6427f46c97913` ### Attempt 2 请求 再次向真实 `POST /api/execute` 提交 owner-only Ortholog 请求: ```json { "stage": "ortholog", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "blastEvalue": 0.00001, "scopeFile": "workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` 请求没有发送 `forceRerun` 或 `forceRerunStages`,所以 API 模型/参数构造中的有效值为 `forceRerun=false`、`forceRerunStages=[]`。请求模型没有 `use_existing` 字段,本次也未发送任何 `use_existing` 参数。 - API task ID:`cb4515ba-117f-4749-9b72-a5a083ad04dd` - Celery task ID:`66463b47-abe9-49f4-82a3-87263e11fad6` - Queue:`plantai_4090_9010.medium` - `/api/task/{id}`:`success`,6 pairs,Celery 用时 `0.5197922608349472s` ### Attempt 2 实际行为 worker 日志明确记录: ```text 09:00:12.554 WARN Effective member FASTA resolution failed for Target.string_taxon_4555.HKL 09:00:12.591 INFO Reusing identity-matched ortholog pairs for Sv -> string_taxon_4555: workspace/job_1784552755238_b8762f/ortholog/Sv.HKL.Sv_to_string_taxon_4555_pairs.txt 09:00:12.596 Direct single-stage result: success, 6 pairs 09:00:12.672 Celery task succeeded in 0.5197922608349472s ``` API/Celery success 消息声称日志为 `workspace/job_1784552755238_b8762f/logs/20260721_090012_ortholog.log`,但该文件不存在。`/api/task` 返回的 `log` 字段实际仍是 attempt 1 的 `20260721_082842_ortholog.log` 内容。这与 worker 的 reuse 行一致:attempt 2 没有执行新的 `run_ortholog.py` 命令。 中间产物没有变化: | 文件 | mtime | SHA256 | |---|---|---| | `ortholog/Sv.HKL.Sv_to_string_taxon_4555_pairs.txt` | `08:28:47.682668677` | `4c5e1c3b…d35f29` | | `ortholog/Sv.HKL.Sv_to_string_taxon_4555_pairs.txt.identity.json` | `08:28:47.714255320` | `f97a7774…6201` | final 物化产物在 attempt 2 被重写: | 文件 | mtime | SHA256 | |---|---|---| | `final/Sv.HKL.orthologs.txt` | `09:00:12.591883154` | `cdce241c…a677` | | `final/Sv.HKL.orthologs.txt.identity.json` | `09:00:12.592846398` | `f0a96652…14bca` | | `final/Sv.HKL.ortholog.manifest.json` | `09:00:12.593582705` | `3236e7ed…8f60` | | scoped Ortholog manifest | `09:00:12.594018966` | `dcccb1b7…1420` | intermediate sidecar 的核心 identity 仍为:TaxID `4555`、storage key `string_taxon_4555`、target identity `c59de0…6f847`、member identity `6ba954…bb1f`、mapping identity `00c273…6a0a`。物化后的 final sidecar 保留相同 target/member identity,final mapping identity 为 `f288bd…0568`。 ### Attempt 2 根因 新的 producer 修复位于 `pipeline_backend.py:9477-9506`:只有传入的 `ortholog_scope_data.scope_mode == "target_only"` 时,才设置 `preserve_target_only_scope=true`;随后 `build_ortholog_run_identity` 和 `ortholog_run_identity_matches` 决定是否复用中间结果。 但请求在到达该修复前已被 `/api/execute` 改写: 1. owner-only 请求只带 `ppiReferenceStorageKey=string_taxon_4555`,未带普通 `refSpecies/ppiReferenceSpecies/referenceBundleSpecies`。 2. `main.py:8898-8913` 构造 `technical_reference_species` 时不读取 `ppiReferenceStorageKey`,因此列表为空。 3. Ortholog 在 `main.py:8914-8937` 进入通用 target-reference fallback,恢复 job 默认参考 `At` 和 `target_plus_reference`。 4. `_ensure_gene_family_scope_file` 在 `main.py:9002-9013` 判定原 `target_only` scope 与新 expected scope 不同,生成 `Sv.HKL.HKL.target-Sv.ref-At.target_plus_reference.scope.json` 并替换请求中的 `scopeFile`。 5. Celery 经 `tasks.py::execute_single_stage_task` → `StageToolRegistry.execute` → `StageToolExecutor.execute` → `pipeline_backend.run_stage` 收到的是已经改写的 scope。 6. producer 看到 `source_scope_mode=target_plus_reference`,因此 `preserve_target_only_scope=false`;expected identity 与旧 intermediate sidecar 相同,`ortholog_run_identity_matches` 返回 true,并复用旧 pairs。 因此,attempt 2 证明当前修复点太晚:它能保留收到的 `target_only` scope,却无法纠正 API 入队前已经发生的 scope 改写。 ### Attempt 2 停止点 post-Ortholog 真实 preflight 在 `09:00:54` 再次返回 `needs_ortholog / stale_ortholog_identity_conflict`。按失败即停规则,没有提交 PPI,也没有运行 species matrix 或独立 Bn job;本轮没有代码修改或结果删除。 ## Attempt 3:target-only producer 修复后的真实主链 ### Gate 与 9010 重启 真实 job scope: - 绝对路径:`/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json` - SHA256:`31d8f69ef697c9c802cc929cd2383aca8e700a6c7fc52a57db408156384ed711` - `scope_id=HKL.target-Sv.target_only`,`scope_mode=target_only`,target=`[Sv]`,reference=`[]` 重启前确认 9010 Web/worker 全部位于目标目录,使用 `BBAV5_QUEUE_PREFIX=plantai_4090_9010`、`BBAV5_REDIS_URL=redis://localhost:6379/11`,DB11 PONG。只停止旧 9010 Web PID `2544115` 和五个 worker master `2544081/2544089/2544096/2544103/2544116`。 重启后: - Web:`2586056` - default/heavy/medium/light/rnaseq:`2586051/2586052/2586053/2586054/2586055` - 5/5 worker pong;`/docs` 与 `/openapi.json` 均 HTTP 200 - 9000 worker master `3588799/3588807/3588814/3588821/3588830` 与 19000 Web `2529914` 未变 - 当前 `apps/web/vue3/main.py` SHA:`90240498d608c8182afb10ad79e81a0213b20e428c3a20f69a7c63c9458266a4` ### 真实 preflight 与 Ortholog confirmed owner preflight 使用原 target-only scope、TaxID `4555`、storage key `string_taxon_4555`,先返回预期的 `needs_ortholog / stale_ortholog_identity_conflict`。随后提交: ```json { "stage": "ortholog", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "blastEvalue": 0.00001, "scopeFile": "/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` - API task:`eaf45f36-d86e-4887-ae2d-d799d3ccaaef` - Celery task:`6ad681e3-e7d5-49fd-b78c-0d8c999b3df6` - 真实新命令已执行,Celery 用时 `5.773302449146286s`;没有 reuse 行 - 新日志:`logs/20260721_100750_ortholog.log`,SHA `902d3998e3c3098ff62b67817867d89dfb3aa7d690877dee292627118b4215f5` - intermediate pair/sidecar mtime 均更新为 `10:07:56`;sidecar SHA `21d61a72…00fe6` - final sidecar SHA `ffd3c39b…90358` - scoped manifest:`Sv.HKL.HKL.target-Sv.target_only.ortholog.manifest.json`,SHA `95e74562…1ce07` - manifest/sidecar 均记录 TaxID `4555`、storage key `string_taxon_4555`、PEP SHA `2c037f…bd926`、target identity `c59de0…6f847`、member identity `dc9fbb…094a` - manifest `scope_id=HKL.target-Sv.target_only`、`scope_mode=target_only`、`analysis_route=target_only`,scopeFile 保持原绝对路径 post-Ortholog preflight 返回 HTTP 200:`status=ready`、`decision=ready_reference_mapping`、issue code 为空,provenance `required=true, confirmed=true`。 ### 真实 PPI 请求与失败 在 ready gate 后提交的完整请求: ```json { "stage": "ppi", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "scopeFile": "/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiSpecies": "auto", "ppiScore": 200, "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` - API task:`1f2a89c4-5042-4b93-a50f-923cd8925bfa` - Celery task:`a25e255e-6d14-4c8f-98ac-151b90aa682c` - Queue:`plantai_4090_9010.light`,CPU 4 - Celery task wrapper 用时 `11.837375451112166s`,业务结果为 failed - 错误:`PPI 无法从 Ortholog 映射推断 STRING 参考物种` - issue code:`ppi_invalid_ortholog_mapping` Celery 的原始 kwargs 未写入 task 状态或 worker 日志,不能事后逐字恢复;可验证的有效参数链为:`main.py` 将请求的 `ppiSpecies/ppiReferenceTaxonId/StorageKey/SelectionMode/UserConfirmed` 放入 params,`StageToolExecutor` 将同名字段传入 `run_stage`。失败 provenance 保留 `selection_mode=tree_nearest`、`confirmed=true`、mapping reference=`string_taxon_4555` 和 mapping path,证明 owner 状态已到达执行层。 PPI 在调用 `skills/ppi/run.py` 之前失败,所以: - 没有新的 PPI stage log - worker 没有 `[CMD] ... skills/ppi/run.py` - 没有 network/report/url/id-resolution 等 PPI 成功 artifacts - 仅生成中间 source ID 文件 `ppi/analysis/Sv.HKL.HKL.target-Sv.target_only.ppi_source_ids.txt`,6 IDs,SHA `1e0cc6…df2ef` - failed manifest:`final/Sv.HKL.ppi.manifest.json`,SHA `ce6e65ec…f885a`,`artifacts={}` - 精确 scope 的 `/api/stage-status` 为 `not_found/completed=false`,因为 scoped PPI manifest 未生成 failed manifest resolution 为:`ppiSpecies=auto`、selected taxon/reference 为空、fallback=`invalid_mapping`、reason=`ortholog_mapping_target_species_not_supported_by_string`。失败 provenance 的 selected taxon 也为空,但仍保留确认信息与 `string_taxon_4555` mapping。 ### Attempt 3 根因判定 这不是验证请求遗漏字段,也不是 API→Celery 传输丢字段。当前前端真实请求构造同样保持 `ppiSpecies=auto`:`executeStageDirect` 从 stage/confirm 取值,否则为 `auto`;`applyPpiOwnerFieldsToRequest` 只追加 owner TaxID/storage/mode/confirmed,不把 `ppiSpecies` 改成 selected TaxID。因此本次请求与真实前端路径一致。 执行层的分叉为: 1. `run_stage` 对 `ppiSpecies=auto` 将 execution species 初始化为空。 2. target-only scope 的 reference list 为空,所以不能从 scope 得到 execution species。 3. 读取 mapping 第五列得到 `string_taxon_4555`,但 `infer_string_species_from_ortholog_mapping` 仅调用 legacy `species_to_string_code`;storage key 不在该别名表中,因此返回空。 4. `run_stage` 虽已收到 `ppiReferenceTaxonId=4555` 与 storage key,却没有在该解析分支用 owner TaxID 作为 STRING execution identity,于 CLI 前失败。 5. 失败 provenance 的 selected taxon 为空是次生记录问题:`fail_ppi_execution` 仅从空的 `ppi_species` 计算 TaxID,也没有使用 `ppi_reference_taxon_id`。 按失败即停规则,没有重试、没有改请求、没有修改代码、没有运行物种矩阵或 Bn job。终检五个 9010 队列均为 0;9000/19000 PID 保持不变。 ## Attempt 4:复用 ready Ortholog 后的单次真实 PPI 重试 ### Gate、重启与请求 本轮没有重跑 Ortholog。重启前、重启后分别用真实 `/api/ppi/species-resolution` 确认已有映射为 `ready / ready_reference_mapping`:TaxID `4555`、storage key `string_taxon_4555`,provenance confirmation 为 `required=true, confirmed=true`。复用的 final mapping 为 `final/Sv.HKL.orthologs.txt`,SHA256 `cdce241c…a677`;final sidecar SHA256 `ffd3c39b…90358`;scoped Ortholog manifest SHA256 `95e74562…1ce07`。 只重启了 9010:Web PID `2595459`,default/heavy/medium/light/rnaseq worker master 为 `2595454/2595455/2595456/2595457/2595458`,5/5 pong,`/docs` 与 `/openapi.json` 均 HTTP 200。9000 worker master `3588799/3588807/3588814/3588821/3588830` 和 19000 Web PID `2529914` 未变化。 生效代码 SHA256: | 文件 | SHA256 | |---|---| | `apps/web/vue3/main.py` | `90240498d608c8182afb10ad79e81a0213b20e428c3a20f69a7c63c9458266a4` | | `tasks.py` | `89b434ccd7e2a4c997efc87cbec954fbfd63857931752b2daa0549279f13fc08` | | `gfa_core/mas/tools/stage_tools.py` | `ffda6ec77256e8ef23c2635210f5624db550c2e657aaaf8b38b0c3b820d5f1a9` | | `apps/web/pipeline_backend.py` | `57b35484a89cb096211ac18032a34ad220a33dbc5bc98a455724713ce3303d05` | | `gfa_core/ortholog_materialize.py` | `a0a70088f230eb0560355c7a68cb05a9b4933c72cc626c9ebef6427f46c97913` | | `gfa_core/ppi_provenance.py` | `b4d947d5…c3031` | | `gfa_core/mas/tools/stage_status.py` | `a3fc7012…d473` | | `skills/ppi/run.py` | `8518de8c…36afe` | 提交的完整 PPI 请求与 attempt 3 相同: ```json { "stage": "ppi", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "scopeFile": "/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiSpecies": "auto", "ppiScore": 200, "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` - API task ID:`fd77c17d-0387-477c-a294-747f41277529` - Celery task ID:`f401575e-43ac-43dd-84ac-26d1b20a392e` - Queue:`plantai_4090_9010.light`,CPU 4 - wrapper 用时:`29.942377381026745s` - 业务状态:`failed` ### 完整执行身份与失败证据 本轮通过了 attempt 3 的 execution-species 阻塞,真实 CLI 已执行: ```text /home/xzq/miniconda3/envs/test4py311/bin/python skills/ppi/run.py --gene-ids /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/ppi/analysis/Sv.HKL.HKL.target-Sv.target_only.ppi_source_ids.txt --species 4555 --normalization-species-label 4555 --prefix Sv.HKL --output /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/ppi --score 200 --provenance-json /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/ppi/Sv.HKL.ppi_provenance.json --mapping /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.orthologs.txt --id-map /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/input/job_1784552755238_b8762f/string_taxon_4555/string_taxon_4555.pep_cds_idmap.tsv ``` ID map 的 header 与首个证据行是: ```text species_code protein_id pep_id cds_id gene_id ncbi_gene_id pep_present cds_present pep_header cds_header string_taxon_4555 NP_001267731.1 NP_001267731.1 ... ``` skill 在载入 6 个 source IDs 和 6 条 Ortholog mapping 后停止,精确错误为: ```text Alias evidence species mismatch at row 2: declared '4555', observed 'string_taxon_4555' ``` 因此 attempt 4 的单一直接阻塞点是两个不同层级的身份被当成同一个字段: - STRING 远程查询 execution identity:TaxID `4555`,`--species 4555` 正确; - 本地 reference bundle / ID-map normalization identity:storage key `string_taxon_4555`; - 实际错误参数:`--normalization-species-label 4555`,与 ID map 的 `species_code=string_taxon_4555` 冲突。 也就是说,Ortholog mapping、owner TaxID、STRING 查询物种和确认 provenance 都已正确到达执行层;本次失败只由 normalization label 未使用 storage identity 触发。 ### Manifest、provenance 与停止点 | 文件 | SHA256 | 结果 | |---|---|---| | `logs/20260721_102510_ppi.log` | `07f7cb3a…d650` | 完整 CLI 与 mismatch 错误 | | `final/Sv.HKL.ppi.manifest.json` | `987b929b…886f` | failed,`artifacts={}` | | `ppi/Sv.HKL.manifest.json` | `71250422…6463e` | failed,精确 mismatch message | | `ppi/Sv.HKL.ppi_provenance.json` | `94875cbf…4242` | selected TaxID `4555`、mapping reference `string_taxon_4555`、normalization label `4555` | | scoped source IDs | `1e0cc6e5…df2ef` | 6 IDs | `final/Sv.HKL.ppi.manifest.json` 是 stale/merge 的 legacy failed manifest:顶层 error 已更新为 attempt 4 的 exit-code/log,但 timestamp 和 `parameters.ppi_species_resolution` 仍保留 attempt 3 的 `10:09:28 / invalid_mapping`;其 provenance 则已更新为 selected TaxID `4555` 和 normalization label `4555`。因此不能把旧 resolution 块当作本轮根因。 精确 scoped `/api/stage-status` 返回 `not_found/completed=false`,期望 manifest 为 `final/Sv.HKL.HKL.target-Sv.target_only.ppi.manifest.json`;legacy task stage status 为 `failed/completed=false`、`artifacts_checked=0`。没有生成 network/report/url/id-resolution 等成功产物。 按失败即停规则,本轮没有 PPI 重试、没有 Ortholog 重跑、没有物种矩阵、没有独立 Bn job、没有代码修改或文件删除。终检五个 9010 队列均为 0,9000/19000 进程保持不变。 ## Attempt 5:normalization identity 修复后的真实 PPI 成功 ### Gate 与 9010 重启 本轮仍只执行 PPI,没有重跑 Ortholog。重启前和重启后两次真实 `/api/ppi/species-resolution` 均返回: ```text status=ready decision=ready_reference_mapping selected_taxon_id=4555 reference_species=string_taxon_4555 mapping_reference_species=string_taxon_4555 confirmation required=true, confirmed=true ``` 既有 Ortholog 身份未变化:mapping SHA256 `cdce241c…a677`,final sidecar `ffd3c39b…90358`,target-only scoped Ortholog manifest `95e74562…1ce07`。生效代码 SHA256 为: | 文件 | SHA256 | |---|---| | `apps/web/vue3/main.py` | `90240498d608c8182afb10ad79e81a0213b20e428c3a20f69a7c63c9458266a4` | | `tasks.py` | `89b434ccd7e2a4c997efc87cbec954fbfd63857931752b2daa0549279f13fc08` | | `gfa_core/mas/tools/stage_tools.py` | `ffda6ec77256e8ef23c2635210f5624db550c2e657aaaf8b38b0c3b820d5f1a9` | | `apps/web/pipeline_backend.py` | `9834917f36c9b400b22b7a8a50b7e047a57a3cf3e01ee83184f5e3b5aa9a629a` | | `gfa_core/ortholog_materialize.py` | `a0a70088f230eb0560355c7a68cb05a9b4933c72cc626c9ebef6427f46c97913` | | `gfa_core/ppi_provenance.py` | `b4d947d5ffa05db776039ffdec0c6f713e247a706994673dff1d92e4733c3031` | | `gfa_core/mas/tools/stage_status.py` | `a3fc701271bbfca599324eeac721f027dd67752a1e640977b9ffef76cb21d473` | | `skills/ppi/run.py` | `2f592370b3c0c97d8f5e0500f348099fb85e581ad29219e2143b629011327a12` | 仅重启 9010:Web PID `2608735`,default/heavy/medium/light/rnaseq worker master 为 `2608731/2608635/2608732/2608607/2608636`;5/5 pong,`/docs` 与 `/openapi.json` HTTP 200。9000 worker master `3588799/3588807/3588814/3588821/3588830` 与 19000 Web PID `2529914` 未变化。 ### 唯一真实 PPI 请求 ```json { "stage": "ppi", "job_id": "job_1784552755238_b8762f", "prefix": "Sv.HKL", "cpu": 4, "scopeFile": "/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev/workspace/job_1784552755238_b8762f/final/Sv.HKL.HKL.target-Sv.target_only.scope.json", "scopeMode": "target_only", "analysisRoute": "target_only", "geneFamily": "HKL", "targetSpecies": ["Sv"], "ppiSpecies": "auto", "ppiScore": 200, "ppiReferenceTaxonId": "4555", "ppiReferenceStorageKey": "string_taxon_4555", "ppiReferenceSelectionMode": "tree_nearest", "ppiReferenceUserConfirmed": true, "dependencyOwner": "ppi" } ``` - API task ID:`72ddcc69-fa90-4514-bd78-3a931e8054c9` - Celery task ID:`44f60fe5-ffcc-4def-b9fd-48d531a085a2` - Queue:`plantai_4090_9010.light`,CPU 4 - Celery wrapper:`32.72843774687499s` - 最终业务状态:`success` 真实 CLI 中两个身份已正确分离: ```text ... skills/ppi/run.py ... --species 4555 --normalization-species-label string_taxon_4555 ... ``` 其中 `4555` 仅用于 STRING 远程查询,`string_taxon_4555` 用于本地 reference bundle / ID-map 归一化校验。attempt 4 的 alias-evidence mismatch 不再出现。 ### STRING 真实请求与生物结果 stage log `logs/20260721_104344_ppi.log`(SHA256 `eb3cfcb8…dc5f`)记录:载入 6 个目标 ID、6 条 Ortholog mapping;向 STRING TaxID `4555` 查询 6 个已解析 ID: ```text 4555.K3Z5J1, 4555.K3Z625, 4555.K3ZDE9, 4555.A0A368R4B9, 4555.K3XGZ3, 4555.K3XGV8 ``` 真实 STRING URL 明确包含 `species=4555&required_score=200&network_type=functional`。结果:6/6 genes、15 interactions,平均 score `0.904`,15 条均为 high-confidence;ID resolution 的 member/query mapping rate 均为 `1.0`,0 unresolved、0 ambiguous。STRING network image API 另生成有效 PNG,`3253 × 793`、RGBA、161,819 bytes。 ### Manifest、artifacts 与 scoped status target-only scoped success manifest:`final/Sv.HKL.HKL.target-Sv.target_only.ppi.manifest.json`,SHA256 `118ddf51…0359`。其 `scope_id=HKL.target-Sv.target_only`、`scope_mode=target_only`、`analysis_route=target_only`、`member_set_id=HKL.target-Sv.target_only:target_only:all_members`。 | Artifact | SHA256 | 大小 | |---|---|---:| | `final/Sv.HKL.ppi_network.tsv` | `9fe9e10c…c52a` | 492 | | `final/Sv.HKL.ppi_report.md` | `866e63d6…d60f` | 717 | | `final/Sv.HKL.ppi_id_resolution.tsv` | `488f0a2a…5399` | 1,845 | | `final/Sv.HKL.ppi_url.txt` | `3c26395f…dbdf` | 304 | | `final/Sv.HKL.ppi_network.string.png` | `fe7891cf…b862` | 161,819 | | `final/Sv.HKL.ppi_alphafold2_links.tsv` | `dde7bdba…1598` | 1,748 | 精确 scoped `/api/stage-status` 返回 `status=completed, completed=true, manifest_status=success, artifacts_checked=6`,missing artifacts 与 errors 均为空。provenance 一致记录:selected STRING TaxID `4555`、mapping reference `string_taxon_4555`、normalization label `string_taxon_4555`、selection mode `tree_nearest`、user confirmation `required=true, confirmed=true`,STRING snapshot ID 仍为 `ede47d…eeb3`。 本轮没有 Ortholog 重跑、PPI 重试、物种矩阵、独立 Bn job、代码修改或文件删除。终检五个 9010 队列均为 0;9000/19000 进程保持不变。 ## Final read-only matrix:当前 9010 + 已部署 snapshot 验证方式:仅调用既有 job `job_1784552755238_b8762f` 的 `POST /api/ppi/species-resolution`,并读取 attempt 5、Task 4 的既有证据。没有调用 `/api/execute`、没有新建 job、没有触发 PPI/Ortholog/KaKs、没有重启或修改代码。所有预检请求 HTTP 均为 `200`。 | # | 场景 | 关键请求 | 关键响应/证据 | 等级 | 结果 | |---:|---|---|---|---|---| | 1 | Os direct,无 Ortholog | `Os / Oryza sativa Japonica Group / TaxID 39947 / requestedStages=[ppi]` | `ready / ready_target_string / exact_string / selected=39947 / candidates=[]`。未传 scope/mapping。父种 TaxID `4530` 另返回 Oryza Top3,未被错误当作 exact。 | real API | PASS | | 2 | Sv tree-nearest Top3 与确认 | `Sv / Setaria viridis / 4556`;确认时 owner=`4555,string_taxon_4555,tree_nearest,true` | 未确认:`confirmation_required`,Top3 `4555(d2),4540(d6),888268(d6)`;确认:`ready_reference_mapping`,mapping=`final/Sv.HKL.orthologs.txt`,provenance confirmed=true。 | real API + real job | PASS | | 3 | Ft 动态近源 | `Ft / Fagopyrum tataricum / 62330` | Top3 `3562(d10),3476(d12),3775(d12)`;`candidate_source=string_species_tree`、`resolution_source=explicit_tree_taxon_id`、policy=`string_species_tree_v12_topology_v1`。响应没有静态 Ft 标记。 | real API | PASS | | 4 | 旧 map 外、registry 内 | `Bn / Brassica napus / 3708` | 当前 API:`ready_target_string / exact_string / selected=3708`。真实 STRING 证据:`docs/validation/2026-07-21-string-ppi-task4-real-network.{md,json}`,TaxID 3708 alias/network 均成功。 | real API + prior real STRING | PASS | | 5 | 第二 unsupported 植物稳定 Top3 | `Cs / Camellia sinensis / 4442`,相同请求两次 | 两次均为 `542762(d1),1590841(d7),4155(d9)`,`candidate_source=string_species_tree`;非 Ft。 | real API ×2 | PASS | | 6 | unknown 补身份,不猜 At | 第一次 `Xx` 无 scientific name/TaxID;第二次补 `Camellia sinensis / 4442` | 第一次 `unresolved / target_string_tree_unresolved`、空 candidates/reference;补身份后返回 Camellia Top3,第一候选 `542762`,不是 At。 | real API | PASS | | 7 | 自然 At fallback 的确认门 | `Aa / Arabidopsis arenosa / 38785`,候选 Top1 `3702 At`;owner storage=`At`、mode=`model_fallback` | 未确认:`confirmation_required`;确认:`needs_ortholog`(未执行),selected=`3702`、reference=`At`、PEP complete;provenance required=true/confirmed=true,species_resolution.reference_selection_mode=`model_fallback`。 | real API | PASS | | 8 | nearest 主链成功 | 读取 attempt 5 | scoped manifest SHA `118ddf51…0359` 与当前文件一致;network SHA `9fe9e10c…c52a`;6/6 genes、15 interactions、mapping rate 1.0;TaxID 4555、storage normalization `string_taxon_4555`。 | prior real job + current file verification | VERIFIED | | 9 | PPI 与 KaKs/CDS 独立 | PPI-only 使用已确认 Sv owner;KaKs-only 使用同一 storage/reference | PPI-only 保持 `ready_reference_mapping`;KaKs-only 返回 `needs_reference_data / kaks_reference_cds_missing`,bundle=`pep_only`、missing=`[cds]`、`kaks_ready=false`。没有触发任何 stage。 | real API | PASS | ### 请求/响应身份摘要 - API:`http://127.0.0.1:9010/api/ppi/species-resolution` - Snapshot:STRING `12.0`,ID `ede47d546d853d0ec30ee75066976a35c08fd2412e6e5fc7866bbd205fc2eeb3` - 所有 tree-nearest 候选均携带 LCA、两侧 edge 数和 `tree_distance`。 - Item 7 特意使用 snapshot 中 At 自然为 Top1 的 `Arabidopsis arenosa`;对 Ft 强塞 At 的试探被 API 继续阻断为 `confirmation_required`,没有把非候选伪装成 fallback。 - Item 9 的 PPI 与 KaKs 是两个独立预检请求;KaKs 缺 CDS 没有覆盖或中断 PPI 的 ready 状态。 - 终检五个 `plantai_4090_9010.*` Redis 队列长度均为 `0`。 结构化字段已追加到同名 JSON 的 `final_read_only_matrix`。