Skip to main content
Browse the documentation

Autonomous runs

Running a goal to completion

Describe what "done" means in a TOML file and let the agent work at it without you — with budgets that stop it.

Interactive mode is a conversation. Autonomy is different: you write down what success looks like, hand it over, and come back to a result.

snaga --autonomy goal.toml

Writing a goal

A goal file has three parts: what you want, what "done" means, and how much it may spend getting there.

id = "blink-firmware"
description = """
Write a Rust firmware for a Raspberry Pi that blinks GPIO17 every
500 ms, runs as a systemd service, and reports heartbeat over
MQTT. Must compile with the stable toolchain.
"""

[budget]
max_rounds = 80
max_minutes = 45

[[success_criteria]]
kind = "shell_exit_zero"
cmd = "cargo build --release"

[[success_criteria]]
kind = "file_exists"
path = "target/release/blink"
min_bytes = 50000

TOML rather than YAML, deliberately: mixed indentation breaks subtly when a model edits it, and this is a file a model will edit.

What "done" can mean

kindPasses when
shell_exit_zeroa command exits 0
file_existsa file exists, optionally above min_bytes
tests_passthe test suite passes
http_okan endpoint answers
telemetry_reportsa value appears on a topic within a window

Write these as tightly as you can. They are the only thing standing between "the agent decided it was finished" and "the thing works". A criterion of shell_exit_zero on cargo build says the code compiles and nothing about whether it does the job — pair it with a test.

Budgets

max_rounds and max_minutes bound the run. They are not a suggestion: the executor stops there, whether or not the goal is met.

There is also a loop guard. A run that keeps hitting the same unresolvable obstacle is detected and stopped, rather than burning the whole budget rediscovering it.

Profiles

snaga --profile robotics --autonomy goal.toml

Stock profiles: robotics, drone, server-ops, space, auto. A profile presets the behaviour for a domain. For your own, use custom:<path>.

Resuming

A run persists under .snaga/autonomy/<goal-id>/, so a crash or an interrupt is not the end of it:

snaga autonomy list                  # runs, with their progress
snaga --autonomy-resume <goal-id>    # continue one

autonomy list shows which runs still have pending work; those are the ones worth resuming.

Watching without interfering

From another terminal:

snaga tail <session-id>

This follows the session's structured event log. You see gap detections, tool calls and decisions as they happen, without attaching to the process or interrupting it.

When a long run finishes, Snaga notifies you — a terminal bell always, and a desktop notification where the platform has one. Opt out with SNAGA_NO_NOTIFY=1.

Before you let one run unattended

Autonomy does not relax any of the other rules. Confirmation requests still happen — and with nobody to answer, they resolve to deny, so a goal that needs a privileged command will stall on it rather than proceed. Decide in advance what the run may do:

--yolo removes that friction and every guard with it. On an unattended run, that is a decision to think about while you are still in the room.