Skip to content

release: workflow runner v0.4.53 for CLI rc.30 - #40

Merged
Shooksie merged 14 commits into
mainfrom
release/v0.4.53-rc30
Jul 26, 2026
Merged

release: workflow runner v0.4.53 for CLI rc.30#40
Shooksie merged 14 commits into
mainfrom
release/v0.4.53-rc30

Conversation

@Shooksie

Copy link
Copy Markdown
Contributor

Aligns the workflow runner with Protocol v0.7.0-rc.12 and CLI v0.7.0-rc.30. Hardens delegated session lifecycle by invalidating dead resident-host generations without replaying exec_session, propagates actor context across prepare and exec_session with strict node-side ANIMUS_ACTOR_JSON parsing, and preserves paused sessions as resumable live checkpoints.\n\nValidation: cargo fmt, cargo check, clippy -D warnings, release build, and all-target tests (290 passed; 5 pre-existing ignored). Independent review found no blockers.

Shooksie added 14 commits July 16, 2026 15:10
…via exec_session (REQ-052)

When a workflow's resolved `environment` is a FULL standalone animus that
advertises `environment/exec_session`, hand it the ENTIRE workflow in ONE
`EnvironmentClient::exec_session` call instead of running phases locally or
routing them per-phase (REQUIREMENT-048). The node runs every phase on its own
animus and streams `environment/journal` events home; the runner forwards them
through its `WorkflowEventEmitter` and drives the run to terminal from the
session's terminal `ExecSessionResponse`.

New `src/workflow_session.rs`:
- capabilities_advertise_exec_session / environment_is_session_capable — detect a
  session-capable environment from its plugin manifest `capabilities` list.
- map_journal_event_kind / session_status_to_workflow_status — pure, unit-tested
  mappings from node journal events + terminal status to the home runtime types.
- delegate_workflow_via_session — prepare bare node, exec_session with a
  journal-forwarding closure, teardown, synthesize WorkflowExecuteInternalResult.

Branch point added in execute_workflow_with_hub before the REQUIREMENT-048
per-phase environment resolution; only full runs delegate (a `--phase` run keeps
the per-phase/local path). Non-session-capable / unset environments fall through
UNCHANGED.

Gated behind the `remote-animus-session` cargo feature (default OFF): the
parent-side exec_session / EnvironmentJournalEvent surface (orchestrator-core
REQ-052, commit bcce5012, one commit past the pinned rev d03cd174) and the
environment/exec_session protocol types (animus-environment-protocol, not in the
pinned tag v0.7.0-rc.6) are not in the current pins. With the feature off the
module is inert; the pure detection/mapping logic compiles + is unit-tested
unconditionally.

needs node/CI build+test — not built locally per policy.
…ion by default

- all animus-protocol crates v0.7.0-rc.6 -> v0.7.0-rc.8 (rc.8 = rc.6 + the
  environment/exec_session commit only — clean, minimal bump)
- orchestrator-* animus-cli rev d03cd174 -> 748f684d (env-protocol repinned to
  rc.8, local exec_session [patch] dropped)
- default = [remote-animus-session]: flip the whole-workflow exec_session
  delegation ON. Needs node/CI build+test (per ao-cli policy).
…on) ON

Validated green on GH Actions (all 3 targets). Pins: animus-protocol v0.7.0-rc.8,
orchestrator-* animus-cli rev 748f684d.
…on delegation (v0.4.47)

REQ-052 exact-once: when the parent runner delegates a whole workflow via
exec_session and it completes, delegate_workflow_via_session emitted a terminal
journal event but never drove the parent's persisted workflow state machine to
terminal. The journal_runs row stayed status=running, so the daemon's
journal-resume sweep (resumable_orphans_for_redispatch, past the 90s grace)
re-dispatched it as a resumable orphan until a re-dispatch happened to
terminalize it -- ~3 runs per dispatch instead of exactly 1.

Thread the ServiceHub into delegate_workflow_via_session and, after the session
returns, drive the parent state machine terminal best-effort: bounded
complete_current_phase_with_decision loop for Completed, mark_completed_failed
for Failed/Escalated, cancel for Cancelled. Pure state-machine transitions (no
agents/post-success); the terminal event + synthesized result are unchanged.
Whole-workflow exec_session delegation forwarded only lifecycle journal
events; the agent-run transcript (output_chunk/tool_call/...) was dropped
by map_journal_event_kind and never reached the parent log store, so the
portal showed 'No output captured for this run' for remote runs.

on_journal now mirrors transcript events into the PARENT run dir first
(before the lifecycle map), re-keying the node run id onto the parent
workflow id (rekey_transcript_run_id) so the portal's /logs groups them,
and persists via ipc::persist_run_event -> the daemon log_storage
supervisor ships them to the store the portal reads. Lifecycle stays
journal-only (reaches the parent via the upstream proxy).

Paired with animus-env-transport bridge change (streams journal/event).
Bump v0.4.47 -> v0.4.48.
…TASK-723)

