It Only Sounds Like Philosophy

Strip the idioms off everything on this site and what's left isn't an opinion. It's a pile of unglamorous decisions made earlier than you'd like, and it costs more up front than the thing it replaces.

· 15 min read

methodology verification agents developer-tools


Somebody reading this site straight through would be forgiven for thinking it has a philosophy. State is a value. The pointer is a throne. Verify by hash, not by trust. Kernel, not convention. An absence of fact must never be reported as a fact of absence.

That is a lot of aphorism for what is, underneath, a collection of boring engineering decisions. And the aphorisms are doing something real, which I will get to. But they create a specific false impression worth correcting, because it is the impression most likely to make someone try this and quit: that there is an idea here which, once understood, makes the work easier.

There isn’t. The aphorisms are indexes into engineering decisions, not substitutes for them — and the decisions are where the cost lives. Some of them are worth making early and some are premature; some become executable checks and some keep a person in the loop. That is the argument, and everything below hangs off it.

None of these moves makes the first version cheaper. Every one of them spends more effort early, on the first day, before any of the benefit arrives — in the hope of reducing a less predictable kind of effort later. That hope is the bet, and the last section of this post is about how often it loses.

Summaries travel; the work stays home

Take the shortest one. State is a value. Nine words. Read on its own it sounds like a stance you could adopt over a weekend.

Here is what it actually required in one codebase. A canonical encoding, so the same facts always produce the same bytes — which means deciding, in advance and in writing, how every type serializes, including the ones you haven’t added yet. A rule that appending a field must not change the bytes of data that never set it — stable numbered field identifiers, unset fields costing nothing — or every hash you have already handed out becomes garbage the first time the schema moves. Implementations in more than one language that must agree byte for byte, plus shared vectors that fail in CI when they don’t, because “the Rust and Go encoders agree” is not a thing you can know by reading them. And then the typed surfaces generated off that same schema — Go, TypeScript, JSON Schema, tool definitions, MCP descriptors — each of which is a place the contract can drift while every hash still matches. A generation counter. A control block. An atomic flip.

The nine words summarize that work. But summaries travel and the work stays home, so the phrase is what people meet — and compressed effort is indistinguishable from a cheap opinion when you encounter it alone.

Everything here moves effort earlier

The cost is front-loaded, and that is worth stating plainly rather than discovering.

The derived project index is the cleanest example because the comparison is so stark. Writing the index by hand: open a file, list the projects, describe the dependencies you remember, ship it in ten minutes. Deriving it: define a lock format, write the reader that extracts declarations from six different manifest formats, write the folder that turns the lock into a graph, decide what confidence each resolution method carries and write that down, write a gate that fails when the graph is not the fold of the lock, make the gate pure and offline so it means the same thing locally and in CI, and then write a second program that mutates the real graph in every way it could realistically break and confirms the gate rejects each one for the right reason.

Ten minutes against a few days, for the same page.

The same trade shows up everywhere on this site once you strip the framing off it. Content addressing is not a clever way to avoid work; it is a demand that you decide what a thing’s identity is before you write any code that names it, which is a decision most projects successfully avoid for years. A tiered verification pipeline is not a philosophy of quality; it is someone sitting down and writing out the predicates in order, including the boring ones, and accepting that the first failure short-circuits so the useful diagnostic sometimes doesn’t run. A ratcheted lint baseline is not a stance on technical debt; it is a committed file of counts and a gate that only lets them go down.

None of this is difficult in the sense of requiring insight. It is difficult in the sense of requiring you to make a dozen small decisions at the moment when you have the least information and the most desire to get on with it.

Which is a real objection and not just a complaint about discipline. Some of those decisions cannot be made well that early, because the information does not exist yet. Committing to a canonical encoding before you understand the shape of your data does not buy you determinism; it freezes a bad model and charges you for every later escape. The trade is not diligence against procrastination. It is the cost of early commitment against the cost of prolonged ambiguity, and identity and encoding rules sit on the “decide early” side of that line more often than most things do — not always, and not automatically.

The gate is cheap. Proving the gate works is not.

The single most under-sold cost in all of this. A check that passes proves only that its implemented predicate accepted this run. It does not prove that the predicate represents the property you meant to protect.

I wrote recently that a harness does not fail loudly by nature, and the evidence was my own — a property test that stayed green for the entire life of the defect it was supposedly guarding, because the bug sat upstream of everything watching. The rule was written down before the code. The rule was correctly enforced. It was simply being fed a lie.

