# Task 5A validation — frontend PPI owner state and isolation Date: 2026-07-21 Target: `planai5090:/home/xzq/5090/PlantAI-dev4090-7/PlantAI-dev` Gate result: **PASS** ## Scope Task 5A changes only the frontend owner state machine and request isolation. Ortholog reuse sidecars and backend producer identity are explicitly deferred to Task 5B. No backend algorithm, Task 6 status/manifest behavior, service process, or real reference download was changed. ## TDD evidence The original focused suite reproduced the known state as `3 passed, 1 failed`. After adding owner-state requirements before implementation, the focused suite was RED with `3 passed, 6 failed`. The six failures independently covered: - explicit `confirmation_required` handling and second preflight; - PPI-owner-only selection storage; - owner fields read by the dependency request; - download completion owner writeback; - At fallback defaulting to unselected; - PPI and KaKs owner isolation. After the minimal frontend implementation: ```text tests/unit/test_ppi_owner_scheduling_task5.py 9 passed in 18.64s ``` The first frontend/task regression run produced `41 passed, 1 failed`; the failure was an obsolete assertion requiring recovered PPI reference data to be written into shared `ppiKaksReferenceSpecies`. That assertion directly contradicted the approved Task 5 isolation contract and was migrated to require PPI-owner-only fields. The bounded rerun passed: ```text tests/unit/test_ppi_frontend_display_contract.py tests/unit/test_task_status_attachment.py tests/unit/test_ppi_owner_scheduling_task5.py 42 passed in 14.31s ``` ## Verified behavior - A `confirmation_required` response displays backend candidates in their original order, including TaxID, LCA, topology distance, and STRING version. - Confirmation writes only `ppiReferenceTaxonId`, `ppiReferenceStorageKey`, `ppiReferenceSelectionMode`, `ppiReferenceUserConfirmed`, and `dependencyOwner="ppi"`, then performs a second preflight. - Cancellation pauses PPI without submitting Ortholog or PPI. - Batch, plan, PPI stage, and request owner fields are synchronized without adding the PPI selection to shared `referenceSpecies`, `refSpeciesList`, `ppiKaksReferenceSpecies`, or scope mode. - PPI and KaKs build separate owner requests. KaKs receives no PPI owner TaxID or storage key. - Synchronous and asynchronous reference-download completion reapply the PPI owner selection. Shared reference merging remains only inside the explicit KaKs branch. - The Arabidopsis model fallback defaults to `skip`; `model_fallback` owner state is written only after an explicit `ath` decision. - Selecting a generic project reference is rejected for PPI instead of leaking it into the PPI owner. ## Deferred to Task 5B - PPI-owned Ortholog storage-key consumption in the backend producer. - Ortholog run sidecar with reference TaxID, reference PEP SHA256, target/member identity, mapping identity, and mapping path. - Strict final/intermediate mapping reuse by exact identity. No service restart or real download was performed. ## P0 review revision The first Task 5A review requested three additional behavior-level gates. Three Node-backed tests were added before implementation; all three were RED because the pure final-request and post-download orchestration helpers did not yet exist. The dynamic tests execute helper source extracted from the shipped `index.html`, rather than only checking for source strings: 1. A final PPI request retains all five owner fields, removes legacy technical reference fields, and preserves a legitimate project analysis scope. 2. A simulated PPI + KaKs batch proves the PPI request cannot see `KaKsRef`. 3. A simulated post-download/post-fallback preflight returning `needs_ortholog` records the call order `ortholog`, then `resume`. Incremental GREEN evidence: ```text final PPI request + joint owner isolation: 2 passed post-reference orchestration: 1 passed full Task 5A focused suite: 12 passed in 13.53s ``` The final bounded frontend/task regression passed: ```text tests/unit/test_ppi_frontend_display_contract.py tests/unit/test_task_status_attachment.py tests/unit/test_ppi_owner_scheduling_task5.py 45 passed in 16.56s ``` The final request path now applies PPI owner fields after gene-family context construction. PPI no longer participates in the legacy technical-reference override used by Ortholog and KaKs. This preserves legitimate project `referenceSpecies`, `refSpeciesList`, and scope identity while preventing `ppiKaksReferenceSpecies`, `ppiReferenceSpecies`, and `referenceBundleSpecies` from entering the PPI request. Both synchronous and asynchronous download completion, and the explicitly confirmed At fallback, now re-enter PPI owner preflight orchestration. A `needs_ortholog` result must successfully insert or reuse the Ortholog producer before paused PPI work is resumed.