Skip to content

No way to re-run a completed run from a given station (conduit reenter) #60

Description

@queso

Problem

There is no supported way to re-run part of a completed run. The case: a run reaches done, and an operator needs to regenerate one downstream artifact, plus everything after it, without re-running upstream stations that were already approved. For example, re-run an image generation station against an approved brief because the image was rejected outside the flow, or because a prompt change should apply to that stage only.

Four mechanisms treat a completed card as final:

  1. The FSM has no transition out of a terminal state. INTEGRITY_PASS on the last station produces { lane: 'done', status: 'complete' } (src/statemachine/transitions.ts:142), and no event is legal from there. This is a deliberate invariant.
  2. Resume never selects a terminal run or card. Run selection excludes finished runs, WHERE status NOT IN ('done', 'complete', 'terminal', 'scrapped') (src/cli/main.ts:1371). The promote step only re-readies waiting and interrupted cards in non-terminal lanes (src/controller/executor.ts:698).
  3. Checkpoints would return stale outputs. A naive re-run from a station would find the downstream transform and gate checkpoints intact and skip them, reusing exactly the artifacts meant to be regenerated.
  4. Effectful stations would fire twice. The outbox key is ${flow.version}:${cardId}:${stationId}:${card.attempt} (src/controller/executor.ts:2099). Re-entry must advance attempt so that a re-fire is a new intent rather than a pending one that reconcileOnResume escalates to hold.

Proposed mechanism

A separate verb, so that an ordinary resume never takes the terminal path:

conduit reenter <flow.yaml> --run <id> --from <station> [--card <id>]

Within the run lease:

  1. Find the target cards: the run's done cards by default, or the one named by --card. Fail if the run is not terminal or --from is not a station on the card's path.
  2. Reject a fan-out parent or child-lane entry point in v1.
  3. Add one FSM event, REENTER { station }, legal only from a terminal complete state. It produces { lane: station, status: 'waiting', attempt: attempt + 1 } and leaves reworkCount unchanged.
  4. Invalidate checkpoints from --from to the end of the path. Stations before --from keep theirs.
  5. Set the runs row back to running and drive the engine as resume does.
  6. Write a journal entry for the re-entry (from which station, and when), separate from an ordinary attempt increment.

Open questions

  • Should invalidation cover --from to the end of the flow (safe, but those stations are billed again) or an explicit range?
  • Should re-entry across an effectful: true station be refused unless a flag such as --allow-effectful-refire is passed? The recommendation is to refuse by default.
  • Is single-lane re-entry enough for v1?

Acceptance criteria

  • A test for re-entering at a mid-flow station: stations before it are skipped from checkpoint, stations after it re-execute, and the run ends done with the attempt advanced.
  • Re-entry across an effectful station without the opt-in flag is refused.
  • A test that verifies an effectful re-fire gets a new outbox key.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowUseful improvement that is not an immediate correctness risk

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions