Sandbox boundaries are explicit.
Choose Podman or Docker for container execution, or use a host-local git worktree. Container network access is blocked or fully open, readonly_rootfs is optional, and when a branch is created the safety proof checks existing refs and parentage. The final diff is written to your working tree for review.
Container or worktree execution.
Podman
Probed first at startup; Niki falls back to rootful sockets if rootless is unavailable.
Docker
Used when Podman is unavailable; the container backend binds the repository at /workspace.
Git worktree
No container runtime: a git worktree plus host-local processes. Niki prints a host-privilege warning and applies the final diff to the host working tree.
[docker]
backend = "docker"
base_image = "niki-sandbox:24.04"
cap_drop_all = true
readonly_rootfs = false
network_disabled = trueLayered controls
CapDrop ALL, Linux capabilities are dropped by default- Optional read-only rootfs (off by default); the bind-mounted workspace stays writable
- Container egress is block-all unless
network_allowlist = ["*"]; a non-wildcard list warns and behaves as block-all because per-domain allowlists are not implemented - A narrow default command deny-list, including
rm -rf /andcurl | sh; it is not a complete command sandbox - Git safety checks cover committed state;
safety_proof.jsonis not a sandbox or spend proof - Provider errors redact common secret patterns, including
?key=query parameters
Permission modes for unattended runs.
Ask before consequential actions; headless runs may need an explicit policy.
Allow in-policy sandbox actions; host-reaching actions can still ask.
Accept actions without prompting; use only with explicit trust.
Explicit, loud, for environments you control. It is not silent.
--permission-modeflag and[permissions] modeconfigdisable_worktreekill-switch for the no-container backendfail_closed_headless, when enabled, unanswerable approvals fail the run; it is off by default- Lifecycle hooks (
[hooks.commands]) can block runs fail-closed at each stage boundary
A spend cap that actually stops.
Niki records provider-reported token counts and estimates USD from a dated price table. A positive spend_cap_usd is enforced before further stages run; 0.0 means unlimited. Unknown or unpriced models report $0.00 for the estimate and emit a warning that the estimate may understate real spend.
$ niki report <id>…tokens provider-reportedcost estimated from the dated price tablecap enforced when greater than zerotrace local trace.jsonl; OTLP optional
The whole decision trail, on disk.
Human-readable run report under `.niki/tasks/<id>/`: verdict, scores, revisions, token counts and estimated cost.
The unified diff is the published change; task artifacts are written beside it and excluded from the diff.
Per-agent JSON artifacts under `.niki/tasks/<id>/artifacts/`, schema-validated: what each stage emitted. These artifacts stay outside the published diff.
Git invariants for a non-empty run: branch preservation, parentage and no history-rewrite signals. It is not a sandbox or spend proof, and is skipped on empty diffs.
Run provenance under `.niki/tasks/<id>/` when snapshots are enabled. Snapshot metadata is retained for 14 days by default, with configurable pruning of older task directories.
Per-span event trace written locally under the task directory; OTLP export is optional.
May emit a partial JSON bundle for one task. `complete` reflects report.md plus safety_proof.json only, not every artifact or test result.
Outbound traffic is feature-specific.
Provider calls for the stages you run. Nothing else unless you enable it.
niki research via DuckDuckGo, knowledge-base URL fetching, optional OTLP export, and remote MCP servers.