on wax

THE THREE-LAYER LESSON

The VLOOKUPs were in the printed tab.

Source, analysis, presentation. Three layers that never touch. It's the first page of every data-modeling book, and I've held that line for clients since ’01. Then I built my own operating system with an agent, and broke it exactly the way I'd flag in anyone else's work. Here's the arithmetic, and the fix.

Claude Code git Markdown Python generators Architecture

#The printed tab

Every bad spreadsheet I've ever been handed breaks the same rule: somebody put the VLOOKUPs in the tab they print. Analysis and presentation, fused into one artifact. One input changes and there's no way to regenerate. Only to repair, by hand, forever. That's an architecture problem. Spreadsheets are just where it shows up first.

Over four months I built a personal operating system in markdown, run through Claude Code: job search, builds, practices, the whole life. The Source layer was right, one canonical file per fact. The Analysis layer was mostly missing. The Presentation layer was twenty-five hand-maintained index files, a weekly dashboard, and a cross-project tracker, each one restating facts that lived somewhere else.

The day it got undeniable, I closed eleven job applications in one afternoon. One ruling. It touched the eleven files that held those applications, and six more that restated them. Two of the six were generated, and corrected themselves. The other four were hand-kept, and stale before the session ended. Eleven homes, six copies, four wrong. Discipline wouldn't have saved it. That's write amplification, and it's structural.

#The fix

Why would somebody with receipts going back to ’01 suspend a model he'd trusted the whole time? Because I read the problem as new. “Context engineering,” “memory,” “AI system”: the vocabulary made it feel like a domain with its own physics, where the answer was put everything somewhere the model can see it. So every cleanup pass tightened the copies. More indexes, more cross-references, more summaries. The exact opposite of the fix. I was maintaining the caches instead of eliminating them.

The fix is the same three layers, with the new tools in their right seats:

Which collapses to one line: the agent's job is to write the generator, not to be the generator. Agents are a compiler, not a runtime. Every time I asked the agent to be the runtime, re-deriving state each session from prose instructions, I paid for a non-deterministic answer to a question that had a deterministic one.

#Try this

Pick one file you update by hand every week. A status tracker, an index, a summary tab. Ask: does this repeat, and does it accumulate state? If no, let the agent do all three layers. A one-off analysis, a draft. If yes, the agent's only job is to write the script that builds the file. Then delete the file and run the script. The mechanism runs. The agent doesn't.

#What it taught me

  1. The database era held the boundary for me, and I stopped noticing. You couldn't write to the warehouse from a dashboard. A whole career where the tooling enforced the separation, then a tool with write access to all three layers in any order, and I kept assuming the separation was handled. Agentic tooling puts you back in Excel's fused-layer world at machine speed. Excel let you make this mistake one workbook at a time. An agent makes it across twenty-five files in a session, cheerfully, while you're grateful for the help.
  2. One home isn't the same as correct. Single-home kills drift. It doesn't make the fact true. The first production run of the fixed machinery pulled a wrong transcription from the right place and carried it straight into a build. What caught it was re-reading the outside source at the moment it became load-bearing. The tooling can enforce separation. Accuracy still costs a measurement.
  3. Convert prescription into mechanism. Where a rule kept getting skipped, prose never fixed it. “Do the dedup properly,” written into a procedure, failed on the very next run. A dedup script either runs or it doesn't. That's the line I'd give a client.
  4. Git is the Source layer for history. An append-only log of every state the work has been in, with a human note on each entry saying why. So no document carries its own changelog. The doc holds what's true today. The commit message holds how it got that way.

This is the thesis, demonstrated on myself. Same questions. New tools. How do you separate source from derivation from presentation? That question didn't change because the tool became a model and the storage became markdown. It's an easy mistake to make at scale: dump context into retrieval layers, hand-maintain the summaries, call the drift a prompt problem. The fix is the layering you already know, applied the moment the tool changes.