I run business harnesses across two operations. One is business-unit forecasting and results management — around 30 scripts and 10,000 lines. The other is running a newly opened site — 12 scripts and 6,000 lines. Both were written one script at a time in dialogue with Claude Code.
After about six months of this, my honest assessment is that what determined their effectiveness was not the quality of the scripts. What worked was deciding, up front, where information lives.
There is only one principle: if the same fact lives in two places, it will diverge.
What actually diverged
During the site launch, the key register was in this state:
Two files with the same name and different contents, with the portal pointing at the older one.
Nobody acted in bad faith. Somebody took a local copy, updated that one, and only the link stayed where it was. That’s all. But key assignments have physical consequences. Affix a tag with a duplicated number to an actual key, and the cost of correction jumps. In the end, we started by consolidating back to one register.
The further you automate, the more dangerous this kind of divergence becomes. A human updating by hand would notice “hang on, this one is stale” — a script will silently keep updating the older file, correctly. A harness’s speed applies just as fully to the wrong source of truth.
For each location, decide what it holds — and what it must not
So I assigned exactly one source of truth per location. The allocation actually in use:
| Location | Canonical for | Must not hold |
|---|---|---|
HANDOFF.md | What is in motion now; the reasoning behind decisions | Permanent procedures or rules |
| Operations portal | Procedures, vendor list, key and site-access rules | Passwords, anything HR-related |
| Task management system | To-dos and the record of decisions | Drafts and raw material |
| Shared drive | Project schedule, supplies list, key register, as-built drawings | In-progress discussion |
Repository docs/ | Message drafts, approval requests, interview notes, raw material | Confirmed information cleared for the site |
The column that does the real work here is the right-hand one.
Deciding only what each location holds does not stop divergence. When people are unsure, they write into whatever is open in front of them. Without an explicit “this does not go here,” permanent rules end up buried in HANDOFF and in-progress discussion accumulates in the comment threads of a spreadsheet on the drive.
The docs/ row is deliberate in particular. It is a home for raw material and drafts, and it is never canonical for confirmed information. Confirmed information cleared for the site moves to the portal. Without that line, people on the ground have to ask a human which file to look at, every time.
Split documentation into three layers
I also fixed the documentation side into three layers.
| File | Role |
|---|---|
README.md | Spec — what it can do, what options exist |
MONTHLY_OPS.md | Procedure — when, in what order, what to check |
HANDOFF.md | Rationale and lessons — why we decided this, where we got caught |
The reason for three is that the readers and the update cadences differ. The spec changes when the code changes. The procedure changes when operations change. The rationale is appended to constantly but never overwritten. Mix them, and none of them get updated.
And this is the real backbone of running Claude Code over a long period.
Because failures and decisions are written back into HANDOFF every time, the next session doesn’t fall into the same hole. A fresh session simply reads HANDOFF before starting, with no need to re-explain how far we got last time or why the implementation looks the way it does.
In fact, of the 74 commits on the forecasting side, more than 30 were documentation only. At first this felt uncomfortable — days where no code was written. Now I count it as output. Weeks where the record is thin make the following week’s sessions measurably slower.
Hand the pitfalls to the next session
What gets written back into HANDOFF isn’t only decisions. It’s also the quirks of the systems on the other side — things you cannot learn without hitting them, and will certainly hit again.
Some of what’s recorded:
- Within a single API, naming conventions differ per endpoint (one
snake_case, anothercamelCase; reverse them and it fails with a required-field error) - Python’s standard HTTP client gets blocked with a 403 by the CDN, while
curlsends the identical request through - The wrong auth header type returns 401; the right one can still 403 for unrelated reasons
- Externally shared channels only permit creating a draft; sending requires human action
- The corporate e-commerce portal’s payment method is invoice-based, and writing “credit” on the approval request gets it bounced
- Don’t judge availability from the groupware calendar alone; the real bookings live in another calendar system, and it can be full while showing free
None of this is in official documentation. It is knowledge that exists only in the hands of someone who has hit it once, which is exactly why writing it back is worth doing. The faster AI writes your code, the more the bottleneck shifts to whether you know how the other system actually behaves.
”I said / you didn’t” turned out to be a source-of-truth problem too
Deciding sources of truth wasn’t only about documentation.
For messages to the site, I switched to writing the text to a file before sending it. All that changed was no longer typing and sending on the spot, but nine days produced 59 message drafts in the repository. What was communicated when became traceable, and “I said / you didn’t” disappeared structurally.
This is the same principle applied. With the fact living in both the chat history and a file, searchability and retention differ, so they diverge. The file is canonical for what was sent; chat is treated as the delivery mechanism.
As a side effect, dropping the text into a file before sending noticeably improved the writing. Typing on the spot, you inevitably skip establishing shared context.
The order to implement in
If you’re starting the same thing, the order goes like this.
- Enumerate the locations. List how many places the same fact currently lives in. It is usually more than you’d guess
- Write the “must not hold” for each location. Decide this before deciding what it holds
- Consolidate the duplicates into one. Including repointing the links. Skip that step and it reverts
- Create HANDOFF and start writing decisions back. There’s no payoff in the first week, but the speed of your sessions a month out is different
- Then write the harnesses. Automate before the sources of truth are settled, and what you’ve built is a mechanism for updating the wrong place at high speed
The temptation to reverse the order is understandable — writing scripts is more satisfying. But having run two operations this way, my conclusion is that this side is probably what mattered more.
Whether to start by sorting out information design, or to build one harness first to get a feel for it, depends on the organization. I’m happy to go into specifics in a conversation.