Posts

Showing posts from October, 2026

Dev log 11: the stop-loss that lived in RAM, and the AI that had no edge

Part 14 of the Cairn series. This one is off the main road: it is about the paper-trading stock funds that run on the same home server as the rest of this work. I asked a panel of AI models why the funds never sold their losers and how to make them profitable. The answer was not the one I expected, and part of it was my own mistake. This is all paper money, and nothing here is financial advice. The question The funds are simulated. Each one holds a basket of picks chosen by a council of AI models, and none of it involves real money. I noticed that stocks down 30 percent were still held, and stocks up a lot were never trimmed. I asked, more or less, why the AI was not smarter than a person with a stop-loss. Then I asked for a plan to make the funds as profitable as possible. What the council found I put the numbers in front of five models and asked for a diagnosis. Two findings stood out. The AI verdict has no edge. Over seven days, stocks the council called BULLISH returned an ...

Dev log 10: three AI reviewers, one repository, and the findings that were wrong

Part 13 of the Cairn series. Since Dev log 9 there have been three steps: language-neutral vectors for the Merkle proofs, an abuse catalogue with a warning in the verifier, and then the big one, a full review of everything by three different AI vendors. OpenAI read all the code. Gemini read all the documents. DeepSeek read both. This post lists what each of them found, what was real, what was wrong, and what went wrong on my side while I was doing it. These are AI reviews. They are not a professional security audit, and nothing here should be read as one. Where Dev log 9 left off Dev log 9 ended with hash-only payloads, durable opening storage, and vectors for those formats. It listed what was not built, and two items on that list were vectors for Merkle proofs and a catalogue of the ways someone could misuse the framework. Both are done now, so this post starts there. Step 1: vectors for inclusion and consistency proofs The Merkle tree in Cairn follows RFC 9162. A proof format th...

Dev log 9: keeping the payloads off the log, and proving it with vectors another implementation can run

Part 12 of the Cairn series. Dev log 8 closed the loophole for agents that never held a grant. Since then there have been four changes, each audited by Gemini and by OpenAI: invariant I4 for the require-grants switch, hash-only action payloads, durable storage for the secrets those payloads leave behind, and language-neutral test vectors for all of it. This post covers all four, every audit round, and what the audits got wrong and right. Why this round exists Until now an ACTION entry on the log pointed at its arguments and its result by hash, and the blobs behind those hashes were published with the log. That is the right default for governance, because the replay has to read proposals, votes and grants. It is a poor default for what an agent actually did. A web fetch carries a URL. A tool call carries whatever the model decided to put in it. Putting every argument and every result next to a public log is a privacy problem that nobody asked us to create. The fix has to keep two pr...

Dev log 8: closing the loophole where never having a grant meant never being checked

Part 11 of the Cairn series. Dev log 7 made the log hold agents to the grants they have. It ended by naming the gap: an agent that has never held a grant is not checked at all. This post is about closing that gap, one bug it turned up, and what two clean audits do and do not tell us. The gap After dev log 7, replay checked every action of an agent that held a grant against that grant. But "held a grant" was the trigger. An agent that had never been given one was unconstrained, because the rule that binds an agent to a grant could only start once there was a grant to be bound to. The simplest way around the whole system was never to ask for a grant. That was a sensible default while grants were new. It is a poor default for anyone who wants the log to mean "everything an agent did was inside what it was allowed to do". So the fix is not to change the default for everyone. It is to let a deployment write the stricter rule into the log itself, where every verifier ...

Dev log 7: the log now holds agents to their grants, and a plain account of what has gone wrong so far

Part 10 of the Cairn series. Dev log 6 was the OpenAI audit. This one covers what we built since, the two audits of it, and, because we were asked for it, the pains and mistakes of the project so far, not just the progress. What got built Cairn is a tamper-evident log of what AI agents were allowed to do and what they did. Until now the log could say who may delegate a capability (invariant I11: a grant handed down must be strictly narrower than the one it came from). It could not say whether an agent then stayed inside the grant it held. That gap was written into the roadmap as "I11 only as far as delegation", and it was the next thing to close. It is closed for agents that hold a grant. Replay now checks every action an agent logs against its grant: Tool. The action type must be in the grant's tool list. Host. The host the action declares must be in the grant's host list. Expiry. A grant past its not_after time permits nothing. Budget. Each action declar...

Dev log 6: we asked OpenAI to audit Cairn. It found real bugs and three things we had gotten wrong

Part 9 of the Cairn series. Dev log 5 shipped a log server and a witness. This one is about the outside review that followed: what it found, what we fixed, and what we decided not to. Every earlier audit of Cairn used Gemini, with DeepSeek on a few passes. Models from one family share blind spots, so we ran a different one. We gave gpt-5.5 the code verbatim, pasted from git diff and cat rather than retyped, in four separate passes: A: ledger, governance and the verifier. B: review, gatekeeper and providers. C: log server, witness and CI. D: every phase in the roadmap, plus every public claim in the README and docs. Each pass was asked for ranked findings, trigger conditions, tests that would pass even if the code were wrong, and documentation that overclaims. Each ran three to four minutes. We then checked every finding against the repository before changing anything. A model reviewer is a lead generator, not an oracle. Here is how the leads came out. Where it was right and...

Dev log 5: a log server you can append to, and a witness that doesn't believe it

Part 8 of the Cairn series. Two pieces landed: a server that sequences the log, and a second program that checks the server and signs only what it can verify. This one is mostly about what the tests found. Dev log 4 ended with an admission: nobody could append to a Cairn log over a network, because there was no log server. That is fixed. The second thing we said was missing, a witness on a separate machine, is also built. Neither is production software, and the end of this post lists what is still missing. The log server cairn-logd is a sequencer. It is the one process that decides the order of entries. The design rule is that nothing in it needs to be trusted, because everything it stores can be re-checked by cairn-verify . The server holds no signing keys . Validators and witnesses fetch the 81-byte checkpoint body, sign it themselves and post the signature back. The server publishes a checkpoint only once the signatures it holds pass the same check a verifier would run. Before...

Dev log 4: a gatekeeper that can say no, and a checkpoint other tools can read

Part 7 of the Cairn series. Phase 2 is partly built, a survey of similar projects changed the plan, and one external test vector is not a lot. The last dev log stopped at Phase 1: proofs, governance replay, a verifier CLI. This one covers what came after, in the order it happened, and ends with the piece we built most recently: a second way to publish a checkpoint so that other transparency-log tools can read it. Phase 2: the layer that sits in front of the agent Phase 2 added the parts that touch actual agents: a council that evaluates proposed rule changes, provider adapters, a review page, and a gatekeeper . The gatekeeper sits between an agent and its tools. For each call it checks the agent's allow list, writes an intent entry to the log, runs or refuses the call, and writes a completion entry. We keep saying what it is not, so once more: it is a policy layer in the process that calls it. It is not a sandbox . An agent that finds another way to reach a tool is not held by...