Format
The event log is NDJSON — one JSON object per line, emitted in chronological order. Every object has an"event" field identifying its type and a "ts" field with a Unix
timestamp in milliseconds.
Output destination
By default, events are written to stdout, interleaved with your agent’s own output. To separate them, configure file output:.nanny/logs/log.ndjson, a location Nanny always owns and auto-creates,
never something you point at a path yourself. Only set file if you want a different
name — a bare name, no extension, Nanny always appends .ndjson itself:
.nanny/logs/ is meant to stay out of git (Nanny adds it to .gitignore automatically
the first time it’s created): it’s a local audit trail, not source. If you later log this
machine in (nanny auth login), Cloud sync can back-fill from whatever accumulated in
that folder before sync was ever turned on, not just events going forward.
Or pipe stdout to a file at the shell level:
Guaranteed events
Every execution emits exactly these two events, in this order:ExecutionStarted
Always the first event. Emitted immediately before the child process is spawned.ExecutionStopped
Always the last event. Emitted on every exit path — clean exit, timeout, error, or signal.reason will be one of the stop reasons listed in
Limits & Enforcement.
SDK events
When the Rust SDK macros or Python SDK decorators are active, additional events are emitted for each tool call. These appear betweenExecutionStarted and ExecutionStopped:
ToolDenied and RuleDenied are distinct denial events — ToolDenied means the tool was not permitted at all; RuleDenied means the tool was permitted but a rule blocked this specific call.
ToolFailed is different from both — the tool was allowed and called, but encountered a runtime error. No tokens are charged on failure.