Skip to content

v0.6.0

Choose a tag to compare

@vkmtx vkmtx released this 23 Jun 08:08
· 27 commits to main since this release

[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. sandbox gains { 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
    overrides allow 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-relative files_changed, and never
    touches the real cwd (nothing is promoted). Refuses if the clone can't be made.
    Honest scope, bannered in preview_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 / duration p50/p90 / file-churn with explicit sample size
    n and recency window. Restates the local (capped, TTL-pruned) store; makes no
    prediction and no causal claim. Read-only. (RunRecord gains an at timestamp.)
  • 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; wrapCommand prefers 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.sh now routes
    bun/deno/uv (install/add/run/test/build/sync) and image builds
    (docker build/buildx/compose build/docker-compose build) to sh_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=1 are unchanged.

Fixed (audit pass)

  • expect content checks no longer lie on binary/truncated output.
    stdout_contains/stdout_matches decode 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 confident pass:false.
  • effectsFromTrace canonicalizes cwd — a symlinked root (/tmp/private/tmp,
    symlinked $HOME) no longer silently drops real in-cwd writes from files_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 in secrets_unprotected rather
    than silently dropped while secrets_protected counts 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); nextId won'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 .git changes are excluded from its diff. Removed dead sandboxSelfTest.