For AI agents: the complete documentation index is available at https://a3s-lab.github.io/ash/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/ash/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/ash/en/guide/protocol.md.

ASH/1 protocol

ASH/1 is the local machine protocol between a Coding Agent Harness and ash. It is not a POSIX shell language and does not parse Bash, Zsh, PowerShell, or CMD.

Two transports

  • ash rpc: long-lived session. Every ASON document has a four-byte big-endian length; handshake comes first, then concurrent requests.
  • ash run: reads one bare canonical ASON document from standard input, executes it, and exits.

The first rpc frame must be a handshake request. The server chooses a compatible protocol version, limits, and capability intersection, then returns one canonical handshake response. Noncanonical ASON, oversized frames, and unknown required fields fail before large allocation.

Core operations

OperationContract
execDirect executable + argv, environment delta, stdin, deadline, and process-tree cancellation
readBounded byte or line ranges and projection
listStable directory traversal and metadata
searchBounded text search, match context, and complete-result reference
patchCompare-and-swap multi-file patch with preimage digests
fsFile-only create/copy/move/remove transaction
snapshotWorkspace manifest and reference-based delta
batchAcyclic dependency graph, ready-node concurrency, and failed-descendant skipping
/ # ? - | >Slice, search, release, project, or safely materialize retained evidence
cancelCancel queued or active requests and descendants

Data formulas

Reference work uses the mathematical symbol as the operation code, with no generic ref wrapper or second discriminator:

o:|
a:[@7,d,0,64,p,l,t]

This is the compact wire form of π_{p,l,t}(d[0:64]) over @7. Operators / # ? - | > mean byte slice, line slice, search, release, table projection, and workspace materialization. Formula arity is exact. > also requires workspace-write capability and follows the journaled no-overwrite transaction path. The six formulas measure 80 tokens in both pinned tokenizers, matching the direct ASCII-letter floor and beating direct Greek at 86/86 plus the former wrapper at 97/98.

Lossless process evidence

exec drains stdout and stderr concurrently. Each stream keeps at most 4 MiB in memory, then spills every original byte into a session-private temporary file and retains only a bounded head/tail projection sample. Stdout/stderr aliases publish atomically, and / reads only the requested disk range. If the session cannot retain the complete capture, error 601 is returned with no partial reference. After reference release or session shutdown, the final active lease removes the corresponding temporary file.

Complete UTF-8 output first normalizes CRLF to LF, then projects a consecutive run ℓ^N as the first line plus count marker ×N. N includes the retained line, and collapse occurs only when the marker is shorter than the omitted bytes. Rayon may find runs in a large input concurrently, but boundaries merge in source order and worker count cannot change the result. Normalized or reduced output sets the corresponding flags and retains the exact source, so ×N need not be a reversible escape syntax.

A second pass handles blocks. If a K-line block B occurs N consecutive times, it projects one B plus ×N#K, with 2 <= K <= 32. Each position first selects the candidate with greatest byte savings, then smaller K and larger N; a non-saving candidate remains verbatim. Candidate search and large exact checks enter Rayon, but every omitted block is finally byte-equal to the retained block. Hash collisions and worker count cannot alter the result, and the exact source reference remains authoritative.

For an unsuccessful native exit (nonzero code or signal), a third pass focuses complete UTF-8 stdout and stderr on diagnostics. It keeps the first and last two lines plus two lines before and six after every stable error anchor. Each remaining byte-saving gap becomes ⋯N, where N is its logical-line count. ASCII diagnostic terms are matched as whole terms; identifiers such as TypeError and IOException use exact Error or Exception suffixes. Classification may enter Rayon, but window union and encoding remain source-ordered. No anchor means no reduction. Successful exits, timeouts, cancellations, opaque bytes, and disk-backed samples keep the existing path, while every reduced failure stream retains its exact source reference.

Every spool carries a versioned owner marker and a lifetime lock. A later process reclaims it only after one hour, only when no active lock remains, and only when every entry is recognized; uncertain roots are never modified.

A deadline or cancellation terminates and waits for the complete Unix process group or Windows Job Object, then waits for EOF on both pipes. Termination kind 3 means owned descendants and pipes are clean, not merely that a cancellation signal was sent.

Concurrency and order

A persistent RPC session can run independent requests concurrently. Final frames still follow stable input sequence, so the model side spends no tokens recovering from scheduler races. Cancellation control frames bypass final-response ordering to stop target work promptly.

Capabilities and permits

Handshake admits only capabilities supported by both sides. When policy requires approval, ash returns a typed challenge. A trusted Harness signs a one-time permit bound to session, request, canonical action, policy fingerprint, and expiry. Replay, cross-session reuse, and modified actions fail.

Exact fields and canonical fixtures live in docs/protocol.md and spec/fixtures/ason.