Skip to content

plan-export.ts and plan-step-readiness.ts disagree on a dangling dependsOn id #7729

Description

@JSONbored

Context

packages/loopover-engine/src/plan-export.ts and packages/loopover-engine/src/plan-step-readiness.ts both compute plan-dependency state from the same PlanDag shape, and disagree on what a dangling dependsOn id means.

  • orderByDependency (packages/loopover-engine/src/plan-export.ts:37) treats a dependsOn id that isn't present in plan.steps as already satisfied: !present.has(dep) || emitted.has(dep). This is locked in by test/unit/plan-export.test.ts:56-58 ("treats an unknown dependency id as already satisfied").
  • nextReadySteps (packages/loopover-engine/src/plan-step-readiness.ts:10) treats the identical case as never satisfied: statusById.get(dep) ?? "pending", and isDone() rejects "pending".

Neither this package nor packages/loopover-miner validates that every dependsOn id actually exists in the plan — that referential-integrity check (validatePlanDag) lives only in the app's own src/services/plan-dag.ts, outside this package, so a dangling id reaching these functions is a real, reachable case, not purely hypothetical.

The app's own canonical src/services/plan-dag.ts already resolved this exact question in the other direction: it rejects unknown deps via validatePlanDag, and its own nextReadySteps-equivalent treats them as unsatisfied — i.e. plan-step-readiness.ts already mirrors the app's real answer, and plan-export.ts is the outlier.

Requirements

  • orderByDependency in packages/loopover-engine/src/plan-export.ts must treat a dependsOn id absent from plan.steps the same way nextReadySteps does: not satisfied (i.e. remove the !present.has(dep) || short-circuit, or replace it with the equivalent "unsatisfied" branch).
  • Do not change plan-step-readiness.ts — it already has the correct semantics; this issue is about aligning plan-export.ts to match it.
  • Update the existing test in test/unit/plan-export.test.ts (currently asserting "treats an unknown dependency id as already satisfied") to assert the corrected behavior instead — don't leave the old assertion in place alongside the fix.
  • Do not add plan-validation logic to this file (rejecting dangling ids outright); that's validatePlanDag's job in the app layer and is out of scope here — this issue is only about making the two ordering/readiness functions agree on how they handle a dangling id if one reaches them.

Deliverables

  • orderByDependency (packages/loopover-engine/src/plan-export.ts) updated so a dangling dependsOn id is treated as unsatisfied, matching plan-step-readiness.ts's existing semantics.
  • test/unit/plan-export.test.ts's dangling-dependency test updated to assert the corrected behavior.
  • A new or updated test confirms orderByDependency and nextReadySteps now agree on the same dangling-dependency input (same plan, same dangling id, consistent readiness/order result from both).

Test Coverage Requirements

This package is under src/ via the packages/loopover-engine workspace — confirm this package's current coverage.include scoping before assuming the top-level 99% patch gate applies exactly as src/** does; match whatever this package's existing test file already does for its coverage target. The changed branch and the corrected assertion must both be covered — no regression in existing coverage.

Expected Outcome

orderByDependency and nextReadySteps produce consistent results for a plan containing a dependsOn id not present in plan.steps — a step with a dangling dependency is never shown as both "ready now" (via the plan-export renderer used by the MCP loopover_plan_status output) and "permanently blocked" (via resolvePlanOverallStatus/hasPlanReadySteps) for the same plan at the same time.

Links & Resources

  • packages/loopover-engine/src/plan-export.ts:25 (function start), :37 (the mismatched line)
  • packages/loopover-engine/src/plan-step-readiness.ts:8-10
  • test/unit/plan-export.test.ts:56-58
  • src/services/plan-dag.ts (the app's own canonical resolution of this question, for reference)

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions