11 KiB
STRING PPI production wiring — Task 2 identity validation
Date: 2026-07-21
Authoritative target: /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev
Scope: job-local target identity input only; no resolver/preflight decision wiring.
Boundaries
- Added a read-only job-local identity reader for
config.xlsx. - Added independent request fields
targetScientificNameandppiTargetTreeTaxonId. - Passed those fields to the backend and returned a separate
target_identityobject. - Did not modify KaKs, Ortholog, PPI execution, legacy recommendation replacement, or STRING resolver preflight decisions.
Discovery evidence
The required first CodeGraph query was attempted:
timeout 15s codegraph explore "PpiSpeciesResolutionRequest species-resolution API job config.xlsx Species_Code Species_Name Taxon_ID TaxID NCBI_TaxID targetScientificName ppiTargetTreeTaxonId"
Exit code: 124; no output. Targeted rg and bounded source reads were used after recording the timeout.
RED evidence
Initial identity suite:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_ppi_target_identity.py'
Exit code: 1. Result: 6 failed in 1.78s.
- Five tests failed because
resolve_ppi_target_identitydid not exist. - The request-contract test failed because
PpiSpeciesResolutionRequesthad notargetScientificNamefield.
Additional backend propagation RED:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_ppi_target_identity.py::test_explicit_identity_reaches_backend_without_using_ppi_species'
Exit code: 1. Result: 1 failed in 0.32s; failure was TypeError: resolve_ppi_species_resolution() got an unexpected keyword argument 'target_scientific_name'.
GREEN evidence
Focused Task 2 suite:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_ppi_target_identity.py'
Exit code: 0. Result: 7 passed in 1.80s.
Review-blocker correction: scientific-name conflict
The first Gate 2 review found that an explicit scientific name could be mixed with a different job scientific name and the job TaxID. Two negative tests were added before changing production code:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_ppi_target_identity.py::test_explicit_scientific_name_conflict_never_mixes_with_job_taxon tests/unit/test_ppi_target_identity.py::test_species_resolution_api_surfaces_scientific_name_conflict'
RED exit code: 1. Result: 2 failed in 1.31s; both helper and API returned
resolved instead of conflict.
After adding only the normalized-name consistency check, the same command had
exit code 0: 2 passed in 1.25s. The full Task 2 identity suite then had exit
code 0: 9 passed in 1.37s.
The conflict response is target_scientific_name_conflict and deliberately
leaves both scientific_name and tree_taxon_id empty, preventing a mixed
name/TaxID identity from reaching later stages.
Syntax and related identity/API/snapshot regression:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m py_compile apps/web/pipeline_backend.py apps/web/vue3/main.py tests/unit/test_ppi_target_identity.py && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_ppi_target_identity.py tests/unit/test_ppi_frontend_display_contract.py tests/unit/test_string_species_snapshot.py tests/unit/test_string_species_registry.py'
Exit code: 0. Result: 46 passed in 13.67s.
Existing backend preflight regression probe:
ssh planai5090 'cd /home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev && /home/xzq/miniconda3/envs/test4py311/bin/python -m pytest -q tests/unit/test_pipeline_backend_execution_env.py -k "ppi_species_resolution or os_direct_ppi"'
Exit code: 1. Result: 8 passed, 1 failed, 30 deselected.
The sole failure is test_os_direct_ppi_uses_complete_string_registry_without_ortholog, which expects a top-level selection_mode. That field belongs to Task 3 resolver/preflight wiring and is intentionally absent after Task 2. It is not claimed as passing here and was not repaired out of scope.
Identity contract verified
Species_Code=Svplus repeatedSetaria_viridis/Setaria viridisrows yields one canonicalSetaria viridisidentity.Taxon_ID,TaxID, andNCBI_TaxIDare accepted; within one row their priority is that order.- Explicit tree TaxID has priority but a mismatch with the unique job TaxID returns
target_taxon_id_conflict; no silent overwrite occurs. - Bare
Svwith no job or explicit identity returnstarget_string_tree_unresolved; no two-letter-code guess occurs. - Existing curated
Os -> 39947andFt -> 62330compatibility identities remain available. ppiSpeciesremainsautowhen explicit target identity fields are supplied; target tree identity is not placed inppiSpecies.
Changed files and hashes
apps/web/pipeline_backend.py
1c94e33a061fdeba6cc3816968b4e722a03fd3a2886665f6e28d848e24003ccf
apps/web/vue3/main.py
f12cddaaeb0d3e39165884cf1603ef05a79a14ceb02da5e1629fe83fd4e4180f
tests/unit/test_ppi_target_identity.py
7282a78e0e8a384f1ea1ad2abc58464b7d204ddd27e65a8da6e46b11e5965bdc
Gate 2
- Job scientific-name identity: PASS.
- Explicit scientific-name and target-tree-TaxID request channels: PASS.
- Supported TaxID columns and deterministic row priority: PASS.
- Explicit/job TaxID conflict is structured: PASS.
- Explicit/job normalized scientific-name conflict is structured at helper and API layers: PASS.
- Conflicting scientific name is never combined with the job TaxID: PASS.
- Bare unknown short code is not guessed: PASS.
- Os/Ft compatibility identity: PASS.
- Target identity remains separate from
ppiSpecies: PASS. - Task 2 focused and related non-resolver regressions: PASS.
- Task 3
selection_moderegression: NOT PASSED / out of Task 2 scope.
Task 2 Gate: PASS for identity-input scope only. This does not authorize or claim Task 3 resolver/preflight completion.
Online Gate on port 9010
The target has no systemd unit or dedicated 9010 restart script. The observed authoritative process-management pattern was:
start_celery_9000.shwith externally suppliedBBAV5_QUEUE_PREFIX=plantai_4090_9010andBBAV5_REDIS_URL=redis://localhost:6379/11for five workers;- direct
nohup ... python -m uvicorn apps.web.vue3.main:app --port 9010for the Web process.
Before restart, the exact 9010 master PIDs were:
Web 2391890
default 2391860
heavy 2391866
medium 2391873
light 2391880
rnaseq 2391891
launcher shell 2391849
All six service processes had cwd
/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev, queue prefix
plantai_4090_9010, and Redis URL redis://localhost:6379/11.
Only those exact PIDs were stopped:
kill -TERM 2391890 2391860 2391866 2391873 2391880 2391891 2391849
Workers were restarted with:
env BBAV5_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
PLANTAI_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
BBAV5_CONDA_BASE=/home/xzq/miniconda3 \
BBAV5_DEFAULT_ENV=test4py311 \
BBAV5_QUEUE_PREFIX=plantai_4090_9010 \
BBAV5_REDIS_URL=redis://localhost:6379/11 \
BBAV5_CELERY_LOG_DIR=logs/runtime_9010/celery \
BBAV5_RNASEQ_CONCURRENCY=2 \
bash ./start_celery_9000.sh
Web was restarted with:
nohup env BBAV5_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
PLANTAI_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
BBAV5_QUEUE_PREFIX=plantai_4090_9010 \
BBAV5_REDIS_URL=redis://localhost:6379/11 \
/home/xzq/miniconda3/envs/test4py311/bin/python -m uvicorn \
apps.web.vue3.main:app --host 0.0.0.0 --port 9010 \
> logs/runtime_9010/web.log 2>&1 < /dev/null &
The combined remote shell initially attempted to write web.pid before its
backgrounded command group had created logs/runtime_9010, producing one
No such file or directory message. Process inspection showed the Web process
was healthy at PID 2455555; the temporary wrapper shell PID 2455480 was
terminated and logs/runtime_9010/web.pid was corrected to 2455555. No second
Web process was started.
After restart, the master PIDs were:
Web 2455555
default 2455521
heavy 2455528
medium 2455537
light 2455544
rnaseq 2455556
Every PID changed. All six new processes have the authoritative target cwd,
queue prefix plantai_4090_9010, and Redis DB 11. The exact worker health check
was:
env BBAV5_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
PLANTAI_PROJECT_ROOT=/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev \
BBAV5_QUEUE_PREFIX=plantai_4090_9010 \
BBAV5_REDIS_URL=redis://localhost:6379/11 \
/home/xzq/miniconda3/envs/test4py311/bin/celery -A celery_app inspect ping \
-d plantai_4090_9010_default@xzq-Rack-Server,plantai_4090_9010_heavy@xzq-Rack-Server,plantai_4090_9010_medium@xzq-Rack-Server,plantai_4090_9010_light@xzq-Rack-Server,plantai_4090_9010_rnaseq@xzq-Rack-Server \
--timeout=10
Exit code: 0; result: 5 nodes online, all five returned pong. HTTP
GET http://127.0.0.1:9010/docs returned 200.
Live API evidence
Both requests used the real Sv job job_1784552755238_b8762f and endpoint
POST http://127.0.0.1:9010/api/ppi/species-resolution.
Exact request commands:
curl -sS -X POST http://127.0.0.1:9010/api/ppi/species-resolution \
-H "Content-Type: application/json" \
--data-binary '{"job_id":"job_1784552755238_b8762f","prefix":"Sv.HKL","ppiSpecies":"auto","targetSpecies":["Sv"],"referenceSpecies":[],"geneFamily":"HKL","requestedStages":["ppi"],"targetScientificName":"Setaria viridis","ppiTargetTreeTaxonId":"4556"}'
curl -sS -X POST http://127.0.0.1:9010/api/ppi/species-resolution \
-H "Content-Type: application/json" \
--data-binary '{"job_id":"job_1784552755238_b8762f","prefix":"Sv.HKL","ppiSpecies":"auto","targetSpecies":["Sv"],"referenceSpecies":[],"geneFamily":"HKL","requestedStages":["ppi"],"targetScientificName":"Oryza sativa","ppiTargetTreeTaxonId":"39947"}'
Consistent explicit identity:
{
"targetScientificName": "Setaria viridis",
"ppiTargetTreeTaxonId": "4556"
}
Response summary:
{
"success": true,
"requested_ppi_species": "auto",
"selection_mode": null,
"target_identity": {
"status": "resolved",
"scientific_name": "Setaria viridis",
"tree_taxon_id": "4556",
"identity_source": "explicit_taxon_id",
"config_scientific_name": "Setaria viridis",
"issue_code": ""
}
}
Conflicting explicit identity:
{
"targetScientificName": "Oryza sativa",
"ppiTargetTreeTaxonId": "39947"
}
Response summary:
{
"success": true,
"requested_ppi_species": "auto",
"selection_mode": null,
"target_identity": {
"status": "conflict",
"issue_code": "target_scientific_name_conflict",
"scientific_name": "",
"tree_taxon_id": "",
"explicit_scientific_name": "Oryza sativa",
"config_scientific_name": "Setaria viridis"
}
}
selection_mode=null is expected because Task 3 resolver/preflight wiring is
not part of this Gate. Port 9000 and port 19000 processes were not targeted or
restarted.
Online Task 2 Gate: PASS.