Builds on the TASK-722 transcript mirror (f04306b) — combined v0.4.48.

- workflow_session passes the parent's workflow_id into exec_session so the node
  RESUMES the parent's row instead of minting its own (one journal row per
  delegated dispatch; the node's transcript lands on the id the portal reads).
- Terminal-drive Failed/Escalated now calls the guarded force_failed op (was
  mark_completed_failed, which no-ops on a still-Running row → the backstop was
  dead); Cancelled uses cancel; both log errors; dropped the racy caller-side
  get() gate (force_failed self-guards inside the store op).
- Repin protocol v0.7.0-rc.8 -> rc.9 and orchestrator-* -> animus-cli ba9b0307;
  drop the local-build [patch] block.
…t phases

commit_implementation_changes no longer bails when the working dir is not a git
repo — portal-harness / orchestration agent phases run at a non-repo project
root (/app) and edit no files, so requiring a repo there was wrong. No repo (or
no pending changes) is now a no-op, not an error. Coding phases still commit +
push via code-open-pr. Fixes "implementation phase requires a git repository for
commit at /app" that blocked all portal-local agent workflows (TASK-746).
….4.50

The runner pinned ao-cli rev ba9b0307, where environment/prepare shares the 60s
ENVIRONMENT_RPC_TIMEOUT — a Railway node (serviceCreate + image pull + deploy +
dial-home, default 300s) can NEVER prepare in 60s, so every delegated coding run
was killed mid-prepare (leaking a half-created node, or ghosting when the 60s
expired pre-create). Repin to 021a874e = ba9b0307 + cherry-picked 4b1b4cc2
(ENVIRONMENT_PREPARE_TIMEOUT=360s, REQUIREMENT-049). Diagnosed via fable+codex.
TASK-811.
…gation terminalizes (v0.4.51)

TASK-811 H1: direct_execute emitted workflow_id=None on the Err arm, so a failed
delegated run (e.g. environment/prepare failure) could not be terminalized by the
daemon and ghosted as 'Running' forever (sweep shields delegated). Thread the
resolved workflow id out of execute_workflow_with_hub via a sink set as soon as
the row is minted/loaded; the Err arm now falls back to it. The daemon can now mark
the run Failed and its stderr ('workflow execution failed: <err>') surfaces the
real prepare error. Diagnosed via fable+codex.
…s restart (v0.4.52, rc.28 reconciler companion, TASK-933)

The REQ-052 remote-animus session path (delegate_workflow_via_session) is the
production delegated-coding path: it prepares ONE node, runs the whole workflow
via environment/exec_session, and tears the node down. It persisted NOTHING
about the node, so animus-cli v0.7.0-rc.28's restart reconciler — which reaps /
reattaches a delegated node off SessionCheckpoint.environment — was inert for
coding runs: a daemon restart leaked the node (a full standalone animus keeps
running) and a re-dispatch prepared a SECOND one.

- phase_session: mirror rc.28's on-disk schema into the runner's local
  checkpoint module (its on-disk twin): EnvironmentBinding { environment_id,
  handle, bound_at, torn_down } + SessionCheckpoint.environment (serde
  default/skip, backward compatible), update_session_environment /
  mark_environment_torn_down (signature-identical to the daemon twin) +
  find_reusable_binding. JSON shape asserted byte-compatible with the released
  rc.28 reader.
- workflow_session (remote-animus session, the coding path): after prepare (or
  reuse) succeeds and BEFORE exec_session, persist the node binding as a Running
  checkpoint at the reconciler's phase (current_phase_id); after a successful
  teardown, mark torn_down; on terminal, close the checkpoint. On re-dispatch,
  probe the persisted handle's liveness (side-effect-free exec of `true`) and
  REUSE the live node (skip prepare) or prepare fresh when dead — mirroring
  rc.28's probe_delegate. Composed with v0.4.48/51's terminal-drive (does not
  duplicate it); rc.28's auto_resume already SKIPS env-bound checkpoints, so the
  synthetic Running checkpoint is never mis-resumed locally.
- Cargo: 0.4.51 -> 0.4.52. KEEPS the line's ao-cli pin 021a874e and
  animus-environment-protocol tag v0.7.0-rc.9 (EnvironmentHandle serializes
  identically to rc.6/rc.28). No pin changes.

Tests: binding round-trips with rc.28's exact fields + JSON keys; teardown
marks torn_down (idempotent, binding-gated); find_reusable_binding selects
live/matching only; the session path persists a Running checkpoint carrying the
rc.28 shape. cargo build + test (231 lib + integration, 0 failed) + clippy
clean; --no-default-features (feature-off) also builds.
…resume-companion-oneid

feat(runner): persist env-node binding + reuse/resume live node across restart (v0.4.52, rc.28 reconciler companion, TASK-933)
@Shooksie
Shooksie merged commit b479b7e into main Jul 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant