Source-bound skill workflows
Experimental (alpha). This local workflow profile has limited testing and its CLI, schema and storage may change without migration. It runs against an existing native AgentSCM data directory owned by the local operator.
A skill workflow binds a small directed graph of checks to one immutable native source revision
and one packaged SKILL.md. The package may include explicitly named resources below the skill
directory. AgentSCM preserves those bytes and includes their identity in the compiled plan; it
does not interpret the skill prose as authority, shell text or a successful check result.
The profile implements source_paths and, on Unix, command. source_paths reads exact files
from the selected native revision and compares their bytes with declared lowercase SHA-256
digests. This establishes source identity for those paths. It does not execute the source or
demonstrate application behavior.
A command action names a strict CommandRecipe JSON resource packaged beside SKILL.md. The
compiler loads that exact resource from the immutable revision and requires a real, existing,
current Change and command/v1 ReviewContext that bind the same revision, policy epoch, recipe,
toolchain and environment. The runtime creates a deterministic durable command attempt and sends
it through the existing isolated OCI collector. It does not derive a command from skill prose,
install packages, run npx, fetch an image, expose model-provider keys or enable network egress.
require_capability records an operation the profile cannot perform. A required unavailable
capability blocks the run. An optional unavailable capability remains visible as an omission and
does not become a success; after all required work succeeds, the run reports
completed_with_omissions.
What this is useful for
Use a workflow when a checkpoint needs the same ordered set of checks each time. The definition names the exact revision, packaged resources and dependencies. The runner records what finished, what failed and what was unavailable, so a restart does not turn an unknown command result into a new execution or a success claim.
An operator or an agent acting through the local CLI starts it explicitly:
flowchart LR A[Explicit local CLI call] --> B[Compile source and skill package] B --> C[Run ordered check or command steps] C --> D[Retain run and command results] D --> E[CLI, API, MCP and dashboard inspection]SKILL.md describes the skill; it is packaged input. A command step also needs the strict recipe
and actual review-context binding described below. Arbitrary skill prose is not an instruction to
launch an agent, install a package or execute a shell command.
Agent hooks, execution and admission
The existing file-edit hooks coordinate contention and remain warn-once/fail-open. The optional Claude Code Stop loop separately checkpoints source, runs isolated tests and bounded review, returns failure feedback, and records a current completion receipt. The MCP workflow tool reads status; it does not start, resume or cancel a run. The bundled example skill still covers source-path checks only.
Individual command evidence satisfies a requesting command context. An operator-installed
native target workflow requirement additionally requires every required step to pass, including
review, before approval or landing. This is checked in the authority transaction. A standalone
run remains an observation with admission: "not_assessed"; it is never an approval itself.
Catalog installation, other agent adapters and authenticated remote execution controls remain
planned. The native gate does not protect arbitrary Git or forge merge operations.
Definition
Definitions are strict JSON: unknown fields are rejected. The repository ID comes from the
read-only native authority in --data-dir; the revision, policy epoch, skill paths, dependency
graph and source expectations must all validate before a plan is produced.
{ "version": 1, "name": "verify-native-source", "source": { "repository": "0123456789abcdef0123456789abcdef", "revision": "0000000000000000000000000000000000000000000000000000000000000000", "policy_epoch": 0 }, "skill": { "entrypoint": "skills/native-workflow/SKILL.md", "resources": [] }, "steps": [ { "id": "verify-guide", "needs": [], "required": true, "action": { "kind": "source_paths", "expectations": [ { "path": "docs/advanced/skill-workflows.md", "sha256": "0000000000000000000000000000000000000000000000000000000000000000" } ] } } ]}The entrypoint must end in the exact filename SKILL.md. Resource paths must be regular files
within its parent directory. The entrypoint is included automatically. AgentSCM reads every
declared skill file from the immutable revision, so it does not follow host filesystem paths.
For a command step, declare the recipe using its full native source path in skill.resources,
then use its path relative to the skill directory as action.runner. For example, a package with
skills/native-workflow/SKILL.md and a runner recipe file skills/native-workflow/runner.json (an example
path; this repository ships only SKILL.md) uses:
{ "skill": { "entrypoint": "skills/native-workflow/SKILL.md", "resources": ["skills/native-workflow/runner.json"] }, "steps": [ { "id": "run-command", "needs": [], "required": true, "action": { "kind": "command", "runner": "runner.json", "change": { "repository": "0123456789abcdef0123456789abcdef", "id": "change-1" }, "change_version": 1, "context_digest": "0000000000000000000000000000000000000000000000000000000000000000" } } ]}Those skill and steps members belong inside the complete definition shown above. Replace all
placeholder identities with the current values from the same native data directory. Prepare the
strict recipe and ReviewContext as described in isolated command execution and
review contexts. One ReviewContext has one recipe binding; a workflow that
needs a different command recipe needs a separately bound current context.
Workflows contain 1 to 32 steps. Each step may name at most 32 dependencies, and a
source_paths action contains 1 to 32 expectations with an 8 MiB aggregate file-content limit and a separate 16 MiB encoded-object read ceiling. Step and
workflow identifiers are bounded canonical ASCII. Dependencies must exist, be unique and form an
acyclic graph. The compiler uses a stable topological order.
Local CLI
Use the same existing native data directory that contains the source revision and authority:
agentscm --data-dir ./agentscm-data skill-workflow plan workflow.jsonagentscm --data-dir ./agentscm-data skill-workflow run local-run-1 workflow.jsonagentscm --data-dir ./agentscm-data skill-workflow status local-run-1agentscm --data-dir ./agentscm-data skill-workflow resume local-run-1 --max-steps 1agentscm --data-dir ./agentscm-data skill-workflow cancel local-run-1plan validates the definition and reports its plan and skill identities without running steps.
run starts or reopens the named run and advances it by at most 32 steps. resume revalidates the
stored definition, native repository, revision, current policy epoch and packaged skill bytes
before continuing. A changed binding stops continuation; historical observations remain recorded.
Run IDs are idempotency keys. Reusing an ID with the same plan returns retained state. Reusing it for a different plan is a conflict. Each completed step is persisted, so reopening the local data directory preserves progress. Cancellation is terminal and leaves recorded observations intact.
Source-only workflows use the commands above unchanged. A workflow that can reach a command
step requires both trusted runtime flags on run and resume:
agentscm --data-dir ./agentscm-data skill-workflow run local-run-1 workflow.json \ --docker /usr/local/bin/docker --docker-socket /var/run/docker.sockagentscm --data-dir ./agentscm-data skill-workflow resume local-run-1 --max-steps 1 \ --docker /usr/local/bin/docker --docker-socket /var/run/docker.sockThe flags are accepted only as a pair. Command execution is unavailable on non-Unix platforms;
source-only workflows remain portable. SIGINT and SIGTERM request collector cancellation and
cleanup. A process crash can still leave a running durable attempt. status exposes the command
attempt ID, generation, state, outcome and record digest under the step’s execution member;
inspect its full record with the existing command-check CLI:
agentscm --data-dir ./agentscm-data check-command-show ATTEMPT_IDagentscm --data-dir ./agentscm-data skill-workflow cancel local-run-1 \ --docker /usr/local/bin/docker --docker-socket /var/run/docker.sockagentscm --data-dir ./agentscm-data skill-workflow recover local-run-1 run-command \ --docker /usr/local/bin/docker --docker-socket /var/run/docker.sockUse recover only for an interrupted command step; its backend flags are required. Recovery
reconciles the retained container custody before finalizing the attempt and does not rerun the
command. While a command runs, other controllers can inspect its status. Cancellation and recovery
hold the workflow journal lease while reconciling container cleanup; concurrent journal operations
may return workflow journal is active during that bounded operation. Cancellation can omit the flags only when no command attempt is running. All command limits, isolation checks, cancellation behavior and recovery uncertainty are
the same as the underlying command/v1 collector.
The JSON status includes admission: "not_assessed". A successful workflow means only that its
implemented steps reached their declared success conditions. It does not approve, integrate,
merge, deploy or authorize the revision. The local owner, controller and Docker daemon remain
trusted. The optional required-target loop revalidates the graph and copies an exact-subject
receipt into native authority; read-only hub projections do not grant authority.
The compiler rejects more than 63 explicitly selected resources before source access; the automatic
SKILL.md makes 64 package entries. Relative package paths are limited to 512 bytes.
A partial resume --max-steps N may exit successfully while the JSON state is still running.
Inspect the state rather than treating process exit as workflow completion. A status read can
conflict with an active journal writer; retry after that operation finishes.
Local journal consistency checks bind retained definitions, ordered steps and observations. They detect inconsistent records under the trusted local-owner model; they do not authenticate a producer or prevent an owner from replacing coherent state. Recovery can finalize already-recorded terminal steps after a policy change without rerunning source checks. Unfinished work still requires the current source and policy bindings.
The native service exposes a read-only run projection with historical state separate from present source applicability.
For authenticated team access, configure the hub/MCP read mapping and use the dashboard run lookup. Execution and recovery remain local CLI operations.
Read-only access makes no workflow-row, execution, approval or integration changes and does not initialize an absent journal or native store. SQLite may create or update WAL/SHM sidecars for existing databases, including the native authority. Reads can fail if required sidecar housekeeping is unavailable. This is logical read-only access, rather than a zero-filesystem-write guarantee.
Library callers using advance(..., 0) execute no new steps, but may reconcile an already
recorded all-terminal run outcome. The CLI accepts step budgets from 1 to 32.
What the tests establish
The workflow tests and command workflow tests cover source and recipe binding, graph dependencies, retained progress, failure propagation, context and policy drift, concurrent-controller cancellation, lost-result recovery without replay, unknown cleanup and CLI signal handling. Ordinary command cases use a fake Docker transport.
The opt-in live_runtime_executes_the_exact_native_revision test executes a fixed command through
the real container collector and verifies the native source bytes it sees. It needs an explicitly
selected Docker executable, socket and pre-acquired immutable image. The existing
execution qualification covers the collector’s tested isolation and
cleanup controls for its selected runtime.
The Claude Code loop adds targeted failure/fix and native admission tests. Fixture protocols alone do not qualify a live model or hostile execution. Catalog installation, other agent adapters and deployment are not qualified by this profile.