Agent tenants exist to run the cron-driven duty engine, and the engine's
installer runs unprivileged — it can detect a missing cron but never
apt-get it. Install cron with the shared toolbelt, then assert the
effective state, not the package: crontab on PATH AND cron.service
enabled and active, converging (unmask/enable/start) best-effort first.
A masked daemon with the binary present is exactly the silent-inert box
the issue reports, so the service asserts are the authority and either
failing dies naming cron.
staging-box stays exempt with the rest of the agent-assert block: no
agent, no duty engine. Machine roles (bootstrap.sh) are deliberately
not widened — the issue names tenants as the demonstrated gap.
Closes#162
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
json_string_array took the first "Tags" array anywhere in the document,
justified by Self-before-Peer field order. An untagged Self omits the key
entirely (Go omitempty), so the match fell through into Peer and returned
a peer's tag — false-refusing every login join and false-verifying
untagged authkey joins on any tailnet with a tagged node. Extract Self by
brace counting (Location nests an object, so slicing to the next key
would truncate) and read the array inside it.
Refs #160
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first README fence becomes two labelled, copyable commands — the
RIG_REF=main development command first (byte-identical to before, so the
#89 guard at test/cli.sh:514 still passes) and the bare latest-release
command below it, each preceded by a comment line naming its channel.
Refs #149
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The security-trade paragraph lands verbatim in the README (its twin is in
rig-templates' README, per the issue's docs task), with the 2026-07-24
ruling recorded in place.