So “we check this” only means something with a second artifact behind it: something that deliberately breaks the thing and confirms the alarm sounds, and sounds for the right reason, since a mutation caught by accident is not a mutation caught. In the index case that is an entire extra program. In the confinement case it is a test suite that refuses to accept an empty output as proof of denial and insists on the kernel’s own error, and that plants its decoy secret outside the directory the sandbox default-allows — because a decoy hidden somewhere the policy was going to permit anyway would pass every time and prove nothing.

Getting a negative test to mean something takes as much care as getting a positive one to. The principle is philosophical, often enough — decisions about what counts as evidence, and which failures are intolerable, are value judgments wearing work clothes. The bill is operational, and it is the bill I keep finding people have not been quoted.

With one limit, and it matters, since this essay is otherwise cheering for the technique. A mutation suite proves a gate is sensitive to the failures you thought to inject. It says nothing about the ones you didn’t. Every deliberately-broken graph being rejected demonstrates that the alarm is wired and sounds for the right reason; it does not demonstrate that every meaningful way the graph could be wrong is represented in the set of mutations. That is evidence that the alarm is wired to the failures you modeled — not that the model contains every failure that matters. That is the distance between “the check works” and “the property holds”.

Which leaves a residue that does not encode. Whether an abstraction is misleading, whether the model will still fit in six months, whether a rule that executes cleanly is measuring the thing anyone cared about — those resist becoming predicates, and a system that pretends otherwise has just moved its judgment somewhere less visible. Reading is one of the verifiers for that class — expensive, fallible, and not going away. Not the last word either: staged rollout, telemetry and the incident you didn’t want all supply evidence after every human has signed off. What reading is not is unfinished engineering waiting to be automated. It’s the part that stays.

Intent survives as the aphorism or not at all

Not construction. You do not need to have read Hickey to write a canonical encoder, and nobody ever shipped a lockfile because they understood epochal time.

What the vocabulary buys is recognition across distance. When you have five projects and the same shape appears in all of them — a name derived from content, one mutable pointer, everything else immutable — having a phrase for it is what lets you notice that they are one problem rather than five. That is real, and it is why the writing exists.

It buys a second thing, and this one is the reason the phrasing is ornate rather than plain. Code records what a system does. Docs record what somebody claimed about it, as of the day they wrote. Neither artifact carries intent — the invariant you were trying to hold, the thing a future change should be weighed against when the tests pass either way. Intent is exactly the residue this essay keeps circling: the property that resists being written down as a predicate. It cannot fail CI, so it has to survive some other way, and the aphorism is the nearest thing it has to an artifact. The pointer is a throne describes no function and gates no build. What it does is tell whoever touches the system next — a maintainer in two years, an agent that cannot ask a follow-up — where the danger concentrates and which property is load-bearing, which is precisely the information the diff and the README both lack.

And the ornateness is doing work in that job, not decorating it. A style guide’s “prefer immutability where practical” and state is a value contain roughly the same advice. The first gets paraphrased on its second retelling and dies into filler; “where practical” is a hole the whole rule drains out through. The second survives transmission intact, because it is strange enough that you cannot soften it without noticing you did — repeating it wrong is audible. A phrase built to be quoted is a phrase built to arrive unmodified at a reader you will never meet, and that durability is a property you select for, the same way you select a serialization format for surviving the wire. The test from the previous section still applies to every one of these sentences — an intent you cannot trace to a decision, or that no later evidence could contradict, is a vibe with good tailoring. But an intent that passes the test deserves an encoding that survives being handed around, and plain prose measurably does not.

But there is a failure mode attached, and this site has already published its own instance of it. A cache-invalidation crate was written in the language of cellular sheaves, and the design docs treated the cohomology as the moat. When someone finally asked what the coboundary operator reduced to on the inputs it actually saw, the answer was: a hash-gated reverse-dependency walk. The mathematics was real, present in the code, and completely off the path that decided anything. The write-up’s own verdict — restriction maps earned rent, cohomology did not — is the cleanest warning I can offer about my own register.

And the ending is better than a clean cautionary tale, which is why I’d rather tell it properly than use it as a stick. The sheaf vocabulary did pay off — through restriction maps, which are also sheaf machinery, and which turned out to name the thing that mattered: cache a derived view against the hash of the exact rows it reads. That shipped. It lives in the crate named after the math that failed, and the record is careful to say the failure stays failed — the audit finding that the coboundary operator was a hash-gated walk still holds, and the positive result does not revive it.

