Running Growlight
There is one way growlight runs unattended and one way it runs with you at the keyboard:
softfig growlight startlaunches an interactive agent session, primed with the protocol and baton, that you watch and/clearbetween handoffs.- growlightd, a user daemon, runs unattended sessions for every armed fleet member. One agent is just a fleet of one.
Both drain the same backlog under the same protocol.
Scaffold: softfig growlight init
Section titled “Scaffold: softfig growlight init”softfig growlight initCreates the growlight/ pillar: protocol, session policy, an empty backlog and
baton-log, and the navigation wiring in the root map. It also seeds
config/growlight.toml with the fleet disarmed. It is idempotent: re-running
fills only what is missing and commits nothing if nothing changed. Then
queue some work.
Interactive: softfig growlight start
Section titled “Interactive: softfig growlight start”softfig growlight startGenerates the loop runtime under $XDG_CONFIG_HOME/softfig/growlight/ and
launches an agent session. You watch it work; at a handoff you /clear and the
next session reseeds from the rewritten baton. This is the best way to learn the
loop, and the right mode for work you want to review closely.
| Flag | Effect |
|---|---|
--backend claude|opencode |
Which agent runs the loop. Without a flag, a terminal gets a picker. |
--opencode |
Shorthand for --backend opencode. |
--model <spec> |
Backend and model in one word: claude, flash, reasoning, auto, or provider/model. auto uses the model the active item declares in its > Model: line. |
--no-launch |
Generate the runtime files, don’t start the agent. |
Unattended: arm growlightd
Section titled “Unattended: arm growlightd”growlightd (softfig-growlightd.service, a systemd user unit; see the
unit files)
supervises each agent in its own transient scope, so closing a terminal or
logging out does not kill the work. It is armed from the garden itself, in
config/growlight.toml:
fleet_enabled = true
[[fleet]]agent = "a" # a work-stream id; backend defaults to claude# pin = "my-queue" # optional: bind this member to one queuefleet_enabled ships false. The daemon is started when keeperd unlocks the
garden with the gate on, and re-reads the file when it restarts; to apply a
change to a running fleet, restart the unit
(systemctl --user restart softfig-growlightd.service). A config mistake never
arms anything: an invalid file leaves the fleet disarmed and logs why.
Because the gate lives in the garden, arming is a versioned, intentional change. The full key list (backend, model, queue model, binaries, bounded runs) is in the commented template.
Backends
Section titled “Backends”A member runs on claude by default. It can instead run on opencode (for
example over DeepSeek) with backend = "opencode" and a required model, chosen
per member, so a roster can mix both:
[[fleet]]agent = "b"backend = "opencode"model = "deepseek/deepseek-flash"An unknown backend, an opencode member with no model, or a model on a claude
member is refused rather than guessed, so no member quietly runs on a provider
you did not choose. opencode members are metered and shown with a dollar figure,
not against the Anthropic limits. Details and the permission model are in the
fleet backends guide.
Observe and steer
Section titled “Observe and steer”All are subcommands of softfig growlight (see the
CLI reference):
| Command | What it does |
|---|---|
status |
Fleet state, arm gate, pause gate, policy, roster, live agents, and items the fleet is holding for a human. |
watch |
Tail the live event stream: agent activity, budget changes, leases, bus messages. |
pause / resume |
Engage or clear the admission gate: no new or rolling agents while paused. |
resume <item> [--queue <q>] |
Flip one blocked item back to queued. |
stop --agent <id> [--level after-slice|after-iteration|hard-kill] |
Stop one agent at the next boundary (default after-slice), or immediately. |
say [--to <agent|@all>] <message> |
Post to the coordination bus as the human; agents read it at their next boot. |
reports [--tag t] [--all] |
List filed reports. |
resources show / resources set |
Inspect or adjust per-agent build caps live (--build-jobs, --memory-high, --cpu-weight). A throttle, never a kill. |
The terminal UI (softfig-tui, growlight view) shows the same fleet, backlog and
baton live; the optional growlight-gui window is a feature-gated build.
Redeploying when the loop rebuilds soft-fig
Section titled “Redeploying when the loop rebuilds soft-fig”If an agent rebuilds the keeper daemon it runs against, the garden’s encryption
would normally demand your passphrase on restart. softfig daemon cycle restarts
the daemon and resumes the unlocked session without it, using a one-time token
wrapped on 0600 tmpfs that expires after 20 minutes. It works only if you have set
allow_relock = true under [growlight] in the local keeper.toml. That switch
is deliberately outside the garden and outside the agent’s reach.
What the loop owes you, and what you owe it
Section titled “What the loop owes you, and what you owe it”The loop rewrites its baton and logs an entry at every handoff, never merges or
pushes, and escalates real decisions rather than guessing: they go to a for the
human list with a proposed default, or park the item as blocked.
You: skim the baton at handoffs, answer what it parks, keep the backlog real, and
do the review, merge and push. To keep the fleet off an item entirely, put
> Fleet: no in its doc; it stays queued but is held for you and shows under
held in status.
Next: Customizing Growlight.