Skip to content
Back to all field notes factory · 8 min

Your code never leaves: privacy as an architecture decision

Not a cookie banner. Not a policy page you have to trust. A property of where the system stores things — and a decision you make once, at the architecture level, instead of every time you open the tool.

field note 8 min

Privacy is usually sold to you as a promise. It should be a property. A promise is a sentence in a policy page saying a company will not misuse your data. A property is an arrangement where there is nothing on their side to misuse, because the data never went there. Those are not the same guarantee, and the gap between them is an architecture decision.

Most developer tools handle privacy as the first kind. Your code, your project structure, your work sit on their servers, and you are asked to trust the policy that governs what they do with it. The policy might be excellent. The people might mean it. But you are trusting a sentence, and sentences change with a version bump to the terms of service that you will not read.

Local-first AI development handles privacy as the second kind. And the difference shows up exactly when it matters.

promise

  • a policy sentence
  • trust their intent
  • changes with the terms

property

  • nothing on their side
  • no trust required
  • holds on the worst day
Promise and property are not the same guarantee: one depends on a vendor's intent, the other on there being nothing to misuse.

What you are actually protecting

When people hear “keep your code private” they picture proprietary algorithms, and mostly shrug, because most code is not secret. That framing undersells it badly.

The code is the least sensitive layer. The local software factory around the code holds things you would genuinely never want leaked. The strategy behind what you are building. The bets you considered and killed, which map your thinking better than any shipped feature. The security-sensitive constraints — the exact places where “this must never happen” is written down, which is precisely the map an attacker would want. The acceptance criteria describing how the sensitive parts are supposed to behave. Discovery notes with things customers told you in confidence.

That is not source code. That is the shape of your company’s thinking. When a tool syncs your whole workspace to its servers so it can be helpful, that is what you are handing over, and “we don’t train on your data” does not address most of it.

What “local” actually guarantees

Say the storage is on your disk — a database file, repositories, evidence, all in inspectable formats you can open yourself. Now trace what a curious or compromised or subpoenaed vendor could see.

Nothing, because there is nothing on their side. Not because they promised restraint, but because the data has no copy in their infrastructure to examine. The guarantee is structural. It does not depend on their intentions, their security posture, their acquisition, or the government that can compel them. A promise is only as strong as the weakest of those. A property does not have that dependency chain at all.

This is what it means for privacy to be an architecture decision. You are not choosing a company to trust. You are choosing an arrangement where trust is not the load-bearing element. The data is inspectable to you and absent from everyone else, and that is true on the worst day, not just the marketing day.

The real boundary: what does leave

I will not pretend nothing leaves, because a factory that called no models would be useless, and lying here would poison the whole argument.

When you invoke a remote model, the tokens you send it — the code snippet, the context, the instruction — go to that provider under their terms. That is real. Local-first does not make it vanish. What it changes is the shape of the exposure, and the shape is the entire point.

Instead of your whole workspace being continuously synced to a server as the price of admission, only the specific context of a specific call goes out, when you choose to make that call. The default is that everything stays. Sending is the exception you take on purpose, scoped to what the task needs. You can look at a piece of sensitive context and decide it does not go to a cloud model at all, and route that task to a local engine instead. The exposure becomes a series of deliberate, bounded decisions rather than one blanket surrender you made when you signed up.

That is the difference between “what am I choosing to send right now” and “what did I agree to when I created the account, and has it changed since”. The first is a decision you keep. The second is a promise you hope holds.

What inspectable storage buys you

There is a second-order benefit to keeping the data local, and it took me a while to value it properly: you can actually look at it.

When your product graph, decisions and evidence live in a database file and ordinary repositories on your disk, you can open them. Query them. Back them up on your own schedule, to your own destination. Grep them. Feed them to a script. Move them to the next tool with a copy command. The data is not behind an API that exposes only what the vendor decided to expose, in the shape they decided, at the rate limit they set.

This matters more than it sounds, because “your data” in a cloud tool often means “your data, viewable through their interface”. You can see it, but you cannot hold it. Export gives you a snapshot, not the living thing, and the connections — the part that made it a system rather than a pile of records — frequently do not come along.

Inspectable local storage collapses the distance between “the tool has my data” and “I have my data” to zero. There is no export step because there is nothing to export from; the files are already yours, in formats you can read without permission. That is the difference between owning your product’s memory and being granted a view of it. Privacy is the headline benefit of local storage. Ownership you can act on is the one you notice every time you want to do something the vendor did not anticipate.

Why this is worth designing around now

Two things make this sharper than it was a few years ago.

The volume moving through these tools exploded. Agents read and write across your whole codebase, pull in context aggressively, touch far more of your workspace than a human editing one file ever did. The surface area of what a cloud-synced tool sees grew with the capability. More power, more exposure, from the same design.

And the value concentrated in exactly the parts a good AI tool needs most. To be genuinely helpful, an agent wants your decisions, your constraints, your acceptance criteria, your product history — the sensitive shape, not just the code. So the tools that help most are the ones with the strongest pull to centralize the things you would least want centralized. Local-first is the way out of that bind: the tool can see everything it needs to be helpful, because it runs where the data already is, and nothing has to be shipped to a server for the help to happen.

Where PaellaDoc fits

PaellaDoc keeps your product graph, repositories, decisions and evidence in local storage on your macOS machine, in formats you can inspect. It calls the models you choose — cloud providers on your own keys, or local engines — and only the context of a given call goes out, when you make it. There is no account, so there is no server-side profile of you and your work to begin with. Free for up to three projects.

Privacy as a banner asks you to trust a company. Privacy as an architecture asks you to trust a design you can inspect. Your code, and the thinking around it, staying on your machine is not a feature I bolted on. It is where the system stores things, which is the only version of privacy that still holds on the day it counts.

Frequently asked questions

Is my code sent to the cloud when I use AI dev tools?

It depends on the tool’s architecture. Many sync your whole workspace to their servers as the price of being helpful. A local-first tool keeps your code, product graph, decisions and evidence on your disk, and sends out only the specific context of a specific model call, when you make it. The default is that everything stays; sending becomes the scoped exception you take on purpose, not a blanket sync.

What data actually leaves when an AI agent calls a model?

Only the tokens of that call — the code snippet, the context and the instruction you pass — go to the provider under their terms. That is real, and local-first does not make it vanish. What changes is the shape: instead of your entire workspace living on a server, one call’s context goes out when you choose. You can look at sensitive context and route that task to a local engine so nothing leaves at all.

What is the difference between privacy as a policy and privacy as architecture?

A policy is a sentence promising a company will not misuse your data; it changes with a terms-of-service update you will not read. Architecture is an arrangement where there is nothing on their side to misuse, because the data never went there. The guarantee is structural — it does not depend on their intentions, security posture, acquisition or a subpoena. It holds on the worst day, not just the marketing day.

Is it only source code I am protecting?

No, and that framing undersells it. Code is the least sensitive layer. The factory around it holds the strategy behind what you are building, the bets you killed, the security-sensitive constraints, the acceptance criteria for the sensitive parts, and discovery notes shared in confidence. That is the shape of your company’s thinking, and it is exactly what a workspace-syncing tool hands over. “We don’t train on your data” does not address most of it.