Skip to main content

The Part of Your App You Can Hand to Something You Don't Trust

CJ Cummings
Co-founder & CEO, Limitr

Somewhere in the last year, "an AI agent will just edit the file directly" stopped being a hypothetical and became a default workflow. Point a coding agent at a config, a document, a state blob — and it reads, edits, and writes back, no UI in between.

That's genuinely useful. It's also a trust problem most formats were never built to answer.

The question nobody's format answers

When something you don't fully control — an agent, a plugin, logic that arrived over the wire — edits your app's state directly, two questions come up immediately:

  1. Can it leave the data in a broken state? Most formats are just structure. JSON doesn't know what a valid version of itself looks like. Validation lives somewhere else — a schema file, a Zod/Pydantic model, a check the host app runs after the fact. The data itself has no opinion.
  2. Can it reach further than it should? If the edit includes logic — a new field, a new rule, a new function — what stops that logic from touching the filesystem, the network, anything else on the machine, the moment it runs?

Most of the systems solving "one portable file, edited by anything" today answer both by widening the trust boundary instead of narrowing it: bundle the whole app, sign the release, ship a rollback plan if something goes wrong. That's a reasonable answer. It's also a lot of infrastructure just to make an edit safe to accept.

A narrower answer

Stof takes the opposite approach: instead of trusting the whole bundle, make the data the thing that can't misbehave.

A Stof document validates itself — fields carry their types and rules inline, so there's no separate schema to drift out of sync with the data it describes:

#[type]
Person: {
#[schema((target_val: str): bool => target_val.len() > 1)]
str name: "Ada"

#[schema((target_val: int): bool => target_val >= 0)]
int age: 30

fn greet() -> str {
`Hello, ${self.name}!`
}
}

And it's sandboxed by default. A document can only touch what you explicitly hand it:

const doc = new StofDoc();

// nothing is reachable from inside the document until you grant it
doc.lib('Http', 'fetch', async (url: string) => {
const res = await fetch(url);
return await res.json();
});

doc.parse(`
fn main() {
const data = await Http.fetch("https://api.example.com/data");
...
const valid = <Person>.schemafy(person);
}
`);

await doc.call('main');

If that fetch capability was never granted, that function simply can't reach the network — not because of a permissions check bolted on afterward, but because the document has nothing to call. Logic that arrives from an agent, a tool result, or another service can be parsed straight into a running document and invoked immediately, and the blast radius of "what if this is wrong or malicious" is defined by what you handed it, not by how much you trust the source.

Not the container. The part inside it you can trust.

It's tempting to read "portable, sandboxed, single unit" and reach for the bigger idea — what if the whole app lived inside a Stof file? UI, rendering, the works?

We don't think that's the right shape, and it's worth saying why. The moment a document needs to render pixels or drive a UI, it needs broad, standing access to do its job — and at that point you're back to trusting the whole bundle, the exact problem sandboxing was supposed to avoid. You'd end up rebuilding the "sign it and hope" model other single-file systems already use, just with different syntax.

The useful version is narrower: the UI stays outside, doing what it's good at — drawing things. The state, the rules, and what's allowed to happen live in a Stof document, because that's the one part of the system that's safe to hand to something you don't fully trust. An agent can edit it directly. A plugin can extend it at runtime. None of it requires you to trust the editor — only to trust that the document can't be made invalid, and can't reach further than you allowed.

That's the actual shape of the moment we're in: more and more of an application's state is being edited by something other than the application itself. The question isn't how to make the whole app safe to hand over. It's which part of it should be.