Skip to content

Expose desired versus observed launch generation for adopted tasks #40

Description

@schickling-assistant

A running task is adopted solely because its stable task ID is alive. If its
Agent Spec changes under that same ID, the catalog can describe generation g2
while the process is still executing g1. No machine-readable surface exposes
that disagreement.

This behavior is deterministic on current main.

Minimal reproduction

https://github.com/schickling-repros/2026-07-st2-dynamic-agent-spec-lifecycle

git clone https://github.com/schickling-repros/2026-07-st2-dynamic-agent-spec-lifecycle
cd 2026-07-st2-dynamic-agent-spec-lifecycle
./repro.sh

The second half:

  1. publishes a synthetic worker whose command writes g1 and sleeps;
  2. runs one reconciliation pass and observes g1;
  3. replaces agent.kdl with the same identity/task ID but a command that writes
    g2;
  4. runs another reconciliation pass.

The second pass reports:

adopted (1): worker

and the running process still reports:

Before declaration update: running generation = g1
After declaration update:  running generation = g1

Why this matters

Adoption is the right default for st2's nomadic control-plane contract: replacing
or restarting st2 up must not destroy a long-lived interactive session.

The missing distinction is between:

  • adopting a task which realizes the current launch definition; and
  • adopting an older task merely because its stable ID matches.

An external Agent Spec publisher cannot honestly report running or ready
after publishing new bytes. The same ambiguity affects hand-edited declarations:
command, cwd, environment, or rendered harness inputs may say one thing while
the live process remains on another.

Automatic restart on every KDL change would be worse: comments, metadata, and
non-launch-affecting changes should not destroy interactive work.

Expected

st2 should expose desired-versus-observed launch-definition identity. A live
task with an older effective launch definition should be observable as drift,
not silently indistinguishable from convergence.

Possible directions

A. st2-computed task generation (preferred long-term)

Compute a fingerprint over the lowered spawn-affecting task contract, persist it
in PTY/exec runtime metadata, and expose per-task desired/observed generations.

Values would include task kind/ID, command, cwd, effective environment, and
other spawn-affecting fields. Declaration-only comments or inert metadata would
not change the task generation.

Reconciliation remains nondestructive by default:

same task ID + same task generation      -> adopt
same task ID + different task generation -> report drift

Replacement should be a later explicit operation, not an automatic consequence
of observation.

B. Publisher-authored opaque rollout revision

Allow an opaque declaration/task revision to be persisted and compared by st2.
This is smaller, but makes correctness depend on every renderer choosing the
right hash scope.

C. Exact declaration-byte digest only

Useful for CAS and audit, but insufficient by itself: comments and inert metadata
would appear to require a new process even though the spawn contract is
unchanged.

A machine-readable agent inspect/agents --json result should eventually
include the desired and observed identities plus an honest state such as
converged, drifted, or unknown.

Related

Version

  • st2 0.1.0+a77776a
  • source a77776ac553af9b9b04149f2bc9f6c269a008b83
  • Linux
Posted on behalf of @schickling
field value
agent_name co2-pine
agent_session_id cdd15622-c01a-4731-bbfe-ab8cce0cad54
agent_tool Codex CLI
agent_tool_version 0.145.0
agent_runtime Codex CLI 0.145.0
agent_model unknown
runtime_profile /nix/store/ph8rlhdj25mg71v81jsfzy6dq4xpcs9m-coding-agent-runtime-profile/share/coding-agents/profile.json
skills_manifest /nix/store/lsykz8x5481xrpbgk280xh3pypk1c5jy-agent-skills-corpus/share/agent-skills/manifest.json
worktree tmp
machine dev3
tooling_profile dotfiles@3649b53

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions