A context system for a security project
The same build method, taken into a project whose whole job is security. A second layer of docs, one home for every fact, a few honesty rules, and a system that caught its own drift.
Part of my methodology series, the security case study. If you have not read the overview, start there; this piece takes the method into a live security project.
The method was built with ordinary software projects in mind: a context system that holds the decisions, a build graph, a progress log, a loop that lets an agent build for hours without drifting. Then I pointed it at Libero, which is not an ordinary project. Libero is a security effort against VolleyPacket, a live product serving real users. Its whole job is to find where the system could be broken, and to close those gaps before anyone else finds them.
So the interesting question was not “does the method work here.” It was “what does the method have to change when the project is about security, and the target is live.”
Two things change when the work is security
First, the context system holds something dangerous. On a normal project the docs describe what to build. On a security project they describe how the thing could be attacked. That is genuinely useful to write down, and genuinely a problem to store, because the same notes that make the work legible would, in the wrong hands, be a map of the live system’s weak points.
Second, the output has to be publishable without publishing the attack surface. I wanted to show the work, a real before and after, as proof. But the proof cannot include the specifics, because the specifics are exactly what an attacker would want. So the sanitized result is public: attacks landing dropped from 33 of 53 before hardening to 0 of 55 after, across sixteen suites. The report is here. Everything you are about to read is the method. None of it is the how.
A second layer, not a second copy
VolleyPacket already had a context system for the product itself: the docs that say how the app is built, what it must never do, how the code is written. The security work did not fork that or restate it. It added a second layer beside it, a set of security docs that link out to the product docs for “how the app works” and own “the security work and the law for handling sensitive material.”
That split carried a precedence rule. On how the product works, the product docs win. On the security work, the security layer wins, and one named document is the authority for handling the sensitive material. So the two systems never argue, and neither has to repeat the other. The security layer is a lens on the product, not a copy of it.
One home for every fact
The move that made the whole thing hold together is strict and a little boring: every fact has exactly one home, and everything else points at it. The risk model is the only place a severity is set. One document is the only place the handling rules live. The record of what is fixed pulls its severity from the risk model and its proof from the test design; it never re-decides either.
The payoff is that a thing cannot be rated High in one file and Medium in another. “Controlled” means the same thing on every page, because it is defined on one page. When nine interlocking documents each own one thing, they stay consistent without anyone policing them by hand.
The rules that kept it honest
A few rules did the real work, and they are the same shape as the “things that must never be true” from an earlier writeup:
- Verify before asserting. No risk is rated and no fix is claimed without evidence in the code, by file and line, and a test that reproduces it. Ratings moved in both directions because of this, some up, some down, some quietly lowered once a test showed the real behavior. A rating with no test behind it is a guess wearing a number.
- A control with no test is aspirational. A gap counts as closed only when its test suite is green at the threshold and the fix has actually landed, not when someone believes it is handled.
- Change the source first, then ripple, then log, in the same session. When a decision moved, the foundation document moved first, every doc that referenced it was brought in line, and a log entry was written before stopping. Two documents were never allowed to disagree, not even overnight.
- A security fix that breaks the product’s own rules is the next incident, not a fix. The product’s invariants were hard constraints on every change, never something a fix got to trade away.
The order came from the graph
As in any project on this method, a dependency map decided what to build, not a checklist. The keystone was the hardest, most load bearing risk. Its test proved the gap was real, the fix landed on a branch that never shipped on its own, the test went from failing to passing, and a pipeline gate now blocks the gap from coming back. Every later check was the same shape aimed at a different target, so once the keystone was done the rest fanned out cheaply. The graph turned “a long list of scary things” into “one proven pattern, applied again and again.”
The system caught its own drift
The best moment was a mistake the method turned into a save. After every fix had shipped, the ledger still said none had landed, because the shipping ran ahead of the writing. The drift rule exists for exactly this. A deliberate reconcile pass walked the docs back to reality: the ledger corrected each status, the dependency map gained a “where things actually stand” section, the log recorded the correction. The system noticed it had drifted from the truth and pulled itself back. A pile of loose notes never does that; it just quietly lies to the next person who reads it.
Where a security.md finally earns its keep
In the context system writeup I said most projects do not need a dedicated security file, that the rules belong inside the files you already read while building. Libero is the exception that proves the shape of the rule. Here the security surface is the project, so a general architecture file would bury the thing that matters most under the thing that matters least. That is exactly the condition where a separate file stops being clutter and becomes the spine. The judgment did not change; the project did.
The lesson
A good way of working should bend to a harder problem without breaking. The context system was built for software, and a security project stretched it in two places: the notes got more dangerous to store, and the results got more dangerous to publish. Both were handled by the instinct the method already had, keep the sensitive thing in one controlled place, and make the safe version the one that leaves the building. Everything else, the memory outside the chat, the graph, the ledger, one home for every fact, carried straight over. And in the security setting the discipline paid for itself: honest severities, real before and after proof, and a set of working docs that doubled as the report.
If you want the general method without the security specifics, start with the overview. If you want the proof it produced real hardening on a live system, the Libero report is the receipt.