So the vocabulary was not decoration and it was not a moat. It was a map that was right about the terrain and wrong about which road you’d take. That is the most you should expect from a borrowed formalism, and it is worth something — just not the something the design docs claimed.

The wrong half did concrete harm, and naming it is what keeps this a diagnostic instead of a confession. The vocabulary hid the critical path. Anyone reading the design docs would have concluded the cache’s discriminating power came from the cohomology, and so would have looked there first to improve it, or to audit it, or to decide whether the thing was worth depending on. The actual discriminating step was a hash comparison anyone could have reviewed in a minute. It also created a moat that wasn’t there — a sense that this component was doing something hard and therefore defensible — and moats are the kind of claim nobody re-examines, because re-examining them looks like not understanding them.

Sophisticated vocabulary is a claim you have to pay for like any other. The moment it starts standing in for evidence, it is doing negative work, and it is harder to notice than a plain wrong claim because it sounds like it has already been checked.

Trace it to a decision, or it is decoration

I want to state the difference carefully, because the sharp version of it is wrong and I nearly published it.

The sharp version is: all of this has an exit code, and an opinion cannot fail CI. It is constraints compose, opinions don’t pointed at prose instead of at architecture. That is a good line and it does not survive its own examples. State is a value has no exit code. It is not a predicate at all — it is a name for a group of them: deterministic encoding, cross-language byte equivalence, a head that verifies before it is adopted, an append rule that leaves old bytes alone. The phrase chose and grouped those checks. It does not reduce to any one of them, and the fact that it doesn’t is what makes it worth having.

The defensible version is narrower. An idiom earns its place when you can trace it to something you would do differently, and to evidence that could show it was wrong. Not one command necessarily — a decision you can point at, and a way to find out you were mistaken.

That is a test “write clean code” fails here — and the reason is narrower than the one I would have given a week ago. It is not that the phrase is empty while mine are full. State is a value tells you nothing about what to build either, until somebody interprets it in a particular system. The difference is that one of them has been cashed out in this codebase and the other hasn’t. “Write clean code” cannot serve as a gate until someone says what consequences it has here and what evidence would contradict it, and that is a job nobody has done, not a property the words lack.

And the reverse holds too, which the sharp version misses. “The diff must be under ten files” runs perfectly and may still be a bad rule — someone chose ten, chose files rather than lines or call sites, and chose to treat a large mechanical rename the same as a large redesign. It executes. That does not make it correct, and being executable is not a defense of a threshold nobody has revisited. Mechanization moves an argument from prose to a config file; it does not settle it.

So the useful question about any of these sentences is not whether it compiles. It is whether you can name what you’d do differently if you believed it, and what you’d expect to see if you were wrong.

And it is often not worth it

There is a threshold, and below it every bit of this is a costume. A script you’ll run twice does not need a canonical encoding. A project index for three repositories should be hand-written, and deriving it would be a joke at your own expense. The test is local and it is an expected-value one: some software is short-lived enough, low-risk enough, or single-owner enough that the cost of drift is smaller than the cost of preventing it. The failure mode all of this machinery exists to stop is a second copy of the truth diverging from the first while nobody notices — and the question is how much drift you should expect, not whether time and multiple people are literally present. One person can update one representation and forget the other inside an afternoon. What varies is how much repetition, coordination and plain error the thing will accumulate, and whether that is worth the machinery.

The discipline earns out under three specific conditions. When the artifact outlives your memory of it. When a machine has to read it, and cannot ask a follow-up question. When more than one worker touches it, and they are not in the same room, or the same hour, or the same species.

That last one is why this stopped being optional for me, and it is not a philosophical development. Agents made the second and third conditions ordinary. A thing that reads your dependency graph and cannot ask you what you meant, working overnight, in parallel with other instances of itself, on artifacts none of them wrote — that is a workload where a hand-maintained second copy of the truth fails quickly and quietly.

So the pitch has never been that any of this is elegant. It reads elegant because prose compresses and code does not. The pitch is that where the failure mode is real, the bill arrives either way — and you get to choose whether to pay it in a week you planned or a week you didn’t.

The work is in the machinery. The vocabulary is how you notice you need it again.