Files
PlantAI-dev/.planning/ppi-kaks-temporary-frontend-circuit-breaker/PLAN.md
T

16 KiB

Plan: Temporarily pause PPI/KaKs without blocking other analyses

Locked via user decisions on 2026-08-05; implementation is not authorized by this plan alone.

Goal

Keep ppi and kaks visible in every generated plan while both features are under revision, but make the web UI treat them as globally and explicitly paused. The UI must not run PPI/KaKs reference-species preflight, show reference-download dialogs, submit reference-download requests, or submit PPI/KaKs execution requests. Other planned stages and their confirmation dialogs must continue normally. Backend APIs, CLI programs, stage contracts, manifests, and biological methods remain unchanged so developers can still exercise those paths directly.

Acceptance criteria

  1. Plans returned by the backend still contain ppi and kaks; no PlanningAgent pruning is introduced.
  2. Before dependency preflight, the batch UI records every planned ppi/kaks stage as paused with the user-visible reason 功能修订中,本次自动跳过.
  3. With the temporary circuit breaker enabled, the UI does not call /api/ppi/species-resolution or /api/reference-bundle/download for those paused owners.
  4. The UI never calls /api/execute with stage equal to ppi or kaks through normal batch or manual UI flows.
  5. A PPI/KaKs-owned auto-inserted ortholog stage is paused only when its parameters identify that ownership via autoInsertedFor, dependencyOwner, or a PPI/KaKs dependency referencePolicySource. An independently requested, unowned ortholog stage remains runnable.
  6. Non-PPI/KaKs stages continue through the existing confirmation queue and dependency scheduler after the paused stages are recorded.
  7. Paused stages are reported as paused, not failed or completed, and no success Manifest is generated for them.
  8. Turning off or removing the single temporary circuit-breaker declaration restores the existing PPI/KaKs preflight behavior without backend or contract migration.
  9. Foreground batches, background batches, manual confirmation, stale open dialogs, and shared submit paths enforce the same pause behavior; none can bypass the circuit breaker or misreport a pause as failure.

Root cause

startBatchExecute() currently awaits ensureOrthologProducerForPpiKaks() before it initializes and runs the ordinary stage scheduler. ensureOrthologProducerForPpiKaks() stops on the first owner for which ensurePpiKaksDependencyOwner() returns false. startBatchExecute() then returns before executeStagesWithDependencies(), so a PPI/KaKs dependency problem prevents every later confirmation dialog and otherwise independent analysis.

The observed job log contains repeated successful HTTP calls to /api/ppi/species-resolution but no /api/reference-bundle/download call for the failing attempt. That localizes the blocking behavior to frontend dependency/preflight control flow rather than an executed NCBI bundle download.

CodeGraph and source findings

  • .codegraph/ exists, so codegraph explore was attempted first for the PPI/KaKs dialog and scheduling call path. It returned no usable output; targeted source reads were therefore used.
  • apps/web/vue3/index.html:14058 — runPpiSpeciesResolutionPreflight() owns the species-resolution request and blocking alerts.
  • apps/web/vue3/index.html:14354 — ensurePpiKaksDependencyOwner() owns per-owner reference decisions and download behavior.
  • apps/web/vue3/index.html:14491 — ensureOrthologProducerForPpiKaks() globally gates the batch.
  • apps/web/vue3/index.html:14980 — startBatchExecute() returns early when that gate is false.
  • apps/web/vue3/index.html:15037 — stored pause states are applied before dependency execution.
  • apps/web/vue3/index.html:15600-15900 — the shared stage confirmation queue and confirmation handlers control subsequent dialogs.
  • apps/web/vue3/index.html:12881 and apps/web/vue3/index.html:18927 — manual confirmation and execution entry points must be guarded before scope loading, timers, or submission.
  • apps/web/vue3/index.html:21789-21882 — background batch execution is a separate scheduling path and must preserve paused rather than converting the circuit breaker into failed.
  • apps/web/vue3/index.html:13713 — an already-running legacy reference-download monitor can otherwise resume temporarily disabled owners.
  • Auto-inserted Ortholog ownership is already recorded with autoInsertedFor, dependencyOwner, and referencePolicySource near apps/web/vue3/index.html:14243-14339.
  • PlanningAgent dependency expansion can add the formal KaKs Ortholog without those frontend-only owner fields. The plan response exposes the original intent stages near apps/web/vue3/main.py:22079-22089, but the current frontend plan handoff near apps/web/vue3/index.html:22617-22625 does not preserve them. The frontend must retain that evidence to distinguish an explicit independent Ortholog from a KaKs-only dependency.

