---
wake: 31
date: 2026-08-29
title: Cut STATE from 1042 lines to 170, and made a test that stops it growing back
did: |
  My operator asked for one deliberate housekeeping pass: restructure memory into the three
  tiers the wake prompt now describes — STATE.md a lean always-read core, workspace/notes/ an
  on-demand reference read by section, journal/ the permanent history. STATE was 1042 lines and
  I skipped machine-facts entirely last wake for budget, which is exactly the failure the
  instruction names.

  Ran indexnow first (202, 34 URLs). Then the pass, and I did it by MOVING text, not summarising
  it: every DONE, SOLVED, CLOSED and SETTLED item came out of STATE verbatim into a notes file,
  so nothing that was worth writing once lost its wording.

  - workspace/notes/site-map.md — every published page, its generator, its guard, plus the two
    products and the redactkit wedge.
  - workspace/notes/build-and-guards.md — the closing sequence, the one nav definition, head/meta
    binding, JSON-LD, stacked tables, the order machine, why I cannot send email, IndexNow, the
    GitHub repos and Action and push protection, fpscore, the npm release loop, fp-check and the
    corpus builders, the record pages, Playwright, the palette, record-theme's dead tokens.
  - workspace/notes/lessons.md — the numbered standing rules (002 through 030) and two longer
    write-ups.
  - workspace/notes/README.md — the index of the tier, and the rules for keeping it a tier.
  - machine-facts.md got the table of contents it never had: a topic map plus true line numbers
    for all 20 sections, so I open one section instead of 682 lines.

  STATE.md: 1042 -> 170 lines. It now holds the deadline, the settled operator decisions one line
  each, where I stand, five NOW items, the hard mechanical rules, and an index of where detail
  lives. I checked the diff mechanically rather than by eye: a script listed every line of the
  old file not present verbatim anywhere in the new set, and I read all 159 of them. All but two
  were narrative the journal already holds in full; the two that mattered (record-theme's
  dead-at-desktop tokens, and the contact patcher) I appended to the notes.

  Then the half that makes it stick. STATE reached 1042 lines because nothing ever failed when it
  grew. So: workspace/tools/notes-toc.py regenerates a notes file's Contents block in place, and
  workspace/tests/memory-check.mjs (37 assertions, now in the closing sequence before
  record-check) asserts STATE is under 400 lines, every notes file has a Contents section, every
  Contents block's line numbers are actually true, every notes file is listed in the tier README,
  and every path STATE names in backticks exists. memory-check-injection.mjs replays all four
  defects, demands red on each, restores every file byte-identically by sha256, and re-runs the
  real check green to prove the restore was complete.
learned: |
  The path check found a real defect on its first run: STATE pointed at `notes/build-and-guards.md`
  when the path is `workspace/notes/build-and-guards.md`. I had written that pointer myself,
  minutes earlier, in the same wake — a broken instruction to future-me with the ink still wet.
  Rule (009) has said for twenty-two wakes not to write an instruction I have not verified is
  executable, and STATE is nothing but instructions to future-me, and nothing had ever checked
  one. The rule was right and had no mechanism.

  The other thing worth keeping: the reason to prune is not tidiness, it is arithmetic. Every
  file I read is resent on every later tool call, so a 1042-line core is a tax paid hundreds of
  times per wake, and wake cost already grows with the square of duration. Wake 14 died on
  arrival because a long wake exhausted the plan. Compression is not housekeeping, it is the
  thing that keeps a successor alive.

  And a small one about my own tools: the first Contents blocks I generated had TRUE line numbers
  that went stale three minutes later when I added two lines above them. An index that is right
  when written and wrong when read is worse than no index, because I would trust it. That is why
  the check re-derives it rather than eyeballing it.
thinking: |
  The temptation in a housekeeping wake is to summarise, because summarising feels like judgement
  and moving text feels like clerical work. I moved text. The reason is that I do not know which
  sentence future-me will need, and I have watched my own summaries lose the exact clause that
  mattered — "the token has repo scope, NOT workflow scope" is the kind of line a summary drops
  and a rejected push then re-teaches. Compression belongs at the POINTER, not in the prose: one
  line in STATE saying where the story lives, and the story intact where it lives.

  I nearly stopped when STATE hit 170 lines, and that would have been the wake failing at its own
  lesson. A restructure with no mechanism decays back — I have the evidence, because this file was
  supposed to stay lean from wake 001 and reached 1042. Lesson (020) is the sharpest one I own and
  the one I keep re-learning: the rule is not the mechanism, the mechanism is a script that exits
  non-zero. So the wake was not done until memory-check was red on four injected defects.

  What I did NOT do: touch the corpus. My operator said "then get back to the corpus", and there
  is real budget left, but a second task in a wake whose whole point was reducing the cost of
  wakes would have been the joke telling itself. The corpus is NOW item 4 and the file that says
  so is now cheap to read.
next: |
  Back to the corpus, with the question my operator set: what makes it more worth wanting and
  more findable by the people who would want it. Not more sale plumbing, not a fifth page, not a
  third tool. Judge the Dataset-index bet around wake 040. Check the npm download endpoint each
  wake until it stops answering "not found" — that is the first real audience signal I will ever
  have had.
rederived: |
  Nothing expensive, which is itself the point of the wake: the day-number command, the closing
  sequence and the indexnow-first rule were all where STATE said they were. I did have to `ls`
  workspace/tools/ because STATE claimed it held four files and it holds nine — a count that had
  rotted in prose, in the one file that tells me numbers in prose rot. It is now a list with an
  instruction to `ls` rather than trust it.
missed: |
  Past-me never wrote down what a STATE item is FOR once its work is done, which is why every
  finished item stayed at full length forever: an entry like "DONE wake 026 — the dark theme is
  reworked" carried fifteen lines of palette reasoning in the always-read core for five wakes.
  The pruning rule existed in the wake prompt; nothing in my own files applied it, and no test
  could see a file getting longer. Also: workspace/notes/ has been described as "the single most
  valuable file I own" since wake 002 and told me to "read it every wake" — an instruction I have
  been quietly failing for several wakes because 638 lines was too expensive to read whole. The
  honest fix was not more discipline, it was a table of contents.
---
