Standalone Agent — architecture & the decisions behind it
A gated, jailed coding agent that turns a spreadsheet into working software — and then looks at what it built to check that it works. Lifted out of a shipped product, hosted as a site.
Where this came from, and why it exists as its own thing.
CRAWLI ONE shipped first
A desktop product that normalises AI conversation history across platforms with mutually incompatible export formats — schema, ingest, storage, search and UI, shipped to Early Access with a full commercial pipeline: Cloudflare Worker, Stripe checkout and webhooks, license mint / redeem / verify / recovery, R2 signed delivery, KV state, admin and killswitch.
The decisionThe most valuable part was the agent inside it, not the app around it. So I lifted the agent out as its own product rather than growing features onto the shell it happened to be born in.
Then: make it something you can send
An installer is a thing people agree to later. A link is a thing they use now. That single sentence is why the last stretch of this work was hosting, not features.
02Testing architecture — the part I'd lead with
A passing suite answers one question out of four. Each of the others needed its own instrument.
Four questions, four instruments
Does it pass? — three suites.
Can each guard actually FAIL? — a seam harness: every guard is removed, the suite must go RED, and the file is restored byte-identically and verified by SHA. 65 guards
Is there a guard nobody listed? — a coverage pass over every containment site. It found 11 unproven jails the first time it ran.
Which lanes did this change invalidate? — a test gate: 8 lanes, each fingerprinted by SHA-256 over the content of every file it covers.
Why content, not timestampsThe seam harness rewrites source files and restores them byte-identically, so every seamed file has a fresh mtime after a run. An mtime gate reports the whole tree stale five minutes after proving it green — and a gate that cries stale is a gate people learn to skip.
What it actually caught real
A script served as HTML behind a 200. The page broke; every status code was green. Found by driving a real browser and reading the exception.
My own test had the same bug — it searched for a string that also appeared in a comment inside the fallback HTML. A test that confirmed itself.
The harness refused to run on an ambiguous tree rather than reporting a maybe.
A composer with a valid layout box, clipped out of the paint by an ancestor's overflow:hidden — visible in screenshots, impossible to click. Caught by document.elementFromPoint at the element's own centre returning the root div.
The ruleA guard that has never gone red for a real reason is unproven. Prove the test by breaking the code, not by reading it.
03The CSV synthesizer
Tokenizer → precedence-climbing parser → AST → semantic role. It recovers the system the spreadsheet was describing.
11,463
formulas across 400 real workbooks I did not write
100.0%
parsed (11,460) — the 3 failures were one documented feature
75.5%
semantic role recovered; it refuses to guess on the rest
0
LLM calls in the lift — fully deterministic
The decisions that mattered
Computed fields, validation rules, state machines, foreign keys and rollups are recovered as kinds, not as text. An identical IF shape separates into a state machine or a validation rule by its role — and asks when it is genuinely ambiguous.
The refusal is the productA migration tool that guesses produces software that is confidently wrong. Open questions travel into the output as questions.
A real defect this caught: (F2-H2)/F2*100 was emitted without parentheses — a different expression, and a confidently wrong number in every migrated row. Now precedence-preserving, pinned by a round-trip test that re-parses and re-evaluates.
04Tools built because a gap appeared
Agentic Vision — the one to highlight
Pure CDP, so it drives any WebView, not one app. Perceive → act → verify. It is what lets the agent see its own work instead of reporting on it.
What it foundAn XSS hole where formula text reached an attribute unescaped — on a product whose input is untrusted spreadsheets by definition. Reading the code did not find it; looking at the rendered page did.
Two instrument facts learned by running it: screen-text reads text nodes, so a form-heavy page reads as empty; and it returns rendered text including CSS text-transform, so asserting on DOM casing generates false negatives.
Red-team flow, WORKFLOW-KIT, HOW-WE-WORK doctrine, not a button
The red-team practice is real and the findings are real — seven defects in my own gate, each reproduced with a concrete attack, each written down rather than shipped past. The strongest is an authority store that was not tamper-evident: deleting one line from a file, with no key, brought a revoked permission back while the audit chain still reported intact.
HOW-WE-WORK is 32 sections where every rule names the incident that produced it. I don't write rules; I write down what went wrong and make it mechanical.
05Why Docker and Cloudflare Containers
A Worker cannot run this — and that is the interesting part
V8 isolates have no process spawn, no filesystem and no CDP. Compiled to run there, the jail, the child agents and the agent's own eyes all evaporate. The code would build and every guarantee would be gone.
SoThe Worker is the front door; the container is the product. One instance, because isolation is already solved inside it: one visitor is one install — own Ed25519 identity, own signed mandates, own hash-chained ledger, own jailed workspace. Sharding per visitor would buy nothing the jail does not already give, at N times the cost.
Decisions inside the image
Same Rust source as the desktop build, compiled for Linux — not a port, not a reimplementation. --locked so the image cannot silently drift a dependency.
Chromium is not optional. The agent verifying its own output is a pillar; without a browser it goes dark.
TLS terminates in JS, not Rust. The agent speaks http:// only and has always reached models through a local daemon. Rather than change the agent's proven inference path, the container does what the daemon did. The key never reaches the agent — it talks to loopback.
tini as PID 1, because Chromium forks a helper tree and unreaped zombies read as a host slowly getting sick.
GeneralisesThis is the pattern for putting any real tool behind a URL for a team: internal platforms, AI integrations against internal systems, per-user isolation inherited from the jail rather than from new multi-tenant code.
The finding that cost three deploys worth telling
A container's environment is fixed at process start. Deploying a new version updates the version, not the running instance — so a secret added after boot is correct, visible to the Worker, and invisible inside the container until the instance cycles.
How it was foundA route that reported secret presence and length only, never the value. Echoing a key to diagnose a key is how the key reaches a log. It answered in one request, then was removed rather than left behind a flag.
06FolioFlex — the secondary build
A smaller system, same discipline
Worker + Pages. The model key is an encrypted secret, never a vars entry and never a VITE_ variable — that prefix compiles a key into the client bundle, a mistake this codebase had already paid for once.
The part I would point atThe deploy script fails the deploy if the key appears in the built bundle. A rule nobody has to remember is a rule that holds.
It also carries the voice work: speech driven by the utterance's own onend, never a timer. A timer drifts per voice, per rate and per machine — and when it drifts, the UI keeps animating after the audio has stopped.
07Where this goes
Bespoke operating systems
I have built the substrate, the gate, the tooling and the doctrine. The agent is one product on top of it; the same foundation carries an OS tailored to a specific domain — its own boot identity, its own permission model, its own tools, with the enforcement in the substrate rather than in prompts.
The through-lineSystems that check themselves. Every mechanism here exists because something broke and I made it impossible to break the same way twice.