Allowed existing APIs and patterns

  • Use the existing Vue reactive stage state: stageExecutionStatus, stagePauseReasons, recordStagePause(), and the batch pause summary.
  • Use existing stage identity helper getStageId() and existing stage parameter objects; do not invent backend request fields.
  • Follow the existing test pattern that extracts real JavaScript source blocks and executes them with Node in tests/unit/test_ppi_owner_scheduling_task5.py.
  • Keep /api/ppi/species-resolution, /api/reference-bundle/download, /api/execute, CLI entry points, and Manifest schemas unchanged.

Approach

Phase 1 — RED: executable regression tests

Modify only frontend scheduling tests first.

  1. Add a behavior-level test for a small circuit-breaker helper extracted from the real HTML source. Given a plan containing ordinary stages, ppi, kaks, a PPI-owned Ortholog, and an independent Ortholog, assert that only ppi, kaks, and the owned Ortholog are selected for temporary pause.
    • Cover PPI-owned, KaKs-owned, jointly owned, unrelated-auto, explicit-independent, and unknown-source Ortholog examples.
    • Preserve the stage list itself; only statuses change.
  2. Add a batch-start control-flow test or source-extracted harness proving that, while disabled, the existing ensureOrthologProducerForPpiKaks() callback is not invoked and scheduling proceeds.
  3. Add a manual-confirmation guard test proving that PPI/KaKs resolve as paused and do not reach the execute-submit callback.
  4. Add a shared-submit guard test covering stale open dialogs or alternate callers.
  5. Add a background-batch test proving the owners and owned Ortholog remain paused rather than failed while unrelated background stages continue.
  6. Add a stale-monitor test proving resumePpiKaksPausedStages() cannot restore disabled owners to pending.
  7. Add negative assertions that the disabled branch does not invoke species-resolution, reference-bundle download, or PPI/KaKs /api/execute submission.
  8. Run the focused tests and confirm they fail because the circuit-breaker behavior does not exist yet.

Documentation references:

  • tests/unit/test_ppi_owner_scheduling_task5.py — _source_block() and Node execution pattern.
  • tests/unit/test_ppi_frontend_display_contract.py — frontend contract assertions.

Anti-pattern guards:

  • Do not add tests that only assert a constant string exists.
  • Do not mock the helper under test.
  • Do not weaken existing PPI owner-isolation tests.

Phase 2 — GREEN: one frontend circuit breaker

Modify apps/web/vue3/index.html only.

  1. Add one plainly named temporary feature declaration near batch execution state, for example const PPI_KAKS_TEMPORARILY_DISABLED = true, with a removal condition comment rather than a configurable framework.
  2. Add one pure ownership predicate for an Ortholog stage. Its canonical condition is that autoInsertedFor contains ppi or kaks; dependencyOwner and the two existing PPI/KaKs referencePolicySource values may be accepted only as compatibility evidence for already-built stage objects. Never infer ownership merely because an Ortholog is present in the same batch.
    • When the plan contains an untagged Ortholog added by dependency expansion, compare it with the preserved original intent stages: explicit ortholog intent means independent; absent ortholog intent combined with requested kaks means KaKs-owned.
    • If intent provenance is absent or ambiguous, preserve Ortholog rather than guessing.
  3. Add one helper that records the temporary pause reason for planned PPI/KaKs and owned Ortholog stages. It must not reuse ppiKaksPauseStageIds() because that helper currently adds any planned Ortholog and would violate independent-Ortholog preservation.
  4. In startBatchExecute(), branch once:
    • disabled: record the temporary pause set and continue;
    • enabled: execute the existing ensureOrthologProducerForPpiKaks() path unchanged.
  5. Preserve the existing status initialization and applyStoredPpiKaksPauseStatuses() flow, or introduce a narrowly named equivalent if the existing pause object cannot express precise stage IDs.
  6. Add an early guard in showConfirm() before scope loading, dialog display, and the automatic countdown. Add a second guard at the start of doExecute() for a stale dialog opened before deployment/page-state refresh.
  7. Add a final shared-submit guard before PPI/KaKs preflight and /api/execute. It is defense in depth for alternate callers, but its result must be interpreted as paused, never as a failed stage.
  8. Apply the same pause selection to startBackgroundBatchExecution() so background execution excludes disabled owners and owned Ortholog, continues unrelated stages, and reports paused counts.
  9. Prevent resumePpiKaksPausedStages() from changing temporarily disabled owners back to pending when an older reference-download monitor completes.
  10. Do not change backend stage availability or returned plans.
  11. At the frontend plan handoff, preserve the existing plan API's original intent stage list in batch state solely as ownership provenance; do not change the plan API schema or PlanningAgent.

Anti-pattern guards:

  • No edits to gfa_core/mas/agents/planning_v2.py, apps/web/pipeline_backend.py, apps/web/vue3/main.py, CLI scripts, contracts, or Manifest writers.
  • No job-ID special case.
  • No broad ortholog pause by stage name alone.
  • No fake completed state, empty success Manifest, or swallowed failure reported as success.
  • No path that represents the temporary circuit breaker as an exception and then maps it to failed.
  • No refactor of the large Vue file beyond the helpers required for this behavior.

