These maintained, hand-authored declarations are the canonical starting points:
agent-claude.kdluses Claude Code's rules loader and nativeSessionStart,PreCompact, andStopFailurehooks.agent-codex.kdlcomposes the persona and bus contract intoAGENTS.mdand uses Codex's nativeSessionStart,PreCompact, andStophooks.
The examples use <host>, <identity>, and <workspace> placeholders. st2 provides CATALOG,
ST_ROOT, PTY_ROOT, and ST_HOOKS when it starts a task, so hook declarations contain no
machine-specific install paths. Copy the appropriate file into
<catalog>/agents/<host>/<identity>/agent.kdl, replace every placeholder, and add the referenced
catalog-owned templates. role is optional metadata; supervisor is optional runtime routing.
Uncomment them when the agent has an assigned role or reports to another bus identity. In the Codex
declaration, workspace trust is absent by default. The experimental generator adds an argv-local
Codex project trust override only with compile-agent --harness codex --trust-workspace. It preserves
the exact decoded workspace bytes as the key. st2 treats that argv as opaque; the trust flag is not
part of generic catalog validation.
compile-agent is an experimental generation aid. It writes one declaration, catalog-owned
templates, and the agent's resources/{inbox,archive,context,links} directories without changing
the workspace. Inspect all generated KDL and workspace targets before use.
Use this sequence for hand-authored or generated declarations:
st2 hooks install
st2 hooks verify
st2 validate <catalog>
st2 up <catalog> --host <host> --materialize-only
st2 up <catalog> --host <host> --onceHook installation is explicit and receipt-bearing. up and materialization only verify the
selected immutable hook set; they never refresh shared scripts. Managed settings resolve
$ST_HOOKS/<script> into that versioned set.
Both maintained declarations load the shipped bus contract. Agents must declare busy before
actively executing a unit of work and return to available only when yielding or ready for new
work. Busy agents still receive DING. dnd is the only delivery hold and the sidecar does not renew
it, so an abandoned hold becomes stale after 15 minutes. st2 intentionally does not inspect either
harness's terminal pixels.
The render { ... } block is ordered. copy, file, json-upsert, and ensure-line are
boot-gating operations; a failure prevents that agent from starting. Materialization refuses any
real change to a Git-tracked target before its first workspace write. A byte-identical tracked
target is safe and idempotent; untracked and non-Git targets remain writable. git-exclude is
advisory, so a non-Git workspace or exclusion failure does not prevent a boot.
Tracked-target detection invokes git and fails closed if it cannot inspect a workspace that appears
to belong to a Git worktree.
Materialization is idempotent. JSON values are deep-merged, existing unrelated
settings survive, loader lines are added once, and generated workspace files
are excluded without changing the repository's committed .gitignore.