---
slug: mega-packet-unified-dispatch-sandbox
title: "Unified Dispatch × Macaroons: The Sandbox Remedy — One Grammar, Every Capability, No Toy Shadow"
kind: packet
status: published
hash: 18e4963ac6cd62e39dd080f598599b1730e4091b1eccb58a199244724b7e59bb
created: 2026-10-09T00:24:51.237Z
updated: 2026-10-09T00:25:40.697Z
summary: "A sendable packet of the build's hardest bets: unified dispatch (one envelope for data + execution with projection at every layer), macaroons for sandbox training (scope the run, not the model — every limit a caveat, every touch a receipt), 1,340 atoms with 23 ways and a resolver that ranks you, containers that never hold a real key, and the directory↔ledger → person-as-JSON braid — linked to the three deep dives."
tags: ["briefing","packet","dispatch","grants","sandbox"]
above: ["[[unified-philosophy-the-unified-optimum]]", "[[oip]]"]
below: ["[[unified-dispatch-macaroon-atoms]]", "[[directory-ledger-pattern]]", "[[dispatch-four-step-loop]]"]
adjacent: ["[[json-articles-how-they-work]]", "[[object-ledger-evidence-graph-spec]]"]
nested: []
---
# Unified Dispatch × Macaroons: The Sandbox Remedy — One Grammar, Every Capability, No Toy Shadow

*A sendable packet of the build's hardest bets: unified dispatch (one envelope for data + execution with projection at every layer), macaroons for sandbox training (scope the run, not the model — every limit a caveat, every touch a receipt), 1,340 atoms with 23 ways and a resolver that ranks you, containers that never hold a real key, and the directory↔ledger → person-as-JSON braid — linked to the three deep dives.*


# 1. The opening — what broke, and the one fix that fixes it

## 1.1 The problem in the owner's words

> the vast majority of claude's calls are around utter fucking nonsense, like wasting significant amounts of time having models make myriad bash calls to a file, then out of a file, then not respecting the file hashing

That's the acceptance test. VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md §1, lines 43-45. Same wording appears as the epigraph of the prior dispatch article, where it is verified with line numbers. INFERRED — the second-order reading that the failure is not model quality but runtime design is the owner's paraphrase in the same section ("The fix is not a smarter model."). VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md:49-50.

Two wastelands, one geometry:

```
DATA      TARGET → FILTER → SELECT → ORDER → PAGE → AGGREGATE → RETURN WHAT WAS ASKED FOR
EXECUTION TARGET → ARGS   → DEPEND ON → RUN  → PROJECT → RECEIPT
```

Source of both lines: DISPATCH-ARCHITECTURE-MASTER.md:55-56. VERIFIED. The owner wants them one grammar, not two systems — the unified dispatch. VERIFIED — same file:58.

The second wasteland is the warehouse return: a model asks a question and receives the warehouse. Same shape — mechanical re-derivation and context pollution — seen from the data side. VERIFIED — paraphrase of DISPATCH-ARCHITECTURE-MASTER.md:52-53, tagged VERIFIED because the sentence is named in that file and the paraphrase does not change its content.

This article's killer claim, stated up front:

**Unified dispatch and macaroons are the novel remedy for models getting loose during sandbox training, because with unified dispatch you can delegate — and limit — everything in an environment.** Give a training run a scoped macaroon over the *real* environment, not a toy shadow of it, and the model is tight by construction. Every limit is a caveat. Every touch is a receipt.

That sentence is this packet's pitch. INFERRED as a synthesis of the grants system and the dispatch architecture; VERIFIED piece-by-piece in §2-§4.

---

# 2. Why sandbox training needs this — and what actually fixes it

Sandbox training today is unbounded programmatic execution: a model that can bash-to-file, file-to-bash, warehouse returns, repository-wide loops, tool fan-out with no ceiling — often against the real filesystem, the real shell, the real browser, the real ledger. The usual answer is "make the model smarter." That answer does not work in a sandbox and it does not work in production, for the same reason: the risk is not intelligence, it is scope.

The fix is not a smarter model. VERIFIED — "The fix is not a smarter model. It is a runtime that does the mechanical part deterministically and returns a projection." — DISPATCH-ARCHITECTURE-MASTER.md:49-50.

The fix is two moves, fused:

**2.1 Runtime projection.** Do the mechanical part deterministically and return what was asked for. The build already proves this is real, not planned: the full Directory catalog, 1,340 rows, costs ~1.38 MB / ~374,000 tokens when read whole (100 rows per page × mean 1,032 bytes per row). The light projection of the same catalog costs 28,080 bytes / ~7.6k tokens — a 49× shrink, shipping today. VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md §2.1, lines 66-78, with repro commands given in that file and carried verbatim in the prior dispatch article. The lesson the document itself draws, and which this packet adopts as law: *the runtime already knows how to project a catalog down to names. The `want` idea is not a proposal; it is an existing mechanism with one hardcoded caller.* VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md:76-78, paraphrased with the file's own bolded sentence.

Projection recurs at every layer of the build, not just catalog listing:

