Repository navigation
Latch v0.2.2
Latch v0.2.2 makes the agent scriptable, coordinated, and harder to fool. It
adds a stable machine interface (latch run, resume, sessions, doctor)
for scripts, CI, and benchmark harnesses, durable agent groups for parallel
workstreams, and a deterministic release gate that CI runs on every change.
Security and evidence got stricter: sandboxed processes and native tools cannot
reach Latch credentials or its state directory, an approval can never grant
something the sandbox cannot execute, and only kernel validation can call a
changed workspace verified.
Highlights
A stable machine interface
latch run,latch resume,latch sessions, andlatch doctorare the
non-interactive surface for scripts, CI, coding agents, and benchmark
harnesses. They never open the TUI, never wait for a human, and never mix
diagnostics into stdout.latchstill starts the TUI, andlatch -p "..."
(also with--resume) now runs through the same machine implementation.- Prompt sources are exclusive: exactly one of
--prompt,--prompt-file, or
--stdin.--workspaceresolves and canonicalizes before session selection,
policy, prompt compilation, and tools. --output text(the default) preserves the historical one-shot behavior and
streams assistant text.--output jsonprints exactly one versioned object
("schema_version": 3) with command, session, workspace, run status, resolved
provider/model/effort, durable task state, scoped usage, context accounting,
and event/graph summaries.--output jsonlstreams semantic records
(text_delta,tool_result,durable_event,final).- Usage is scoped to the invocation (
usage.scope = "invocation_graph"): a
resumed run counts onlyModelUsageevents emitted after it began, existing
children exclude prior history, and children spawned mid-invocation count from
their own beginning. Provider categories that were never reported staynull
instead of being fabricated as zero. - Run status stays distinct from durable completion.
status=completedmeans
the invocation ended normally; usetask.completion,task.evidence_count,
andtask.validationfor the kernel's durable state. - Exit codes are stable: 0 completed, 1 runtime failure, 2 CLI/config error,
3 permission unresolved, 4 cancelled.SIGINTorSIGTERMcancels a run and
still emits the final structured result withstatus=cancelled. - Machine mode is fail-closed for permissions: an
Askthe policy cannot
resolve without a human is durably denied and exits 3. There is no--yesor
skip-permissions flag, and existing invocations keep working.
Preflight doctor
latch doctorchecks the machine a run depends on: the mandatory Bubblewrap
sandbox (probed with a minimal sandboxed command), thergsearch runtime,
Git, the effective config path and state directory, the resolved
provider/model/effort, and that the provider credential resolves.- It never contacts the provider, never runs a task, and never prints secret
material: a credential is reported only by its symbolic reference
(env:NAME,file:NAME). - Human-readable by default, one versioned JSON object with
--output json.
Exit 0 when every required check passes, 1 for a runtime prerequisite, and 2
for a CLI or configuration error.
Agent groups
- Agent groups add durable coordination on top of child agents: a shared task
DAG with validated dependencies, atomic compare-and-set claims with exactly
one winner, a durable peer mailbox delivered exactly once at safe model
boundaries, and replayable progress state. Groups never own workers, are
created lazily on first use, and ordinary single-agent and subagent use is
unchanged. - Three fixed tools expose coordination:
group_task,group_message, and
group_status.spawn_agent { task_id }joins a child and assigns a ready
task atomically; only its assignee can start, complete, block, or release it,
and only the root can cancel or reassign. - Root terminal
completeis refused while required group tasks are still
pending, claimed, in progress, or blocked. An interrupted child keeps its task
until an explicit release, reassignment, or completion, so a crash cannot
duplicate work. Completing a task is coordination truth, never root evidence. - Messages are information-only and never wake an idle child or copy
transcripts. Workspace conflicts are advisory warnings from declared paths,
never hard blocks; depth stays 1. - The sidebar shows a compact
GROUPblock with task counts and active owners,
and/groupprints the full coordination view.
Cross-session cache locality
- The provider
systemfield and tool schemas are now session-independent:
workspace, repository instructions, and mode moved into the first
provider-visible message as an explicitly delimited kernel block, so the
cacheable prefix is reused across sessions and mode switches. The session
block stays distinct from the user request, and Anthropic merges adjacent
user roles into ordered, separate text blocks instead of one concatenated
string. - Measured against OpenCode Go with two fixtures differing only by
AGENTS.md:
the second session's first request read 4096 tokens (88.7%) from the provider
cache (was 0), and aggregatecache_read/inputrose from 0.769 to 0.922. - Prompt fragments are ordered least-volatile first, with mode as the trailing
fragment, and the system prompt was trimmed ~12.8% (1489 -> 1298 estimated
tokens) plus tightened tool schemas without changing any tool name, parameter,
enum, or semantic. Read-only inspection, narration, and validation discipline
are now explicit instructions. - Bounded recall selects the newest matching rows first and presents them
chronologically, so a later correction survives/compactand resume even
when older turns repeat the term.
Security and truthful completion
- Credentials are isolated from sandboxed processes: the resolved state
directory and symlinked secret targets are masked for shell and extension
processes, and the kernel-nativeread_file/read_image/search/write/
patchtools refuse the state directory and symlink aliases into it. - Approval can no longer grant what the sandbox cannot execute: unknown tools,
external write targets that cannot be mounted, and Latch state or credential
targets are refused before a normal approval prompt, and a grant cannot
override those refusals. - Whole-file writes require strict compare-and-swap:
base_hashmust match the
current bytes exactly, so one agent can no longer silently overwrite another
agent's newer write. The stale error names the path and both hashes, and the
agent can re-read and retry. - Read-only Git queries are classified per invocation, so
git config --get,
git status, and.git-excluding path filters no longer trigger spurious
metadata-write approvals in machine mode..gitstays read-only in the
sandbox, so this only narrows the Ask heuristic. - Passing validation certifies only its durable workspace generation: guarded
edits and write-capable shell commands advance the generation, a running
write-capable managed process blocks certification until it exits and
revalidates, and resume rebuilds the same state without deleting history. - Verification is separate from loop termination: only
Verifiedends a run on
the strength of its own claim. A run that actually mutated the workspace and
is about to finishImplementedNotVerifiedgets exactly one corrective turn
to validate or record why verification is unavailable, and no correction can
ever promote a run toVerified. - Tool failures stay typed across providers:
is_errorsurvives the durable
projection, Anthropic uses nativetool_result.is_error, and the
Chat Completions and Responses adapters use a small
[latch:tool:ok]/[latch:tool:error]envelope instead of inventing an
unsupported field. read_file/read_artifactare bounded (64 KiB per call, paged line windows,
explicit continuation markers),searchpages with a total count, and binary
or invalid UTF-8 input is rejected honestly.
Reliability
- Every extension lifecycle stage is bounded end to end by the central
[extension_lifecycle]policy: spawn/initialize, ready, ordinary RPCs,
shutdown, and graceful exit. A missed deadline kills and reaps the child, and
startup observes cancellation, so a silent extension cannot block Latch. - The sidebar derives the latest durable user request from kernel events, so
live and resumed sessions show the same request state. - OpenCode Go's default endpoint now targets the versioned gateway
(https://opencode.ai/zen/go/v1), fixing HTTP 404s; endpoint detection, the
stablex-opencode-sessionheader, and model selection are unchanged.
Architecture and CI
docs/RUNTIME_CAPABILITY_MODEL.mddefines the kernel invariants extensions,
backends, and clients may not bypass, the replaceable-port rules, and the
implemented-vs-deferred port map. A narrowContextEngineport replaces the
direct continuity dependency (request/result objects, noEventStoreor
SQLite in the contract), propagates to children through one factory, and
fails closed rather than silently falling back. Default behavior stays
byte-identical.bash scripts/release-gate.shis the deterministic release gate: a Bubblewrap
namespace/mount probe, formatting, locked Clippy with-D warnings, the
kernel invariant tier, the full workspace suite, and a locked release build.
CI runs the same gate on an ephemeral Ubuntu 24.04 runner with Bubblewrap and
user namespaces enabled.- The optional Docker dogfood harness runs the machine CLI against a disposable
workspace in a non-root container without host networking or baked
credentials, records image/source provenance, and includes deterministic,
credential-free integration checks.
Install
Download latch-v0.2.2-x86_64-unknown-linux-gnu.tar.gz below and verify it
with SHA256SUMS, or install from the repository:
cargo install --path crates/latch-cli --lockedThe archive contains the stripped latch binary, LICENSE, README.md,
config.example.toml, and BUILD_INFO (source commit, toolchain, and sandbox
versions). Runtime prerequisites are bwrap (mandatory sandbox) and rg
(search); run latch doctor to check them before your first task.
Validation
bash scripts/release-gate.shpasses on the release commit: formatting,
Clippy with-D warnings, the kernel invariant tier, the full workspace test
suite (kernel, providers, sandbox/command, continuity, CLI machine interface
against a loopback SSE mock provider, extensions, snapshots, dogfood, group,
and stagnation suites), and a locked release build.- CI is green on the same commit on Ubuntu 24.04 with Bubblewrap namespaces and
the mandatory sandbox probe (run 36110454628). - Live, paid-provider tests remain opt-in and ignored, and are not counted as
deterministic CI. Real-provider dogfood measurements made during development
(cross-session cache reuse, prompt trimming, Git classification) are recorded
indocs/DOGFOOD_EXPERIMENTS.md, and the long-horizon report in
docs/LONG_HORIZON_TEST_REPORT.mddocuments 161/189-model-turn runs with
rollover and resume.
Full Changelog: v0.2.1...v0.2.2