v0.6.0
[0.6.0] — 2026-06-23
Four scoped capabilities, each shipping only what its substrate can honestly back
(no headline that the kernel or the stored data can't keep), plus a guard-hook
refresh and an honesty/correctness audit pass.
Added
- Secret read-confine.
sandboxgains{ protect_secrets: true }(built-in
credential-dir denylist:~/.ssh,~/.aws,~/.gnupg,~/.config/gcloud|gh,
~/.kube,~/.docker) and{ deny_read: [...] }(extra dirs). macOS appends
(deny file-read* (subpath …))to the SBPL profile (rule order: later wins, so it
overridesallow default); Linux masks each dir with an empty--tmpfs. Reports
secrets_protected: <n>. Scoped by design — it blocks the listed paths, not a
proof against all exfiltration. - Dry-run preview.
sh_run { preview: true }runs the command inside a
disposable CoW clone of cwd, returns the cwd-relativefiles_changed, and never
touches the real cwd (nothing is promoted). Refuses if the clone can't be made.
Honest scope, bannered inpreview_warning: absolute-path / parent-dir / network
effects are not captured and may happen for real — this is not a sandbox. sh_history. Descriptive aggregates over past runs of a command — observed
exit / retry-recovery / durationp50/p90/ file-churn with explicit sample size
nand recency window. Restates the local (capped, TTL-pruned) store; makes no
prediction and no causal claim. Read-only. (RunRecordgains anattimestamp.)- Landlock Linux sandbox backend (K++). A namespace-free fallback (via
landrun,
kernel 5.13+) that write-confines in containers / CI / Ubuntu 24.04+ where
bubblewrap's unprivileged user namespaces are restricted.sandboxAvailable()now
reports true on Linux with bwrap OR Landlock;wrapCommandprefers bwrap and
falls back to landrun. Scoped, honest: write-confine only — it refuses (so the
caller refuses) network-deny / secret-read-confine rather than fake them, and its
self-test runs a real confined no-op (no--best-effort) so an unsupported kernel
reports unavailable instead of silently running free. - Guard hook covers modern verbose tools.
hooks/veil-guard.shnow routes
bun/deno/uv(install/add/run/test/build/sync) and image builds
(docker build/buildx/compose build/docker-compose build) tosh_run, while
read-only (docker ps/logs) and long-running (bun run dev,docker compose up,
* --watch) forms still pass through to raw Bash. Danger branch, fail-open, and
VEIL_BYPASS=1are unchanged.
Fixed (audit pass)
expectcontent checks no longer lie on binary/truncated output.
stdout_contains/stdout_matchesdecode a base64 (NUL-byte) stream before testing,
and a non-match on a byte-cap-truncated stream is annotated inconclusive (the
needle may be in the dropped head) instead of a confidentpass:false.effectsFromTracecanonicalizes cwd — a symlinked root (/tmp→/private/tmp,
symlinked$HOME) no longer silently drops real in-cwd writes fromfiles_changed.- Read-confine discloses what it can't protect. A requested secret that exists as a
FILE (the dir-only backend can't mask it) is surfaced insecrets_unprotectedrather
than silently dropped whilesecrets_protectedcounts only the dirs. - Server version is read from package.json (was hardcoded
0.4.0, drifting a full
minor behind), asserted equal in the smoke suite. - Landlock knob-refusal is machine-readable (
sandbox_unsupported_feature: true). - Eviction has a memory backstop (records that never reached a flaky disk can't grow
unbounded);nextIdwon't hand back an id whose record file already exists; numeric
env tunables are floored at 0; a committed-then-clean file is labelled "no longer
dirty (committed or reverted)" instead of asserting "(reverted)"; the preview banner
notes.gitchanges are excluded from its diff. Removed deadsandboxSelfTest.