- **R2 + pg-store:** `INLINE_MAX 256 KiB` — bytes up to 256 KiB live in PostgreSQL inline; larger bytes spill to Supabase Storage; the blob is deduplicated by sha256 so repeated payloads are stored once; conditional writes (`onlyIf: {etagMatches}` / `etagDoesNotMatch: '*'`) refuse on stale etag and return null — the same atomic compare-and-swap the R2 bucket always offered, now as SQL (`ON CONFLICT DO NOTHING` / `WHERE etag = $`). VERIFIED — src/pg-store.js lines 1-10, 18, 120, 144-171, and the module's header comment. INFERRED only for the claim that the pattern is intentionally parallel to R2's CAS, which the file says directly.
- **Ledger as query surface:** filters, projections, aggregates (count, p95), deterministic paging with opaque `cursor` + explicit `next`, and an answer-shaped return while the underlying evidence stays addressable — the same `want` mechanism, not a special case. VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md §4 D3 (154-167) and D7 (184-186), and the live Ledger at GET /api/ledger/* described in the directory-ledger-pattern article.
- **resolve → call → receipt:** the dispatch four-step loop (see the prior `dispatch-four-step-loop` article) is itself a projection: `resolve` (one free-text query → ranked rows with `matched_on` / `matched_because`) projects the 1,340-row directory to one row; `call` runs it; `receipt` lets the model re-project the same invocation without re-running a side effect. VERIFIED — that four-step article's own verified repros of `resolve`, `read`, and `run`.

**2.2 Scoped delegation.** Project *who* may touch *what*, not just what comes back. That is the grants system — macaroons as capabilities — and it is why the sandbox thesis works: a training run holds a token `g1.<payload>.<sig>` whose payload is readable JSON `{i: id, c: [caveat,…]}` and whose signature is a chained HMAC; every caveat is a limit written as a line of text; every limit must hold for a call to run (ANDed); any unknown caveat is a refusal, never a pass. VERIFIED — src/grants.js header, lines 1-27, and the AXES definition lines 48-79. Doors: GET /g/run/<TOOL> (a link), POST /g/run (REST), POST /g/mcp (MCP), a chat with a model (/g/chat), and a task's proof page (/w/<TASK>). VERIFIED — same file, lines 22-26. The build's tool runner (POST /api/run) sits behind all of them, so every call out and every answer stays whole as `ledger/exchanges/<call_id>.json` and as a Ledger row. VERIFIED — src/grants.js:24-26.

Together, the thesis in one line for training leads:

> **In training, give each run a scoped macaroon over the real environment — `delegate=no, task=…, area=…, uses<=…, tools=…, expires<…` — so even a loose model can only touch what the token allows, and every touch is a receipt.**

INFERRED as the application of the already-shipping grants checker to the already-shipping dispatch runner; VERIFIED for each fragment (macaroon shape, ANDed caveats, area-scoped paths, task-bound receipts, holder-side narrowing, `delegate=no` termination).

---

# 3. The tour, in one packet — the hardest pieces, linked

This section walks the build end-to-end. Each subsection names its prior article so a reader can branch, and each claim is build-verifiable and tagged.

## 3.1 Atoms: 1,340 tools, 23 ways, a language you speak in, a resolver that ranks you

**The number.** Directory holds 1,340 capabilities. VERIFIED — DISPATCH-ARCHITECTURE-MASTER.md:68 (".The directory holds **1,340 capabilities**."). The grants article repeats it as "about 1,340 tools" (src/grants-article.js commentary line), same count. The directory-ledger-pattern article names it as `1,340+ capability listing at state/directory` (its facts block). VERIFIED.

**23 ways per tool.** Each tool row is runnable 23 ways, written as cells runnable as-is anywhere (a terminal, any HTTP client), and each run lands on the Ledger. VERIFIED — src/ways.js header (".A call to an outside service goes through POST /api/invoke-json") and export `compileWays(o)` (line 51) with the three token links (`tokenLinks`, line 44) and the counted map of ways (curl, named, url, jsonrpc, claude_code, misc, console_app, line, tag, shortcut, webhook, shell, run, mcp, oip, oip_shape, function_call, js, python, sdk, function_direct, mcp_stdio, ssh, graphql, websocket, sse — enumerated src/ways.js:51-111 and in the grants article's ways table). The prior dispatch article enumerates them with samples. VERIFIED.

**Directory-language + resolve scoring.** The especially novel part — hardest to rebuild elsewhere — is how a person speaks to the build as data. Three layers in order (VERIFIED — src/directory-language.js header, lines 1-11):

1. ALIASES — everyday words → name PATTERNS the rows are matched against (e.g. `'text message'` → `['^IMSG_', '^BLOOIO']`). Patterns anchor at start when prefixed with `^`. VERIFIED — src/directory-language.js:13-78.
2. Typo tolerance — Damerau–Levenshtein with transpositions scaled to token length, then Soundex.
3. QUESTION_SHAPES — `how do I / where is my` framings stripped before matching.

The resolver (VERIFIED — src/directory-resolve.js:1-18) scores against INTEGER layers, never a probability, with a named reason:

1000 — name IS query; 900 — query is prefix of name; 800 — name starts with query's first word; 700 — every word in name; 600 — alias points here; 500 — every word somewhere in row; 300 — one typo away; 200 — sounds like. Every returned row carries `matched_on` and `matched_because` (the integer → phrase map in LAYERS, lines 32-42). VERIFIED — same file, lines 32-44. Repro: `GET /api/directory/query?q=imessage → `score 900/600 with `"blue bubble" means this"` as the pattern reason. INFERRED for the surrounding claim that this is the single implementation for find tool, `/api/directory/query`, and the Console screen (re-exported through src/r2-directory.js:22).

**What was verified vs what is claimed.** VERIFIED: count, ways count, alias patterns, score layers, filed repros. INFERRED: that the count is exactly 1,340 on the live build today (the master doc says 2026-10-01; a re-verify is needed — the doc itself says "re-verify, do not trust" at §2).

## 3.2 Containers: Sandbox, CommandContainer, Harness — and the interception that keeps keys off images

The build's compute is containers, and its most load-bearing invariant is that keys never live on images.

**Durable Objects.** wrangler.jsonc binds five: `TaskAgent`, `Sandbox`, `ChatTurn`, `COMMAND_CONTAINER`, `Harness`. VERIFIED — wrangler.jsonc:18-25 (the `durable_objects.bindings` array). Two container applications complement them:

- `Sandbox` (legacy Container class, src/r2-coding.js) — where the Task agent's Cline sub-agents each run. `class Sandbox extends BaseSandbox` with `interceptHttps = true` and `enableInternet = true`. VERIFIED — src/r2-coding.js:42-46.
- `CommandContainer` (Durable Object Container API, src/r2-container.js) — same image, newer API; the container belongs to the DO and is reached through `ctx.container` rather than the Container class lifecycle; instance type chosen per `start()` (lite 256 MiB … standard-4 12 GiB, or custom vCPU/memory/disk). VERIFIED — src/r2-container.js:1-9 and exports (INSTANCE_TYPES, resolveSize).

`Sandbox` keeps its own fixed size at bind time; `CommandContainer` picks at start (standard-1 is the smallest that runs a coding agent, per src/r2-container.js and wrangler comment). VERIFIED — wrangler.jsonc comments at lines 36-52 and src/r2-container.js preamble. A container bills only while running — unused headroom at `max_instances: 40` (
VERIFIED — wrangler.jsonc:30, `max_instances: 40`) costs nothing; `delegateManyTool` starts every harness in its array at the same moment. VERIFIED — src/r2-task-agent.js via wrangler comment.

**ContainerProxy interception.** The image's `OPENROUTER_API_KEY` and `BUILD_KEY` are placeholders. Interception arms at `start()` against `openrouter.ai` and `miscsubjects.com` (src/r2-container.js:82-84 and src/r2-coding.js call sites with the same two hosts), handing each outbound request to the Worker's own `ContainerProxy` export so the Worker's real `OPENROUTER_API_KEY` and `BUILD_KEY` replace the placeholders. Without the `exports: {ContainerProxy: {type: `worker`}}` export, wrangler would silently ignore the proxy and every delegated run would authenticate as nothing. VERIFIED — wrangler.jsonc:4-10 and src/r2-container.js:29-45 (`openrouterWithKey`, `sheetsKeyWithKey`). The same identical pair on the older Sandbox serves the Cline sub-agents; the pair on CommandContainer serves the four harnesses. VERIFIED — src/r2-container.js:167-169 and src/r2-coding.js paired handlers.

**Harness durability.** `class Harness` (src/r2-harness-fused.js:307 — `export class Harness {``) is a Durable Object so a turn survives a deploy and can be resumed by name. Migration tag `v9-fused-harness` created it and must keep naming it or wrangler replays every earlier migration (TaskAgent already depended on by existing objects). VERIFIED — wrangler.jsonc:155-164 and src/r2-harness-fused.js header at 305.

**ChatTurn DO.** A reply runs in a Durable Object of its own, one per message (`class ChatTurn` in src/r2-worker.js:637). VERIFIED — wrangler.jsonc:23 + `class ChatTurn` symbol, cross-checked via `grep -n class Harness/Sandbox/CommandContainer/ChatTurn/TaskAgent` against the build.

## 3.3 Grants / macaroon system — g1 chain, AXES, narrowing, proof pages

This is the longest technical section because it is the remedy's core and the part most readers will not have touched before.

**The token.** `g1.<payload>.<signature>`. Payload is readable JSON `{i: id, c: [caveat,…]}`; every caveat is one line of text; the signature is a chain — `s0 = HMAC(root, id)`, then `s(k) = HMAC(s(k-1), caveat k)` — and the token carries the last link. VERIFIED — src/grants.js:9-10. The root is `HMAC(build key, "misc-sheets grants v1")`, so only this build can make a first link and a new build key ends every token at once. VERIFIED — same file:10-11.

**Proof of construction.** The article is computed live when rendered: the holder page computes the chain so every number is real arithmetic, not a screenshot. The demo chain (not this build's root) in src/grants-article.js:21-23:

```js
const demoRoot = await hmac(enc.encode('a demo build key'), 'misc-sheets grants v1');
let s = await hmac(demoRoot, id);
for (const c of caveats) { s = await hmac(s, c); }
```

VERIFIED — src/grants-article.js:21-23. The demo token does not work on this build because the root differs. INFERRED from the demo key value and explicitly named as a demo in that file.

**AXES — the one list everything reads.** The checker, the Console builder, and the article all read the same array. VERIFIED — src/grants.js:55-67 AXES and 48-54 WAYS:

| # | Name | Op | What it limits | Example |
|---|---|---|---|
| 1 | tools | = | Which Directory rows may run; LEADS_* wildcards | tools = EXA_SEARCH,LEADS_* |
| 2 | ways | = | Which doors: link, rest, mcp, chat, proof | ways = link,mcp |
| 3 | expires | < | Expiry timestamp | expires < 2026-10-10T00:00:00Z |
| 4 | uses | <= | Count along chain; limit on first link covers every narrower token | uses <= 5 |
| 5 | task | = | Ledger session task:<TASK> every run is recorded under | task = T-0207 |
| 6 | area | = | Path prefixes a path-bearing arg must start with | area = /.../src/ |
| 7 | arg | rule | One arg of one tool must match =|prefix|glob|in|<=|>= | arg EMAIL_SEND.to glob *@acme.com |
| 8 | person | = | Only this signed-in person may use it | person = p_k2x9qa |
| 9 | keys | = | Every tool runs as this person's own keys; immutable after mint | keys = p_k2x9qa |
| 10 | model | = | Model the holder talks to in chat | model = … |
| 11 | delegate | = | no — token cannot be narrowed and handed on | delegate = no |

Source of rows and labels: VERIFIED — src/grants.js:48-67 and the WAYS array right above them. Parser: `parseCaveat` accepts the name/op table in AXIS and the arg rule (`arg <TOOL>.<field>  =|prefix|glob|in|<=|>=  <value>`). VERIFIED — src/grants.js:71-79 and 62/74-75.

**ANDed limits; unknown is refusal.** Every known caveat must hold for a call to run; a caveat this build does not know is a refusal, never a pass. VERIFIED — src/grants.js:17-18, 72-79.

**Narrowing without asking the build.** Whoever holds a token can add a caveat and compute the next link themselves (HMAC with the signature they hold). Nobody had to ask the build. Removing or changing a caveat breaks the chain, so a token can only ever be handed on smaller. `delegate = no` ends that: a token with any caveat after it is refused. VERIFIED — src/grants.js:13-15. Implementation: `narrow(token, add[])` parses with `parseCaveat`, rejects `delegate = no` predecessors, computes `H(s, caveat)` for each new caveat. VERIFIED — src/grants.js:398-411 block (bearer/token extraction → check → narrow path).

**Holder pages.** GET /g shows what the token allows and how to use it (reading it is not a use). VERIFIED — src/grants.js:402-405 (`if (p === '/g' && m === 'GET')` → `holderPage`). Every way a token opens a tool is written out there as links and as copy-paste calls.

**Proof pages.** A token made for a task records every run under session `task:<TASK>`, and the task's proof page (`/w/<TASK>`) shows the task, its tokens, every call with exact request/answer, and every chat turn — proof is what the build captured while the work happened, not what the worker wrote afterwards. VERIFIED — src/grants.js:23-27 and the Ledger-exchange backing store (`ledger/exchanges/<call_id>.json`).

**Owner doors.** GET|POST /api/grants · GET /api/grants/axes · GET /api/grants/<id> · POST /api/grants/<id>/revoke|send · POST /api/grants/narrow · GET /api/contracts/<TOOL>. VERIFIED — src/grants.js:29-30 comment and the api route table in the same file.

## 3.4 Directory vs Ledger duality → 360° person-as-JSON view

The build's most Instagrammable idea and its most architecturally stubborn: the same object answers as Directory row, as Ledger fact, and as JSON person component.

**Directory vs Ledger.** The Directory lists every capability; the Ledger lists every call — one table now in Supabase (Hyperdrive-accelerated), with each view (`turns`, `exchanges`, `runs`, etc.) read from its rows. VERIFIED — the directory-ledger-pattern article (factual backbone; persisted in the build's article store) and src/ledger-routes.js plus the `ledgerScreen` / `ledgerAsk` natural-language query parser surface.

**Task-provenance → articles.** A Ledger materialized-path pattern places every tokened tool run and every chat turn onto the proof page of the task that owned the token, and from there onto an article. VERIFIED — src/leaddesk.js orbit comment (owner quote quoted at src/grants.js:5-6: "if I assign a task to the models I can now have all of the associated payloads from the ledger show up from that task onto an article"), implemented as `task: <id>` in src/r2-task-agent.js and surfaced via articles reads.

**360° person-as-JSON.** The identity surface (POST /api/people — add a person; text-to-sign-in; session cookies) makes a person one record per address, and that record is simultaneously: a Directory concept (the person row), a Ledger principal (every sign-in, invitation, share, key set is a Ledger row — INFERRED from src/people.js ingest pattern following src/identity.js behaviour), and a JSON widget component (facts, cards, identity — `card_fields`, `ontology`, `facts.person.*`). VERIFIED — src/identity.js and src/people.js headers and the fact that identity writes ingest to the Ledger like grants does (`deps.ingest([{event: 'person key set'}])` in src/grants.js:431 and parallel in src/identity.js).

**Ledger → article articles.** The procedural counterpart: the Ledger's own task rows can be read as the source of an article's `blocks` — "one governance-shaped Ledger view as an article's block set." INFERRED — the build's block adapters (src/blocks-adapters.js) and the claim that an article can carry a Ledger view as widgets; verified pattern-wise but not by a named repro in this packet.

## 3.5 Apple / Mac / browser / phone atoms — your terminal, browser, and phone as tools

`POST https://agent.miscsubjects.com/exec` is the Mac command runner — every CLI tool, and therefore every delegated harness's file edit, lands there and is measured on the Ledger via `env.__log` / `recorded()`. VERIFIED — src/runner.js and the agent route. The phone side is Blooio/Appple atoms: `BLOOIO_SEND_MESSAGE`, `IMSG_*`, `TWOCHAT_*` groups under Directory, with the ledger proof that a phone-side send ran and what it answered. VERIFIED — directory-language ALIASES: `imessage → ^IMSG_`, `text message → ^IMSG_,^BLOOIO`, `whatsapp → ^TWOCHAT_` (src/directory-language.js:18-42), and the Apple atom doors (`/api/surface/*`, `/api/net`, `/api/adspower`) named as container surface tools.

INFERRED — that those atom doors' specific route strings match the literal table in the brief (they do, verified by a search of `/api/surface` etc. in src/*) but counted here as INFERRED because file presence does not by itself prove route registration.

## 3.6 Invocation — invoke.js parallel model door (200 calls per round trip, no caps)

`src/invoke.js` — `MAX_CALLS = 200` — is the model's model door. One call object is the whole contract (`{key?, model?, system?, input?, inputs?, calls?, temperature?, max_tokens?, json?, timeout_ms?, n?, label?, vars?}`) and `expandSpecs` + `invokeCalls` run the whole batch in parallel in one round trip, with every request out and every reply on `env.__log` for the Ledger. Already in the prior dispatch article: 200-per-batch, uncapped model caps, gateway routing through the account's catalogue. VERIFIED — src/invoke.js:1-11, 48 (MAX_CALLS), 516-541 (invokeCalls parallel batched dispatch with Promise.all per spec), and the header note that aliases, model resolution and provider routing are faithfully ported from the old build.

Key lines quoted verbatim: VERIFIED — `MAX_CALLS = 200` (src/invoke.js:48) and the header `// The model door: one model call, or two hundred in parallel, in one round trip.` (src/invoke.js:1).

## 3.7 R2 + Hyperdrive + pg-store — INLINE_MAX 256 KiB, dedup, conditional writes

Already sketched in §2.1; expanded here because it is a distribution constraint masquerading as a storage detail.

- Document and file store is Supabase (rows in `ms.objects`, bytes in `ms.blobs` — small inline, large in Storage), answering the same calls the R2 bucket binding answered — `get, head, put, delete, list` — with the same object shape (`key, size, etag, httpEtag, uploaded, httpMetadata, customMetadata, body, text(), json(), arrayBuffer(), writeHttpMetadata()`). VERIFIED — src/pg-store.js header, lines 1-5.
- `INLINE_MAX 256 KiB` — VERIFIED — src/pg-store.js:18, `export const INLINE_MAX = 256 * 1024`. Prefetch budget for `list()` carries small bodies riding along with the page but caps total at `PREFETCH_TOTAL 16 MiB` so listing 47,000 queued file writes does not read 1.5 GB to answer nothing — that exact anti-footgun is named in the code comment. VERIFIED — src/pg-store.js:19, 192-201.
- Same bytes stored once — the blob is keyed by sha256. VERIFIED — src/pg-store.js preamble and the `sha256Hex` keying.
- Conditional writes are conditional SQL writes: `onlyIf: {etagMatches}` → `WHERE etag = $`; `etagDoesNotMatch: '*'` → `ON CONFLICT DO NOTHING`; either answers null when refused, exactly as R2 did, nothing overwritten. VERIFIED — src/pg-store.js:7-11 and 144-170. The conditional-sql claim was checked by reading the `put` method's branches, each of which returns null on refusal. VERIFIED.
- Placement near the database: `placement.region = aws:us-east-2` (Supabase region), Hyperdrive binding for Postgres. VERIFIED — wrangler.jsonc:93 (placement) and:88-90 (hyperdrive).
- 43 archived Loop pages remain the one R2 binding left, read-only, by the owner's 2026-10-04 order. VERIFIED — wrangler.jsonc:89-92.

---

# 4. The sandbox remedy thesis, explicitly

In training, give each run a scoped macaroon over the real environment — not a shadow FS, not a fake terminal — with at least:

```
delegate = no
task     = <training-task-id>
area     = <allowed prefixes, comma-separated>
uses     <= <budget>
tools    = <Directory row names or LEADS_* wildcards>
expires   < <ISO time>
```

…so even a loose model can only touch what the token allows, and every touch is a receipt.

Each line above is already enforced:

- `delegate = no` — any caveat after it makes the token invalid; holder-side narrowing ends. VERIFIED src/grants.js:66.
- `task = …` — binds every run to Ledger session `task:<id>` and to the task's proof page `/w/<id>`. VERIFIED src/grants.js:60 and 23-27.
- `area = …` — every path-bearing argument must start with one of these; shell commands are explicitly not path arguments (the comment warns: `do not give shell tools to a token you limit by area`). VERIFIED src/grants.js:61 and PATH_ARGS line 69.
- `uses <= …` — counted along the chain; a limit on the first token covers every narrower token made from it. VERIFIED src/grants.js:20-21, 59.
- `tools = …` — LEADS_* wildcard matching; optional argument rules (`arg <TOOL>.<field> op value`) for fine cuts like `arg EMAIL_SEND.to glob *@acme.com`. VERIFIED src/grants.js:56, 62-65, 74-78.
- `expires < …` — VERIFIED src/grants.js:58.

Why the real environment, not a fake one? Because the class of escape bugs that sandbox training exists to find are bugs of the runtime's edges — permissions, filesystem layout, header trust, key leakage to third parties, phase-of-flight parsing of URLs that an old build treated as hosted. A perfect fake teaches nothing. The build's own interception guarantee — `ContainerProxy` key replacement for `openrouter.ai` and `miscsubjects.com` — already proves it is possible to give a real environment that withholds the secret that matters. VERIFIED — the Proxy handlers and the wrangler `exports` field (same citations as §3.2).

Why receipts, not replayed claims? Because proof is what the build captured while the work happened (Ledger exchange rows and session-bound ingest), not what the worker wrote afterwards — and therefore the object that should carry the evidence is an article (task-provenance → article articles), not a slide. INFERRED as a packaging step; VERIFIED for the receipt substrate.

That paragraph is the single-paragraph pitch to text people. Copy it as-is.

---

# 5. Retire the `just trust the model` answer

That answer raised the sàn secure: it asks a stochastic agent to voluntarily stay in bounds against an environment that has no bounds, and then pays every time the bet loses — in tokens wasted, in context thrown away, in repository damage, in incident time. Unified dispatch already replaced part of it: the runtime projects before the model ever sees the warehouse. Macaroons finish it: delegate a small piece of the real environment, with the bounds written as caveats, and keep the receipts. The holder can narrow before handing on; nobody can keep the broader copy; a single `BUILD_KEY` rotation ends every token. VERIFIED — holding, narrowing, and revocation semantics per grants.js:10-15, 60 (task-bound), 66 (delegate no), and the build-key-rooted HMAC chain.

If a call is denied, it does not silently pass. Every caveat must hold; an unknown caveat is a refusal, never a pass. VERIFIED — grants.js:17-18. If a way is miscalled, the runner names it: `refused` + a human repair string, not a shrug. INFERRED from the runner's named refuses (`REFUSED` constant, src/runner.js) and the four-step article's measured `ran:false` repairs.

---

# 6. What ships, where, how to reach it

Live, now, behind `x-sheets-key: $MISC_SHEETS_KEY`:

- Directory: `GET /api/tools?light=1` (28 KiB projection), `GET /api/directory/query?q=…` (ranked `matched_on` / `matched_because`), `GET /api/contracts/<TOOL>` (every way for one tool).
- Ledger: `GET /api/ledger/*` (ledger as a query surface), ingest via `POST /api/ledger/ingest`, proof-carrying exchanges via task-bound grants.
- Grants: `GET /g` (holder page) / `POST /g/run` / `GET /g/run/<TOOL>` / `POST /g/mcp` / `/g/chat` / `/w/<TASK>` / narrow / revoke / send; owner doors at `/api/grants/*` and `/api/grants/axes`.
- Invocation: `POST /api/invoke-json` (alias of the Worker binding; up to 200 in one round trip, max_tokens and caps uncapped by default — INFERRED from src/invoke.js and the worker wiring).
- Containers: `POST /api/containers/run` and `/exec` (size at start), plus the model-facing tools `run_in_container` and `run_script_in_container`.
- Articles (jarticle/1): `POST /api/jarticles`, `PUT /api/jarticles/<slug>`, `PATCH /api/jarticles/<slug>` with `If-Match` (hash-conditional), `POST …/verify` (quote-found hashing), `/a/<slug>` (page), `/a/<slug>.json` (object + hash + source hashes), the three ontology links rendered as cards, and this article itself at `/a/mega-packet-unified-dispatch-sandbox`.

VERIFIED — route tables in src/r2-directory.js, src/ledger-routes.js, src/grants.js, src/invoke.js, src/r2-container.js, and src/jarticles.js (jarticleApi).

---

# 7. Call to action

If the thesis lands, the next call is short: your sandbox's real environment, behind our dispatch, one scoped token per run. Your team answers `task, area, tools, uses, expires`; every run answers with its receipts. The call before that: open the three prior articles this packet links, and try the live doors — `GET /api/tools?light=1`, `GET /api/directory/query?q=imessage`, `GET /api/grants/axes`, `POST /api/invoke-json` with two calls. If the doors behave as written, the packet's claims are checked. If they do not, they are falsified.

This article is the packet — keep it, send it. It carries its sources, each paragraph's fixes, and three linked deep-dives. The build it describes is at `misc-sheets.massoumi-cyrus.workers.dev` (Workers) and `github.com/massoumicyrus/misc-sheets` (src/*). A build key opens what a token would otherwise scope. The pitch to paste into a message is the sandbox paragraph at the top of §4.



## Facts

```json
{
  "packet": {
    "slug": "mega-packet-unified-dispatch-sandbox",
    "kind": "packet",
    "links_prior": [
      "unified-dispatch-macaroon-atoms",
      "directory-ledger-pattern",
      "dispatch-four-step-loop"
    ],
    "pitch_source_section": "§4 — the sandbox remedy thesis, explicitly",
    "pages_expected": [
      "/a/mega-packet-unified-dispatch-sandbox",
      "/a/mega-packet-unified-dispatch-sandbox.json",
      "/a/mega-packet-unified-dispatch-sandbox.md"
    ],
    "cta_close": "retire the just trust the model answer"
  },
  "dispatch": {
    "envelope": "{target, op, args|where, select, with, order, page, control, want}",
    "data_pipeline": "TARGET -> FILTER -> SELECT -> ORDER -> PAGE -> AGGREGATE -> RETURN WHAT WAS ASKED FOR",
    "exec_pipeline": "TARGET -> ARGS -> DEPEND ON -> RUN -> PROJECT -> RECEIPT",
    "catalog_full_bytes_mean": 1032,
    "catalog_count": 1340,
    "catalog_full_size_mb": "~1.38 MB",
    "catalog_full_tokens": "~374,000",
    "catalog_light_bytes": 28080,
    "catalog_light_tokens": "~7.6k",
    "catalog_light_shrink": "49x",
    "owner_quote_hash": "a15dec4f5f2d7814bfcecd102ea45af34dd00220bb482d40666afa88c6a7c2db",
    "fix_quote_hash": "410f2283731d0fda82243911016552fb830f61b1c22e5c9eeb9279191828ac15"
  },
  "grants": {
    "token_shape": "g1.<payload>.<sig>",
    "payload_shape": "{i: id, c: [caveat, ...]}",
    "chain": "s0 = HMAC(root, id); s(k) = HMAC(s(k-1), caveat k)",
    "root": "HMAC(build_key, misc-sheets grants v1)",
    "token_prefix": "g1.",
    "axes_count": 11,
    "doors": [
      "GET /g/run/<TOOL>",
      "POST /g/run",
      "POST /g/mcp",
      "/g/chat",
      "/w/<TASK>"
    ],
    "owner_doors": [
      "GET|POST /api/grants",
      "GET /api/grants/axes",
      "GET /api/grants/<id>",
      "POST /api/grants/<id>/revoke|send",
      "POST /api/grants/narrow",
      "GET /api/contracts/<TOOL>"
    ],
    "ways_count": 23,
    "path_args_list": [
      "path",
      "file",
      "file_path",
      "filepath",
      "dir",
      "directory",
      "cwd",
      "folder",
      "key",
      "prefix",
      "target_file",
      "notebook_path"
    ]
  },
  "directory": {
    "atoms": 1340,
    "ways_per_tool": 23,
    "resolver_layers": {
      "200": "sounds like",
      "300": "one typo away",
      "500": "every word somewhere",
      "600": "alias points here",
      "700": "every word in name",
      "800": "name starts with first word",
      "900": "prefix of name",
      "1000": "name is query"
    },
    "language_file": "src/directory-language.js",
    "resolve_file": "src/directory-resolve.js",
    "r2_directory": "src/r2-directory.js",
    "ways_file": "src/ways.js"
  },
  "containers": {
    "durable_objects": [
      "TaskAgent",
      "Sandbox",
      "ChatTurn",
      "CommandContainer",
      "Harness"
    ],
    "container_classes": [
      "Sandbox",
      "CommandContainer"
    ],
    "legacy_image": "Sandbox (Container class, src/r2-coding.js)",
    "do_container_image": "CommandContainer (Durable Object Container API, src/r2-container.js)",
    "interception_byHost": [
      "openrouter.ai",
      "miscsubjects.com"
    ],
    "interception_export": "exports.ContainerProxy",
    "max_instances": 40,
    "placement": "aws:us-east-2",
    "billed": "only while running"
  },
  "store": {
    "backend": "Supabase via pg-store (ms.objects + ms.blobs) over Hyperdrive",
    "INLINE_MAX": "256 KiB",
    "PREFETCH_TOTAL": "16 MiB",
    "dedup": "sha256(blob)",
    "conditional_write": "onlyIf:{etagMatches}/{etagDoesNotMatch:'*'} -> null on stale (R2 semantics over SQL ON CONFLICT / WHERE etag=)",
    "catalogue_cache": "caches: miscsubjects-catalogue-bodies (Cloudflare Cache API, 86400s)"
  },
  "invocation": {
    "file": "src/invoke.js",
    "MAX_CALLS": 200,
    "header": "The model door: one model call, or two hundred in parallel, in one round trip.",
    "caps_tag": "NO CAPS ON THE OWNER'S MODELS",
    "gateway": "Cloudflare AI Gateway (ACCOUNT 42da505c278029ba8f199892661e0035, GATEWAY default)"
  },
  "identity_person": {
    "file": "src/identity.js",
    "one_person": "one record",
    "duality": "Directory vs Ledger duality -> 360 person-as-JSON view",
    "card_fields_hint": "facts + cards + identity, card_fields at most 6"
  },
  "sandbox_remedy": {
    "template": "delegate=no, task=<id>, area=<prefixes>, uses<=<n>, tools=<rows|wildcards>, expires< <ISO>",
    "guarantee": "even a loose model can only touch what the token allows, and every touch is a receipt",
    "repetition_in_packet": "top §1 + §2 + full §4 (the pitch)"
  }
}
```

## Sources

1. [DISPATCH-ARCHITECTURE-MASTER.md §1](https://miscsubjects.com/api/file/DISPATCH-ARCHITECTURE-MASTER.md) — “the vast majority of claude's calls are around utter fucking nonsense, like wasting significant amounts of time having models make myriad bash calls to a file, then out of a file, then not respecting the file hashing” (sha256 a15dec4f5f2d7814)
2. [DISPATCH-ARCHITECTURE-MASTER.md §2 measurements (49×)](https://miscsubjects.com/api/file/DISPATCH-ARCHITECTURE-MASTER.md) — “The same catalog already has a 49× cheaper projection, shipping today.” (sha256 03e9cc4a5b90f5ac)
3. [DISPATCH-ARCHITECTURE-MASTER.md §1 fix](https://miscsubjects.com/api/file/DISPATCH-ARCHITECTURE-MASTER.md) — “The fix is not a smarter model. It is a runtime that does the mechanical part deterministically and returns a projection.” (sha256 410f2283731d0fda)
4. [src/grants.js — header](https://miscsubjects.com/api/file/src/grants.js) — “Scoped access: a token that carries its own limits, over the one dispatch authority.” (sha256 b3abf72066a90bfd)
5. [src/grants.js — chain](https://miscsubjects.com/api/file/src/grants.js) — “The signature is a chain, as in a macaroon: s0 = HMAC(root, id), then s(k) = HMAC(s(k-1), caveat k), and the token carries the last one.” (sha256 accf683043526e43)
6. [src/grants.js — narrowing](https://miscsubjects.com/api/file/src/grants.js) — “Whoever holds a token can add a caveat and compute the next link themselves (HMAC with the signature they hold): the new token is narrower and is still valid, and nobody had to ask the build.” (sha256 a45685dfadd6bd8a)
7. [src/ways.js — header](https://miscsubjects.com/api/file/src/ways.js) — “Every way a Directory tool is called, written for THIS build: each cell is the whole call, runnable as written anywhere” (sha256 87375e9ed6fdb4f2)
8. [src/ways.js — completeness](https://miscsubjects.com/api/file/src/ways.js) — “A call to an outside service goes through POST /api/invoke-json, which sends it exactly as written and records the request and the whole answer; a call to the Mac command runner is recorded by the recording door on the Mac.” (sha256 1b8bd23998995c6d)
9. [src/pg-store.js — INLINE_MAX](https://miscsubjects.com/api/file/src/pg-store.js) — “bytes up to this size live in PostgreSQL; larger bytes live in Storage” (sha256 a55fdd48602527a8)
10. [src/pg-store.js — dedup](https://miscsubjects.com/api/file/src/pg-store.js) — “The same bytes are stored once (the blob is keyed by its sha256)” (sha256 1b70e54ba0ad94f4)
11. [src/pg-store.js — conditional write](https://miscsubjects.com/api/file/src/pg-store.js) — “A CONDITIONAL WRITE IS A CONDITIONAL SQL WRITE.” (sha256 4d05d3dca863e2a2)
12. [wrangler.jsonc — name](https://miscsubjects.com/api/file/wrangler.jsonc) — “"name": "misc-sheets"” (sha256 645cce6fb7e95cd7)
13. [wrangler.jsonc — exports](https://miscsubjects.com/api/file/wrangler.jsonc) — “exports” (sha256 4b4e49dd2de5eae9)
14. [src/invoke.js — model door](https://miscsubjects.com/api/file/src/invoke.js) — “The model door: one model call, or two hundred in parallel, in one round trip.” (sha256 58525f06f186c03e)
15. [src/invoke.js — MAX_CALLS](https://miscsubjects.com/api/file/src/invoke.js) — “MAX_CALLS = 200” (sha256 a057a2b6af30c993)
16. [src/r2-container.js — header](https://miscsubjects.com/api/file/src/r2-container.js) — “A second Cloudflare container, on the Durable Object Container API” (sha256 45e393ce2c856ac7)
17. [src/r2-coding.js — header](https://miscsubjects.com/api/file/src/r2-coding.js) — “The Task agent's coding sub-agents: Cloudflare's coding-agent example” (sha256 9e9852b2c6ee3566)
18. [src/directory-language.js — header](https://miscsubjects.com/api/file/src/directory-language.js) — “The language a person speaks to this build, as data. Every word here maps to name PATTERNS” (sha256 5cf41502ccf7fb0f)
19. [src/directory-resolve.js — header](https://miscsubjects.com/api/file/src/directory-resolve.js) — “Any words at all -> the Directory rows they mean, ranked, each with the reason it matched.” (sha256 342088f3aebc8f24)
20. [src/jarticles.js — header](https://miscsubjects.com/api/file/src/jarticles.js) — “An article is one JSON object, posted whole and edited by piece.” (sha256 e8e65a140f0a06e7)
21. [src/identity.js — header](https://miscsubjects.com/api/file/src/identity.js) — “People, sign-in, devices and shared chats: one person is one record, and no person ever sees a key.” (sha256 824cd4e57efca64b)

---

**above:** [[unified-philosophy-the-unified-optimum]], [[oip]]

**below:** [[unified-dispatch-macaroon-atoms]], [[directory-ledger-pattern]], [[dispatch-four-step-loop]]

**adjacent:** [[json-articles-how-they-work]], [[object-ledger-evidence-graph-spec]]
