This document defines the filesystem enforcement contract for local Veritas Kanban agent runs. It is the implementation contract for issue #862.
Documentation freshness: 2026-07-25.
Veritas compiles every required filesystem policy before attempt state is
mutated. Local process adapters run behind one version-bound sandbox wrapper.
The first supported wrapper is the public codex sandbox command introduced
in Codex CLI 0.145:
/usr/bin/sandbox-exec;Veritas does not shell-wrap providers. It invokes the wrapper with an exact
SandboxState JSON document followed by the provider command and arguments.
The wrapper remains the supervised process, so its provider descendants share
the same process group and filesystem boundary.
An unavailable or non-conformant wrapper does not silently weaken a required
policy. A provider-native sandbox can satisfy the contract only when its
versioned runtime manifest reports every required filesystem capability as
supported. The active read, write, deny, dotfile, descendant-process,
run-scoped temporary-directory, and cleanup requirements must all be covered.
Coarse provider modes such as workspace-write remain advisory until their
exact-root semantics have version-bound conformance evidence.
Remote providers such as OpenClaw cannot use a host-local wrapper. They must provide equivalent version-bound native evidence or the required launch is blocked.
The filesystem compiler resolves these preset fields:
| Preset field | Compiled behavior |
|---|---|
readPaths |
Read-only entries after absolute and symlink-aware resolution |
writePaths |
Writable entries after absolute and symlink-aware resolution |
deniedPaths |
Deny entries with precedence over ancestor read or write grants |
dotfileMasking |
Deny globs for dotfiles below every configured root |
localOnlyHandles |
Blocks remote execution unless equivalent local-handle evidence exists |
<workspace> resolves to the canonical task worktree. ~ resolves to the
operator home directory. Other entries must be absolute. Missing leaf paths
are resolved through their nearest existing canonical ancestor; an
unresolvable or ambiguous path fails closed.
Workspace-relative and home-relative aliases must remain below their
canonical base, so .. traversal and symlinks cannot turn a scoped grant into
an external grant. Existing mount points below an allowed root are denied
unless that exact mount is explicitly granted or already covered by a deny
rule. Veritas rechecks the relevant mount topology immediately before
activation; a changed or uninspectable topology blocks launch. Provider-native
enforcement blocks on an ambiguous local nested mount because Veritas cannot
amend the provider’s native boundary.
Before policy compilation and again immediately before activation, Veritas scans the bounded workspace tree for pre-existing hard links that alias an external denied or non-readable inode. It does not follow symlinks during the scan. An external alias, an unbounded tree, or an inspection failure blocks the launch instead of relying on the native backend to distinguish two paths to the same inode.
Required policies start from Codex’s :minimal platform-runtime read set and
then add only configured roots. The wrapper, provider executable package, and
canonical PATH directories are recorded as read-only platform-runtime
entries so the selected harness and normal task tools can execute without
granting a general home-directory read.
Node package roots and Python virtual-environment roots are resolved from the
selected CLI launcher and added narrowly. Linked Git worktrees add only their
canonical worktree and common metadata directories as protected read-only
roots. Ambient system and global Git configuration is disabled inside the
boundary; Veritas carries only the effective author name and email in the
in-memory launch environment when they are available. Those values are not
stored in launch evidence or logs.
The legacy advisory preset retains its documented compatibility behavior and
is recorded as advisory evidence rather than being represented as a required
boundary.
Local provider-native and wrapper-backed runs receive dedicated temporary and
cache directories. They are added as writable roots, supplied through
TMPDIR, TMP, TEMP, and XDG_CACHE_HOME, and bound to the durable run
supervisor for terminal cleanup. A remote provider-native backend must instead
prove both run-scoped temporary storage and cleanup ownership in its exact
runtime manifest.
Codex protects .git, .agents, .codex, and .veritas-kanban metadata
directly beneath configured writable roots. Veritas records those protected
names in the launch evidence and emits explicit read-only entries so the root
write grant cannot make them writable. A policy cannot select a protected
metadata path itself as a writable root, and a protected path that is or
becomes a symlink blocks activation. Dotfile masking is stronger and denies
reads as well as writes.
run-launch-manifest/v1 records a
filesystem-sandbox-evidence/v1 object containing:
The provider runtime manifest remains the evidence authority for provider-native enforcement. The filesystem evidence links to that manifest instead of duplicating unredacted provider configuration.
The wrapper probe is credential-free. It checks:
codex sandbox flags;Probe results are cached only for the current executable byte digest, version, platform, and Veritas probe revision. Veritas rehashes the selected executable after policy evaluation and immediately before activation. A replacement, including a same-size binary with restored timestamps, blocks launch and must re-run conformance before it can satisfy a required policy.
Platform CI runs deterministic compiler and launch-contract tests everywhere. Credential-free backend smoke tests run only when the matching native backend is available.
Policy compilation and backend conformance happen before attempt persistence. Run directory activation happens after the immutable launch manifest and supervisor binding exist, but before provider spawn.
If launch fails before supervisor registration, Veritas removes the task-owned run directory directly. After registration, terminal cleanup is a durable supervisor responsibility. Cleanup state is persisted so interrupted or failed removal can be retried without guessing which directory belongs to the run. Cleanup canonicalizes the sandbox base and rejects a symlinked or non-directory ancestor before recursive removal.
Veritas exposes no per-run bypass for a required filesystem boundary.
overrideReason applies only to task-readiness checks and cannot weaken a
sandbox decision. An operator who intentionally wants advisory enforcement
must use the separately authorized sandbox-policy API to select or maintain an
advisory preset. Policy evaluation and launch then record the resulting
decision in governance evidence linked to the launch manifest.