Phase 3 — GREEN verification and focused regression

  1. Run the new focused tests.
  2. Run all existing PPI frontend/owner tests.
  3. Run the repository's HTML/JavaScript validation command used for apps/web/vue3/index.html.
  4. Inspect the diff and verify every production change maps to an acceptance criterion.

Expected focused commands:

/home/xia-lab/miniconda3/envs/test4py311/bin/python -m pytest -q \
  tests/unit/test_ppi_owner_scheduling_task5.py \
  tests/unit/test_ppi_frontend_display_contract.py
/usr/bin/node --version
python validate_js.py

If the test environment provides a narrower JS validator command, use the repository-documented command rather than inventing one.

Known baseline note: the audit observed test_ppi_frontend_display_contract.py at 17 passed / 1 unrelated existing failure in the openPpiResetDialog() string contract. Record the exact fresh baseline before RED, and do not attribute that failure to this revision or weaken it to obtain green.

Phase 4 — real UI/API validation

Use a non-destructive test job or a justified copied/subset job; do not mutate the user's completed scientific artifacts.

  1. Request a plan containing ppi, kaks, and at least one unrelated stage; verify the plan still displays all stages.
  2. Start the batch in the UI.
  3. Verify PPI and KaKs immediately show paused with the exact temporary reason.
  4. Verify no reference-species confirmation/download modal appears.
  5. Verify the next unrelated stage confirmation appears and can be submitted.
  6. Verify browser/network and server logs contain no new /api/ppi/species-resolution, /api/reference-bundle/download, or /api/execute PPI/KaKs request for this run.
  7. Verify no new PPI/KaKs success Manifest exists.
  8. Verify an explicitly requested independent Ortholog is not paused; separately verify an owned auto-inserted Ortholog is paused.
  9. Exercise the background-batch path and verify disabled stages remain paused while an unrelated background stage proceeds.
  10. Simulate completion of a pre-existing reference-download monitor and verify it cannot resume disabled owners.

This is workflow validation, not a biological full-data validation, because no PPI/KaKs method or output is being changed.

Affected layers and synchronization

Layer Change
Frontend scheduling Temporary availability declaration, precise pause selection, batch gate bypass, manual UI guard
Frontend status/result summary Reuse paused status and pause reason; ensure it is not counted as failed/completed
Frontend tests Add behavior-level red/green regression coverage
PlanningAgentV2 No change; stages remain visible
Backend/API No change
CLI/skills No change
Stage contracts and identity No change
Manifest/reproducibility No change; paused stages produce no success Manifest
Diagnosis No backend diagnostic change; the UI pause reason is explicit

Biological-method assumptions and fallbacks

  • This circuit breaker makes no biological claim and does not alter PPI, Ka/Ks, STRING species selection, Ortholog mapping, or reference bundle methodology.
  • No fallback species is selected automatically.
  • Existing backend/CLI paths remain available only for deliberate development use.

Risks and mitigations

  1. Owned Ortholog is not tagged in an older plan. Preserve it rather than guessing. It may run independently, but an explicit stage must not be silently disabled. Add logging/diagnostic text if encountered.
  2. A later UI path submits directly to /api/execute. Search all in-file submission paths for PPI/KaKs and cover the shared submission boundary with a regression test.
  3. Pause state is overwritten during batch initialization. Verify the pause is stored before initialization and re-applied after stage statuses are initialized.
  4. Background execution maps the guard to failure. Apply pause filtering before its execute/catch path and assert paused accounting explicitly.
  5. Background download monitor survives from an earlier attempt. This change prevents new monitors and prevents their callbacks from resuming disabled owners; it does not cancel an already submitted external task. Document that existing tasks are unaffected.
  6. Temporary flag becomes permanent. Use one declaration and a clear removal condition; do not distribute hard-coded booleans.

Out of scope

  • Repairing PPI, Ka/Ks, Ortholog, STRING selection, or NCBI downloads.
  • Changing dependency graphs or PlanningAgent output.
  • Cancelling already running reference-bundle tasks.
  • Backfilling or rewriting existing manifests.
  • Changing API/CLI access for developers.

Implementation handoff checklist

  • User explicitly authorizes implementation after reviewing this plan.
  • Focused regression tests are written and observed failing before production edits.
  • Only apps/web/vue3/index.html and focused frontend test files are changed.
  • Independent Ortholog preservation is covered by an executable test.
  • Focused tests pass and existing PPI frontend tests introduce no new failures; any pre-existing baseline failure is reported separately.
  • JavaScript validation passes.
  • UI/network/log validation confirms unrelated analysis continues.
  • Service restart requirement is reported; Celery restart should not be required for a frontend-only change unless deployment packaging dictates otherwise.