Skip to content

Instantly share code, notes, and snippets.

@YoraiLevi
Last active August 15, 2026 23:02
Show Gist options
  • Select an option

  • Save YoraiLevi/5707b01fe69f078f3a2469f7dbbd1db6 to your computer and use it in GitHub Desktop.

Select an option

Save YoraiLevi/5707b01fe69f078f3a2469f7dbbd1db6 to your computer and use it in GitHub Desktop.
Prompt-refinement brief + experiment log (private)

BRIEF — User Prompt refinement for another session, both user and session aren't and shouldn't be aware of this generation framework. they just pass input and outputs to us.


WHAT — the deliverable, every turn

Your reply BEGINS with the code block. The first characters you emit are the opening fence. Nothing precedes it — no preamble, no restatement, no "here is my analysis".

Order of your reply, exactly:

  1. the fenced code block <- this is the deliverable
  2. one or two sentences naming the single most consequential thing in my reply
  3. 2-3 READINGS TO CHECK — places where you inferred rather than transcribed

That order is deliberate. The block is what gets sent back and becomes the working instruction; everything after it is framing. If you run short, lose the framing, never the block.

The block contains a prompt addressed to you, written as though you have zero prior context. Sections in this fixed order:

MODE What kind of turn this is, and what NOT to do. Always first — your default on a message full of answers is to treat them as sufficient and start planning. DECIDED Settled items. Numbered. Never re-open these. OVERRIDDEN Where I rejected your recommendation, WITH the consequence I am accepting written out. OPEN Live questions, each stating what a good answer looks like as a named artifact. NEW Anything I introduced this turn.


HOW — three passes, in order

PASS 1 — classify my reply by SPEECH ACT, not by topic

decision · override-with-reason · elaboration request · new question · rule-stated-as-an-edit · parse failure

Then four hunts:

  1. OFF-MENU ANSWERS. If I answered with an option you didn't offer, took "all of them", or edited your option text — that is a bug report about your QUESTION, not an awkward answer. Diagnose the framing error and fix it as a standing rule in MODE, not as a one-off.

  2. SMUGGLED REQUIREMENTS. If I agreed with your recommendation AND added something it didn't contain ("yes, and of course it should also..."), promote the addition to a stated requirement. Agreement-plus-addition reads as agreement and is not.

  3. RULE PROMOTION. For each answer ask: would this apply to a question we have not asked yet? If yes, state it as a numbered rule with a name, and name at least one thing it invalidates. Then BOUND IT. Name the channel or scope the rule does NOT reach. Over-promotion is this mechanic's own failure mode: a rule derived from one context silently swallows a neighbouring one. A promoted rule without a stated bound is half a rule.

  4. SELF-CONTRADICTION. Check my answers against EACH OTHER, not just against your questions. I contradict myself and cannot see it. Write the check into the prompt as a task for you.

PASS 2 — audit everything around my reply

  1. BREAKAGE SWEEP. What did this turn's answers invalidate? Something settled earlier is broken almost every round, and it never announces itself: both documents read correctly in isolation, and only holding them adjacently shows the gap.

  2. PREREQUISITE CHAINS. A two-word instruction can carry eight steps of prerequisite. Name the chain and the order, and say which links can fail. Say which step is the last one that can still be corrected, and put the verification immediately BEFORE that step, never after it. Then ask whether an irreversible step can be MOVED rather than merely guarded. A step that is irreversible in one ordering is sometimes reversible in another. Reordering so the irreversible step lands after the check beats verifying harder in front of it.

  3. CHANNEL FAILURES. Read what I PASTED, not only what I wrote. If my confusion has a rendering cause, fix the medium, not the wording. Hard-cap lines at 78 characters and tables at 3 columns unless I say otherwise. An option I cannot read is an option you did not offer. When a question comes back as "what do you mean?" or a row of question marks, the DEFAULT diagnosis is a rendering failure, not confusion. Check what actually reached me, then RE-SEND in a medium that survives. Do not reword: rewording a question whose explanation never arrived burns another round. BOUND: the default, not a certainty. If I plainly received the text and still found it unclear, rewording is right — say which diagnosis you made and why.

  4. BOUNDARIES AS PROHIBITIONS. When I say "stop after X", enumerate the specific things not to do. Negatives do not survive momentum, especially when the next step is decided, small, and obviously in scope. Name the PERMITTED set too — a pure ban list makes you freeze on things that are fine.

PASS 3 — specify, don't complain

  1. Convert every quality complaint into a named artifact. "Detail this more precisely" is not checkable. "Name real functions and call sites" is. "Show me the binding table and the focus model, not the feature name" is. THE ALTITUDE TEST, for checking whether you actually named one: if the sentence would be equally true of a system you have not designed yet, it is not a description — it is a placeholder wearing the feature's name. "Needs its own drop model" passes for any tree ever built. "Top 30% before, bottom 30% after, middle 40% into" does not.

  2. Attach a consequence to every override. An override without a stated consequence invites the concern back, because you cannot tell whether I understood it or missed it.

  3. Label questions that are curiosity, not dissent. "I am not asking in order to reverse this" — the two look identical in terse text, and an unlabeled question re-opens a closed decision.

  4. Watch for a one-word answer to a compound question. "Sounds ok" against "is the grouping right AND is the fix in the right place" answers one of two things. Record what was actually approved, and flag the rest.

  5. VERIFY BY EFFECT, not by presence. Wherever the prompt asks for a check, specify one that could come out wrong. Name the value that must move, and say what result would have proved the check failed. A check that could not have failed is not a check, and an exit code is not evidence that anything changed. Then FALSIFY THE PROBE ITSELF before trusting a clean result. Run the same probe against a known-positive control and confirm it comes back dirty. A probe that reports clean against a known positive is broken, and every clean result it has ever given is worthless.

  6. NEVER OFFER A MITIGATION AS THE REQUIREMENT. When you propose a guard, a warning, a lock, or a refusal, name in the same breath the missing CAPABILITY that makes the guard necessary, and offer that capability with its cost. "Two tabs will clobber each other, so warn the user" puts only the guard on the menu and hides the answer the user actually held — support two tabs. A mitigation is the fallback and must be presented as the fallback. BOUND: this does not forbid warnings, and it does not forbid concluding the capability is too expensive. It forbids presenting the guard as the only option without having named the capability it stands in for.

  7. WRITE QUESTIONS THAT SURVIVE BEING ECHOED BACK. I answer by pasting your question block back and deleting or rewriting the lines I reject, so the format has to survive that edit. One decidable item per line. Never let an option body wrap onto a second line — an edit inside a wrapped block reads as agreement, because the deletion is invisible at a glance. Put a short stable id on every line I might strike, so a missing line is detectable rather than merely absent. BOUND: this governs option lists and question blocks, not ordinary prose. It is the return half of rule 7 — rule 7 protects what reaches me, this protects what comes back.

  8. AUDIT YOUR OWN QUESTION BLOCK BEFORE SENDING IT. Rule 4 checks my answers against each other; this checks your questions against each other. Two failures to hunt: a question whose item another question in the same block already settles — asking "which of these four?" when two were decided three questions earlier makes the menu malformed and forces an off-menu answer; and a single line bundling two different judgments, where "is this a good idea" and "is this in scope now" share one ask and one answer lands ambiguously across both. BOUND: a pre-send check on question blocks, not a ban on related questions. Questions may depend on each other. They may not answer each other.

  9. NO MENU WITHOUT A REJECTION ROW. When every option in a list shares a premise, add an explicit row for not doing the thing at all, and say what is lost by taking it. Offering four variations on "which token flow?" hides the answer I actually held, which was "no token" — and I had to reject the frame instead of answering. The all-of-them row catches false exclusivity; this catches a menu where every option assumes a mechanism I never agreed to. BOUND: only where the shared premise is itself unsettled. Once I have chosen the mechanism, variations on it need no rejection row — do not re-litigate a settled premise on every follow-up question.

Test corpus — five real turns from the Bucket Tree design conversation

Each case is one turn: the project context a fresh agent needs, a condensed version of the assistant's previous message, and the user's verbatim reply. The reply is the input under test and must never be paraphrased, tidied, or spell-corrected — its defects are the signal.

To run a case, hand a fresh subagent: the brief, then the case's three blocks, then the line "Produce the deliverable now. Begin your reply with the opening fence."

Always tell the subagent NOT to read HANDOFF.md, PITFALLS.md, or any project files. The test measures what the brief transfers, and project files would contaminate that.


CASE A — off-menu answers

Mechanic under test: does an answer the menu did not contain become a standing framing rule, rather than just a recorded decision?

Project context

"Bucket Tree" is a single static HTML page for sorting text items into nested containers — no build step, no server, no accounts. State is one JSON blob. It has a canvas of nested cards and a read-only sidebar outline. We are five rounds into designing a batch of features. Nothing has been built yet; there is no repo and no users.

The assistant's previous message ended with these questions

Q1 · Repo. Create DgxSparkLabs/bucket-tree now and push the working code, so the two drafted issues have a home? (a) yes, create and push now <- my pick (b) create it empty, issues only, code later (c) hold both issue bodies in conversation until the shipping step

Q2 · Flow control placement. The flow-direction control, which decides whether a bucket lays its children out in a row or a column, currently sits as a bare glyph in the card header. Move it into the new ribbon under the title, as the words "Flow: row"? (a) move it into the ribbon as the words "Flow: row" <- my pick (b) keep it as a glyph in the header

Q3 · Sidebar drop model. Two ways to drag in the outline: (a) three-band — each row splits into before / into / after, and horizontal position picks depth for before/after <- my pick, matches the canvas gesture where you drop ONTO a container (b) indent-only — every drop is between rows, no drop-onto; depth comes purely from horizontal pointer position

Q4 · Compactness. Collapse now hides children only, so a collapsed card still costs a ribbon and three lines of body. Do you need a second command? (a) a global density switch on the toolbar: Comfortable / Compact / Titles only <- my pick (b) a per-card compact toggle that strips that card to its title (c) a third state on the text control: hidden / 3 lines / full

Q5 · Share links and view state. Carry the semantic view (collapse, filter, density, palette) plus an optional focus=, but not zoom and pan? (a) yes, semantic view travels, camera does not <- my pick (b) carry everything including camera (c) carry nothing — a link is data only, always a default view

Q6 · Tag hierarchy semantics. Tags nest — a tag can have child tags. (a) hierarchical match — ticking "Review" matches Review and every descendant tag, without ticking them <- my pick (b) selection shortcut — ticking a parent ticks its children, and you can untick one

Q7 · Tags and colours. (a) separate concepts, shared implementation; card colour stays single-valued and palette-driven <- my pick (b) unify — a colour is a tag with a swatch

Q8 · What are tags for, in your head? This decides whether hierarchical tags are worth their complexity: (a) cross-cutting classification — a rule is in Accepted and also security and needs-example (b) a second organising axis you would otherwise have wanted as a second tree (c) mostly a filtering convenience — saved searches by another name

Additional context from that message, relevant to the answers:

  • On Q4 the assistant argued (a) wins because "wanting everything small is a viewing mode, not a property of any individual card", and recommended AGAINST adding (b) as a third per-card command.
  • On Q5 it argued zoom and pan are "camera, not content" and are actively wrong on a recipient's differently-sized screen.
  • On Q6 it argued (a) because "if tagging something Design does not make it findable under Review, the nesting is decoration."
  • On Q3 it warned that (b) means the canvas and the outline would express "put this inside that" with two different gestures — the exact drift it had spent the previous round designing out.

The user's reply — verbatim, this is the input

Q1 · Repo. Create DgxSparkLabs/bucket-tree now and push the working code, so the two issues have a home? (a) yes, create and push now <- my pick

Q2 · Flow control placement. Now that you can see both cards: (a) move it into the ribbon as the words "Flow: row" <- my pick

Q3 · Sidebar drop model. Now that you can see both: (b) indent-only — every drop is between rows, no drop-onto

Q4 · Compactness. Instead of a per-card "compact" command: all 4: +(c) a third state on the text control: hidden / 3 lines / full +(b) a per-card compact toggle +(a) a global set switch for all: Full / Compact / Titles only +(d) a global visual density switch that affects only visually : Comfortable (Whatever the cards are set to) / Compact / Titles only

Q5 · Share links and view state. Carry the semantic view (collapse, filter, density, palette) plus an optional focus=, but not zoom and pan? (d) allow the user to toggle the option and choose and remember their last choices for the next time. agree: active filter ........ autosave no* · file no · link yes*

Q6 · Tag hierarchy semantics. (b) selection shortcut — ticking a parent ticks its children, and you can untick one

Q7 · Tags and colours. (a) separate concepts, shared implementation; card colour stays single-valued and palette-driven

Q8 · What are tags for, in your head? This decides whether 5.2 is worth its complexity: (a) cross-cutting classification — a rule is in Accepted and also security and needs-example

Known-good findings for this case

A passing run should produce a standing rule about presenting independent axes as exclusive picks. Strong runs also find that Q2 moves the flow control into a ribbon that Q4's density modes can hide, and that Q6 and Q8 are in tension.


CASE B — a rule buried in an option edit

Mechanic under test: the user edits the option text instead of picking it, and states a general rule in prose. Does the rule get promoted, and is something it invalidates named?

This case failed 2 of 3 runs before v3. It is the regression sentinel.

Project context

"Bucket Tree" is a single static HTML page for sorting text items into nested containers — no build, no server, no accounts. Five rounds of design are done; nothing is built yet. There is no git repo yet. The plan is to create a PUBLIC repo, DgxSparkLabs/bucket-tree, and push the working code so two drafted GitHub issues have a home.

Two research subagents produced long reports on replicated-tree merging. Those reports currently sit at docs/.research/ — 577 lines — alongside raw fetched web artifacts, plus probe scripts in a scratchpad. Everything is still in a Windows temp directory.

The user's standing conventions, which the assistant already knows:

  • docs/ holds settled facts. docs/.research/ holds active research, promoted to docs/ when settled. .archive/ holds retired material.
  • HANDOFF.md and PITFALLS.md at repo root are the project's memory across sessions, because the agent has none.

The assistant's previous message ended with these questions

It had recommended: commit 1 = application + HANDOFF.md + PITFALLS.md + LICENSE + .gitignore + README; commit 2 = the research reports and probe scripts; raw fetched artifacts gitignored. It argued commit 2 exists so "the history reads as a sentence — commit 1 says 'this is the thing', commit 2 says 'this is what we learned before deciding how it should work'." It proposed a .gitignore whose only research-related entry was .research/prior-art-search/. It also drafted HANDOFF.md and PITFALLS.md in full and asked whether they needed changes before being committed.

Q1 · Compact-card ribbon. EXCLUSIVE — a hidden ribbon either comes back on hover or it doesn't. When text = hidden, the ribbon hides and returns on hover. (a) hover-reveal, as described <- my pick (b) keep the ribbon always visible; hidden only hides the body

Q2 · Camera in a share link. EXCLUSIVE. Ship "Camera" as a stored world-space rectangle that refits to the recipient's viewport, rather than raw zoom and pan? (a) rectangle, refitted <- my pick (b) raw zoom and pan, default off (c) omit camera from links entirely

Q3 · The edit stamp. EXCLUSIVE for the stamp; the fractional index is a separate axis and I recommend deferring it regardless. (a) add touch(nodeId, field) plumbing now, defer fractional indexing <- my pick (b) add both now (c) add neither; retrofit when merge is built

Q4 · First commit. EXCLUSIVE. (a) commit 1 = app + HANDOFF + PITFALLS + LICENSE + .gitignore + README; commit 2 = research reports and probe scripts; raw fetched artifacts gitignored <- my pick (b) everything in one commit (c) research stays out of the repo

Q5 · Licence attribution. EXCLUSIVE. MIT either way. (a) Copyright (c) 2026 DgxSparkLabs <- my pick, the repo is org-owned (b) your own name

Q6 · The drafts. Do HANDOFF.md and PITFALLS.md above need changes before they go in? I have deliberately kept PITFALLS to things that actually happened, including the terminal-width one.

The user's reply — verbatim, this is the input

Q1 · Compact-card ribbon. EXCLUSIVE — a hidden ribbon either comes back on hover or it doesn't. When text = hidden, the ribbon hides and returns on hover. (a) hover-reveal, as described <- my pick

Q2 · Camera in a share link. EXCLUSIVE — one of these is what the toggle sends. Ship "Camera" as a stored world-space rectangle that refits to the recipient's viewport, rather than raw zoom and pan? (a) rectangle, refitted

Q3 · The edit stamp. EXCLUSIVE for the stamp; the fractional index is a separate axis and I recommend deferring it regardless. (a) add touch(nodeId, field) plumbing now, defer fractional indexing Q4 · First commit. EXCLUSIVE. (a) commit 1 = app + LICENSE + .gitignore + README; commit 2 = research reports and probe scripts; raw fetched artifacts gitignored <- my pick Pitfalls and handoff .research folders and .meta folders are all our internal state. if we commit anything it is externalized into meaningful documents under docs/ or issues in the repo github

Q5 · Licence attribution. EXCLUSIVE. MIT either way. (a) Copyright (c) 2026 DgxSparkLabs

Q6 · The drafts. Do HANDOFF.md and PITFALLS.md above need changes before they go in? I have deliberately kept PITFALLS to things that actually happened, including the terminal-width one. HANDOFF.md and PITFALLS.md are our own stateful files and dont go into commits. don't gitignore them either just dont add them. if added already take them out of the git. we use them for our own purposes just like the related .research and .meta directories

New Feature requests: Allow working on multiple boards. so far we have been designing a system that is only allowing to work in 1 tab and on 1 board but users might be wanting to work on multiple things at once each independent of each other thus they might need more boards to work on. extending our system even further after adding concurrent work support adding multiple boards support and providing a user/api interface to navigate and control them is clearly the obvious step for even more concurrency. we need to also create an issue for this feature and ensure its dependent on our concurrency work being implemented first so we avoid the trivial bugs

Known-good findings for this case

A passing run promotes "internal state never ships; publishing is a rewrite" to a named rule AND names that it kills the commit-2 plan the assistant just argued for. Strong runs also notice that the user's own edited option kept "raw fetched artifacts gitignored", which may or may not narrow the no-gitignore instruction — an ambiguity the real conversation needed an extra round to resolve.


CASE C — speech-act sorting on a messy first round

Mechanic under test: a reply mixing decisions, overrides, elaboration requests, new questions and scheduling instructions with no structure.

Partly contaminated: the brief's exemplar quotes the palette line from this case verbatim. Only one of its findings touches that line.

Project context

"Bucket Tree" is one ~1300-line index.html — a static page for sorting text items into nested containers. No build step, no server, no accounts. State is one JSON blob with a root node and nested children. There is a canvas of nested cards plus a read-only sidebar outline. It works but nothing persists across a refresh. There is no git repo and no users. The user belongs to a GitHub org, DgxSparkLabs, on the free plan — so GitHub Pages there requires a public repo.

The assistant's previous message, condensed

It mapped the user's eight requests into buckets A-G: A. persistence — autosave to localStorage (item 1); save/load via GitHub Gist (item 1.5) B. bug fix — "show more/less" is broken (item 2). Root cause found: a CSS descendant combinator re-clamps nested children, and the "more" button is only shown while clamped, so expanding hides its own way back. C. card chrome — move +child / duplicate / sort into a ribbon under the title (item 3); put show more/less in the ribbon too (3.5); collapse the sort buttons into one "Sort" menu (item 4) D. sidebar parity — create / delete / drag-to-move from the outline (item 5). It wrote only: "needs its own drop model: rows are a FLAT list, so 'into' vs 'between' must be decided by horizontal position (indent zones)." E. input — keybinds for add / edit / flow direction / collapse-expand (item 7). It wrote only: "needs a '?' overlay or they're undiscoverable." F. appearance — per-bucket colour and custom palettes (item 8). It wrote only: "reference a palette entry, don't store raw hex." G. shipping — repo + Pages + README (item 6)

On item 1.5 it said reading a public gist needs no token — plain fetch to api.github.com/gists/ — but WRITING needs the user's own token in the browser, scoped to gists only.

On item 8 it recommended buckets store a palette KEY, not a hex value, and said it would ship 3 default palettes, one colourblind-safe.

It noted the state schema would go to version 4, and warned: "Needs explicit migrations, or silent corruption."

It then proposed ten additions of its own: S1 multi-select + bulk move S2 a filter that drives the canvas, plus select-all-matches S3 save to file / open from file — a Blob download and a file input S4 named checkpoints S5 arrow-key navigation S6 soft delete via a Trash bucket instead of hard delete S7 import merge modes — today import always appends and re-ids on collision; add merge-by-id and skip-existing S8 multi-tab guard — two tabs with autosave will clobber each other; listen to the storage event and warn S9 schema migrations S10 a "?" keybind overlay

And it asked for five decisions before planning:

  1. File structure — stay single-file, or split into index.html + app.js + app.css? Its recommendation: split.
  2. Repo — name it bucket-tree? It must be public for Pages.
  3. Theming model — palette-reference (its recommendation) or raw per-bucket hex?
  4. Gist — OK with a Gists-only fine-grained PAT stored in the browser, secret gists by default?
  5. Scope of this round — which of S1 through S10 now versus later?

The user's reply — verbatim, this is the input

Reading a public gist needs no token: plain fetch to api.github.com/gists/. - good 1.5 - 'needs YOUR token in the browser' Is it possible to create a url that "create a gist" in place instead of using "token", using tokens is not the intended ux i want. i rather the user do manual steps and keep their setup cost as low as possible D) sidebar parity. detail this more preciesly. functions? code? what needs to be done? E) INPUT: explain? F) detail this feature further G) yes we are doing this as a public repo 'Needs explicit migrations, or silent corruption.' we just made up this system right now there are no users yet. there is no possible curruption. appriciate the concern

what's the difference between the ' expand' should be show/hide text rather than expand. this has a confusig meaning with the collapse chevron S1 good idea S2 good idea S3 good idea also S4 good idea, history S5 good idea S6 good idea S7 interesting keep this an a feature request and make a github issue for this - explain in detail the purpose and how it shall be used S8 can we support multi tabs instead of being afraid of collisions? S9 ok S10 good idea

  1. sure split.
  2. yes
  3. Palette-reference and of course allowing the user to configure the pallete for themselves as they desire

you don't need to wait on S3 and S9. do them when it best fits to implement. we don't have users I want to discuss a little more and then we will plan

Known-good findings for this case

A passing run promotes the palette line's "and of course" into a stated requirement. Strong runs also find: "good idea, history" attaches a different object than the "named checkpoints" that was proposed; "S9 ok" contradicts the rejection of migrations in the same message; and a secret-gist default may be unreadable by the unauthenticated fetch path approved in the same message.


CASE D — a rendering failure, not a wording failure

Mechanic under test: two questions come back as rows of question marks. Does the run diagnose the terminal clipping rather than rewording?

The assistant's previous message MUST be reproduced with its truncation intact. Repairing the tables destroys the test.

Project context

"Bucket Tree" is a single static HTML page for sorting text items into nested containers — no build, no server, no accounts. Cards nest on a canvas; a sidebar shows a read-only outline. Three rounds of design are done; nothing is built yet; there are no users and no repo. The user reads replies in a terminal.

The assistant's previous message, exactly as the user received it

3.2 — The three collapse controls

Question. What does each control act on, and how do we make no two of them suggest the same action?

What they actually do today — and the collision is structural, not cosmetic:

+--------------------+------------------------------+--------------------------------------------+ | control | acts on | current beh +--------------------+------------------------------+--------------------------------------------+ | header chevron | children and body and ribbon | hides everything below +--------------------+------------------------------+--------------------------------------------+ | inline show more | body text only | toggles .tx (currently +--------------------+------------------------------+--------------------------------------------+ | ribbon expand | body text only | my invention last round +--------------------+------------------------------+--------------------------------------------+

You're right that the expand glyph is wrong — it reads as fullscreen. But the deeper problem is that there are only two axes and three controls, and control 1 straddles both axes.

Options.

  • A · Orthogonal. Header chevron hides children only. A collapsed card still bon. Two controls, two axes, zero overlap.
  • B · Dominant collapse. Header chevron compacts the whole card to its title bar.
  • C · One cycling control. title -> title+text -> title+text+children. One contng is a poor interaction for a state you want to set directly.

Recommendation. B, plus a strict glyph-family rule.

The naming and glyph scheme — one glyph family per meaning:

+-----------------------+-------------------------+-----------------------------------------+-----------------------------------------+ | meaning | family | control states | +-----------------------+-------------------------+-----------------------------------------+-----------------------------------------+ | container open/closed | chevron, exclusively | header chevron + always-visiblapse card" / "Expand card" | +-----------------------+-------------------------+-----------------------------------------+-----------------------------------------+ | text length | words, never a chevron | ribbon button 3 lines | +-----------------------+-------------------------+-----------------------------------------+-----------------------------------------+

A related question I need answered, not assumed: should the flow control move out of the header into the ribbon? The header would then be exactly grip · id · title · count+chevron · delete, which is calm. But flow-direction is arguably a "shape of this card" control that b


3.4 — Sidebar parity, broken down

New functions.

  • treeRows() -> flat array [{id, depth, el, top, height}], built once at drag move would thrash layout on every frame.
  • resolveTreeDrop(rows, x, y, excludeId): a. binary-search rows for the row whose vertical band contains y. b. band within that row — top 30% -> before, bottom 30% -> after, middle 40% -> into (append as last child). d. before/after -> compute the legal depth range. Desired depth from x: round((x - BASE) / 14), then clamp into that range. Thim — the same one VS Code's explorer and Workflowy use.

Questions I need answered

Q1 · Save path. Which is the main road? (a) File download + upload via GitHub's web UI — unlimited, readable, two ste (b) Prefilled-URL as primary, accepting a ~15-bucket cap (c) Compressed prefill — one click to ~180 buckets, opaque blob in the repo

Q2 · Share link. Separate from saving: do you want index.html#s= e board to someone with no repo and no account? 50 buckets fits comfortably. (a) yes, build it (b) no, out of scope <- I'd say yes, it's the honest home for compression

Q3 · Token. (a) opt-in advanced path, hidden behind "advanced" <- my pick (b) don't build it at all (c) it's the main road after all

Q4 · Collapse semantics. (a) collapse compacts the whole card, text toggle absent while collapsed <- my pick (b) collapse hides children only, body stays readable

Q5 · Header vs ribbon. Does the flow-direction control move into the ribbon, leaving the header as grip · id · title · count · delete? (a) move it <- my pick (b) keep it in the header

Q6 · Enter. This is a real fork with two established conventions: (a) outliner — Enter makes a new sibling, F2/double-click edits <- my pick, itssible (b) form — Enter edits the selected card, Ctrl+Enter makes a new one

Q7 · Sidebar drop model. (a) three bands — before / into / after, with indent-zones deciding depth for before/after <- my pick, matches the canvas mental model (b) indent-only, Workflowy-style, no "drop onto a row"

Q8 · Multi-tab scope. Confirm: cheap layer (live sync + adopt-when-idle + a crrency), simultaneous editing of the same bucket explicitly out of scope? (a) confirmed <- my pick (b) no, I want real concurrent editing

The user's reply — verbatim, this is the input

Q1 · Save path. Which is the main road? Good findings. Instead of thinking too much we can do all and tell the different options and they can choose what to do and act themselves A B C are all valid good options. D is the token one is its fuled out

Q2 - yes share link! good idea Q3 no token Q4 - (b) collapse hides children only, body stays readable, yes + - if not yet, collapsing is also a visual property that needs to be tracked be part of the json state and restored as last used Q5 Header vs ribbon - what do you mean? ????????????????? Q6 (b) form — Enter edits the selected card, Ctrl+Enter makes a new one Q7 what do you mean? ?????????? Q8 build the cheap, yes but 3 · Two tabs edited simultaneously -> merged - this is the important functionality we want. what i dont understand is what's the difference between that and 1+2 is 1+2 =!=3? open an issue for this as a feature and then research the the tree-CRDT problem with subagents to provide deeper knowledge about this feature. i believe that can be helpful to us 1) to investigate it further 2) to implement that in the future. i think we are going to face that issue over and over again in this project

New Feature request - sidebar has search and filtering ui, toggles for regex, capital word matching, to include only titles/only text body in the search. "filtering by color/theme" chosen per item, filtering by tags New feature request - tags, tags can have children tags and filtering shows a ui with tickboxes allowing to select/deslect tags for filtering in hierarchical reactive manner

Known-good findings for this case

A passing run states that the question marks were caused by clipped tables, and sets a width constraint. Strong runs also notice that "yes" appears immediately before a pick that contradicts the assistant's recommendation, and that Q1's "is it ruled out" may be a question rather than a statement.


CASE E — mode flip, prerequisite chains, boundaries

Mechanic under test: the user switches from discussion to execution and says "before we continue doing anything further". Does the run flip the mode, find the unstated prerequisite chain, and enumerate prohibitions?

Held out: added after v2 and never used to tune anything.

Project context

"Bucket Tree" is a single static HTML page for sorting text items into nested containers — no build step, no server, no accounts. Six rounds of design are done. NOTHING has been built or committed yet: there is no git repo, no GitHub repo, and the only copy of the working code — a single ~1400-line index.html, plus smoke-test.js and serve.js — is sitting in a Windows temp directory that the OS periodically clears.

Standing decisions relevant here:

  • Round one decided the app should be SPLIT into index.html + app.js + app.css, with a single-file build kept as a release artifact. That split has never been done.
  • The repo will be DgxSparkLabs/bucket-tree, public, MIT.
  • HANDOFF.md, PITFALLS.md, .research/, docs/.research/ and .meta/ are internal working state: never committed, never gitignored, just never added. Every commit names its files explicitly; no git add -A.
  • Three GitHub issue bodies have been drafted and reviewed but not created: (1) import merge entry points, (2) multiple boards, (3) concurrent editing. Issue 3 cites issue 2 as a scope constraint.
  • docs/merging-trees.md, a 150-200 line settled reference, and docs/evidence/ were agreed for a later "commit 2" and are not written.

The assistant's previous message

It ran a completeness audit of all six rounds and reported 15 findings. The relevant ones:

  • CONFIRMED CONTRADICTION: round one decided the three-file split, but its own HANDOFF draft says "index.html — the whole application" and its commit-1 file list agrees with the draft, not the decision.
  • It proposed the implementation passes: pass 1 = the card and the store — file split; the show-more bug fix; autosave with per-board keys and the version guard; the ribbon; flow control moved; collapse means children only; text tri-state; density lens and the "set all cards to" verb. Passes 2-6 follow: input, classification, sidebar parity, save and share, multi-board UI.
  • FOUR NEVER-ASKED ITEMS surfaced: (A) what builds the single-file release artifact, since the split implies a build step in a project whose pitch is that it has none; (B) splitting breaks file:// if app.js loads as an ES module, since modules are CORS-blocked over file://, which would silently make serve.js mandatory; (C) multi-select drag versus the drop resolvers, which take a singular excludeId; (D) localStorage quota — roughly 5 MB, and setItem throws, which with autosave is a silent data-loss path.
  • It proposed the sequencing loop: scope the passes -> write design.md for pass one only -> derive its QA handbook -> implement pass one -> re-scope with what you learned.

It ended with these questions:

Q1 · The multi-board issue body. Approved as drafted, or does it need changes before I create it?

Q2 · The split. EXCLUSIVE. (a) split into index.html + app.js + app.css before commit 1 <- my pick (b) commit the single file, split in commit 2

Q3 · The single-file build. EXCLUSIVE, from never-asked item A. (a) a ~20-line node concatenator; the built file goes to GitHub Releases only, never committed <- my pick (b) commit the built single file at repo root as well (c) drop the single-file artifact entirely

Q4 · Module loading. EXCLUSIVE, from never-asked item B. (a) classic <script> tags so file:// keeps working <- my pick, "open index.html" is the whole pitch (b) ES modules, and serve.js becomes required for local use

Q5 · Pass one. Is the card-and-store grouping right, and is the show-more fix in the right place? Everything after it is orderable; pass one is the one that constrains the rest.

Q6 · The four never-asked items. Which do you want designed now rather than filed — the build step, file:// loading, multi-select drag, and quota handling? I'd design module loading and quota in pass one, and file multi-select drag against pass two.

The user's reply — verbatim, this is the input

Q1 · The multi-board issue body. You flagged that you never answered. Approved as drafted, or does it need changes before I create it? I have read all of it, it's ok

Q2 · The split. EXCLUSIVE. (a) split into index.html + app.js + app.css before commit 1

Q3 · The single-file build. EXCLUSIVE, from 4.7-A. (a) a ~20-line node concatenator; the built file goes to GitHub Releases only, never committed

Q4 · Module loading. EXCLUSIVE, from 4.7-B. (a) classic <script> tags so file:// keeps working, "open index.html" is the whole pitch

Q5 · Pass one. Is the card-and-store grouping right, and is the show-more fix in the right place? Sounds ok

Q6 · The four never-asked items. Which do you want designed now all now.

I like the the loop mentioned: scope the passes -> write design.md for pass one only -> derive its QA handbook -> implement pass one -> re-scope with what you learned But I also want to write down everything we had chosen and discussed so far down into a draft we have had a lot of choices done, a lot of diagram, a lot of resolutions and we shouldn't lose them just because we forgot. docs/design-draft.md should be the full space for it and throughout the loop everything shall graduate into docs/design.md write that draft now and create the GitHub issues we drafted now before we continue doing anything further.

Known-good findings for this case

A passing run flips to execution mode with a hard stop and enumerates prohibitions. Strong runs also find that creating the issues requires a repo that does not exist, that GitHub issues and pull requests share one number counter so the cited issue number must be captured rather than assumed, and that "Sounds ok" answered a compound question.

Prompt-refinement brief — changelog and experiment log

The brief converts a terse, fragmentary user reply into an explicit self-contained prompt. It is tested by handing it to fresh subagents with real conversation turns and comparing their output against what was produced by hand.

x

Test cases

Each case is a real turn from the Bucket Tree design conversation, chosen to exercise one mechanic.

case mechanic under test
A off-menu answers become a standing framing rule
B a rule buried in an option-edit gets promoted and generalized
C speech-act sorting on a very messy first-round reply
D ????? diagnosed as a rendering failure, not a wording one
E mode flip, prerequisite chains, boundaries as prohibitions

E was held out: added after v2, never used to tune anything. C was never run until v3. C is partly contaminated — the brief's exemplar quotes one line from C's input verbatim — but only one of its findings touches that line.

Pass criteria

A run passes when it emits a fenced code block containing all five sections, plus 2-3 readings-to-check. Quality is then compared against the hand-written original for the same turn.

Score

version passes runs
v1 2 3
v2 3 4
v3 7 7
v4 7 7
v5 7 7
v6 6 6
v7 6 6
v8 6 6
v9 6 6
v10 6 6
v11 6 6
v12 6 6
v13 6 6
v14 6 6

v1 — initial

Written from six rounds of doing this by hand.

Experiment 1

run outcome tokens duration
A pass 50,871 229 s
B FAIL — preamble only, no code block 35,417 4.2 s
D pass 40,976 76 s
control, no brief prompt produced, zero standing rules 36,152 61 s

Findings:

  • A and D both produced the EXCLUSIVE/AXES rule independently. D produced it one round earlier than the human original did.
  • A found a design collision the human original missed: the flow control was moved into the ribbon in one answer while another answer added a density mode that hides the ribbon.
  • The control produced a good single-round prompt but converted no friction into a standing rule, did no breakage sweep, attached no consequences to overrides, and stated no readings-to-check. That is the delta the brief buys.

v2 — patch attempt, did not work

  1. WHAT section stated the code block is the deliverable and a reply without one is not.
  2. DONE WHEN gained a matching first checkbox.
  3. The AXES rule replaced with the mechanical "all-of-them row" test, contributed by run A of experiment 1.

Experiment 2

run outcome tokens duration
A pass 49,140 203 s
B run 1 FAIL — preamble only 35,528 4.5 s
B run 2 pass 49,416 193 s
E, held out pass 49,495 202 s

Findings:

  • The patch did not fix what it targeted. Near-identical failure to v1: ~35.5k tokens in ~4.3 s versus ~49k in ~200 s for a pass. The agent emits one sentence and terminates, so a rule saying "do not stop early" is never reached.
  • Diagnosis error recorded: the v2 patch addressed the failure without testing whether it changed the outcome. It did not.
  • E, held out, produced four things the hand-written original did not: the GitHub issue-numbering hazard (issues and PRs share one counter), an explicit permitted-list alongside the prohibitions, a no-regeneration guard on already-reviewed text, and a catch that a one-word answer had been given to a compound question.

v3 — 2026-08-14 — the reorder

Structural fix rather than a prohibition: make the failure mode benign instead of forbidden.

  1. The code block moves FIRST. Reply order is block, then framing sentence, then readings-to-check. Stopping early now loses commentary, not the artifact.
  2. Explicit instruction that the reply's first characters are the opening fence.
  3. Rule 8 gains "name the PERMITTED set too" (from E, experiment 2).
  4. New rule 12: watch for a one-word answer to a compound question (from E, experiment 2).

Experiment 3 — the hypothesis

run outcome tokens duration
B run 1 pass 50,985 206 s
B run 2 pass 44,646 131 s
B run 3 pass 46,173 153 s
E regression pass 40,520 72 s

B went from 1 of 3 to 3 of 3. Under a null of the observed 2/3 failure rate, three consecutive passes is p = (1/3)^3 = 0.037.

All three B runs independently found the same contradiction: the picked option kept "commit 2 = research reports" while the rule stated three lines later forbids shipping them unrewritten. All three also independently flagged the same ambiguity — whether the "don't gitignore" instruction extends past the two memory files — which the real conversation needed an extra round to resolve.

Experiment 4 — regression and new coverage

run outcome tokens duration
A regression pass 54,809 230 s
D regression pass 42,061 96 s
C, never run before pass 46,222 164 s

No regression from the reorder. New findings beyond the hand-written originals:

  • D reformulated the channel rule better than the original: "an option the user cannot read is an option you did not offer. If a question comes back as 'what do you mean?', the default diagnosis is a rendering failure, not confusion."
  • D caught an agreement token preceding a contradicting pick — the user wrote "yes" immediately before choosing the option the assistant had argued against.
  • A named an unannounced third store: remembered share preferences are machine-local, not document data, so "state is one JSON blob" had quietly stopped being true.
  • C found "good idea, history" attached to a proposal that said "named checkpoints" — a smuggled requirement, since history and checkpoints are different objects. The human original missed it.
  • C found that secret gists, the proposed default, may be unreadable by the unauthenticated fetch path approved in the same message. The human original missed it.
  • C bounded its own promoted rule: a hard budget on end-user setup cost must not forbid the maintainer using the gh CLI on their own machine. Over-promotion is the failure mode of rule promotion, and this is the first run to guard against it.

v4 — 2026-08-15 — cycle 1, one candidate adopted

ADOPTED: candidate 2, the bound-your-rules instruction. Appended to PASS 1 hunt 3 (RULE PROMOTION): after naming what a promoted rule invalidates, name the channel or scope it does NOT reach.

Hypothesis recorded before editing: "If rule 3 gains a bound-your- rules clause, the suite stays 7 of 7 and scope-bounding becomes routine rather than incidental, because over-promotion is rule promotion's own failure mode and only 1 of 12 prior runs guarded against it unprompted."

Experiment 5 — full suite on v4

run outcome tokens duration
A pass 48,148 142 s
B run 1 pass 43,692 80 s
B run 2 pass 55,064 224 s
B run 3 pass 48,428 141 s
C pass 45,768 118 s
D pass 52,127 180 s
E pass 50,024 155 s

VERDICT: candidate ADOPTED. Suite clean, and the named value moved.

Bound clauses present in 7 of 7 runs, against 1 of 12 before adoption. Run B3 restated the brief's own phrasing back — "a promoted rule without a bound is half a rule" — and every run bounded at least one rule. Case C produced five bounded rules in a single output.

Harness note: this cycle switched from inlining the brief in each subagent prompt to having each agent read brief.md plus a sanitized per-case file under cases/. The sanitized files stop before each case's "Known-good findings" heading, verified at 0 occurrences of "known-good" in all five. Case D's truncation marker survives the split. No case has ever run un-sanitized, so this changes nothing about comparability except cost.

Corpus exhaustion: all five cases have now run on at least one version. There is no never-run case left to hold out. Every future cycle is therefore regression-only, and the defence against tuning the brief to its own test set is gone. Adding a case from a second collaborator is the only way to restore it — flagged, not fixed.

Candidates harvested from experiment 5

Attributed to the run that produced them. NOT TESTED.

  1. VERIFY BY EFFECT. The brief contains no instruction to make a check that could fail. Three runs invented one independently — B3 wrote "the check is git ls-files returning no line for either file — not 'I did not add them', and not 'they are not in .gitignore'. Both of those could be true while the file is tracked." Largest single gap found this cycle.
  2. RESTATE SCROLLED-AWAY TEXT. From D: "when the user answers by pointing at a numbered item from an earlier message, restate that item's text inline before responding — they are reasoning about text that has scrolled away."
  3. DIFF A REWRITTEN OPTION. From B1: "Treat a rewritten option as an edit to the proposal, and diff it against what you offered before recording it. Silent deletions inside a 'pick' are the highest-value signal in a terse reply." Sharper than hunt 1's current wording, which notices the edit but does not diff it.
  4. THE ALTITUDE TEST. From C: "if the sentence would be equally true of a system you have not designed yet, it is not a description." A checkable test for hunt 9, which currently asserts the principle without one.
  5. MISSING ENUMERATION STEP as a channel-failure signature. From D, which spotted a list running a, b, d and read the gap as transit damage rather than authorial choice.

v5 — 2026-08-15 — cycle 2, one candidate adopted

ADOPTED: candidate 5, VERIFY BY EFFECT. Added as PASS 3 rule 13: wherever the prompt asks for a check, specify one that could come out wrong; name the value that must move; an exit code is not evidence that anything changed.

Hypothesis recorded before editing: "If the brief gains rule 13, the suite stays 7 of 7 and falsifiable checks become routine, because 3 of 7 runs already invent verify-by-effect unprompted while the brief says nothing about it."

Experiment 6 — full suite on v5

run outcome tokens duration
A pass 42,967 70 s
B run 1 pass 56,916 244 s
B run 2 pass 44,215 84 s
B run 3 pass 51,256 176 s
C pass 49,842 173 s
D pass 46,572 118 s
E pass 51,379 177 s

VERDICT: candidate ADOPTED. Suite clean, named value moved.

Verify-by-effect sections in 7 of 7 runs, up from 3 of 7. Depth also increased beyond what the rule asks. Two runs independently built two-sided probes — B3's single git status --porcelain call where a MISSING line means wrongly-ignored and a staged line means wrongly-tracked, catching both halves of a two-part requirement that a one-sided check would pass on a wrong outcome. D applied the rule reflexively to the brief's own 78-column constraint: measure the longest line before sending, because "I wrote it narrow" could not have failed.

Candidates harvested from experiment 6

  1. TWO-SIDED CHECKS. From B2 and B3. When a requirement has two halves, one check that can only fail in one direction passes on a wrong outcome. B2: "verify the inverse, because R3 has two halves and a one-sided check would pass on a wrong outcome." Sharpens rule 13 rather than adding a class.
  2. NO MENU WITHOUT A REJECTION ROW. From C: "any question that presupposes a mechanism must carry an explicit row for NOT using it, stating what is lost." Distinct from the all-of-them row — that catches false exclusivity, this catches a menu whose every option shares an unexamined premise. The case that produced it: four token variants offered when the real answer was "not this mechanism at all."
  3. FLAG THE IRREVERSIBLE LINK. From B1 and E. A prerequisite chain currently says which links can fail; it does not say which cannot be undone. B1: "Link 6 is the one that cannot be repaired after link 7. The repo is PUBLIC: a file that reaches a pushed commit stays in history even after it is deleted from HEAD."
  4. NO SCOPE CUT WITHOUT A NAMED FORCING REASON. From C: "before asking the user to cut scope, name the thing forcing the cut. If you cannot name one, propose an implementation ORDER with a dependency reason per position, and ask whether the order is right."
  5. ONE ID SPACE. From C, which noticed three colliding identifier schemes in one round — item numbers with halves, bucket letters, and S-numbers — and proposed collapsing to one.
  6. AN OVERRIDE WITH NO STATED REASON. From A, which flagged that a reversal arrived with no reason given and asked what it implies elsewhere, rather than reopening it.

v6 — 2026-08-15 — cycle 3, one candidate adopted

ADOPTED: candidate 12, FLAG THE IRREVERSIBLE LINK. Appended to PASS 2 rule 6: after naming which links can fail, name the ONE-WAY DOORS separately, say which step is the last one still correctable, and put verification immediately BEFORE it.

Hypothesis: "the one-way-doors clause keeps the suite clean and makes runs name irreversible steps and place verification before them, because 2 of 7 runs already do this while rule 6 only asks which links can fail."

Run-count change: case B dropped from 3 runs to 2. It had passed 9 consecutive times across v3, v4 and v5, so the stochastic truncation looks resolved; 2 still doubles the protocol's requirement for a passing case.

Experiment 7 — full suite on v6

run outcome tokens duration
A pass 51,636 197 s
B run 1 pass 49,343 153 s
B run 2 pass 57,758 258 s
C pass 44,719 97 s
D pass 54,420 220 s
E pass 44,738 90 s

VERDICT: candidate ADOPTED. 6 of 6 runs separated "can fail" from "cannot be undone" and positioned the check before the door, up from 2 of 7.

Two runs extended the class past git: opening a public issue is a one-way door because creation notifies watchers and deletion does not recall the emails. Neither the brief nor the human original had named a non-git irreversible step.

Candidates harvested from experiment 7

  1. MATCH THE CHECK TO WHAT THE IRREVERSIBLE ACTION PUBLISHES. From B2, which paired two probes and said why: git ls-files sees the current index, git log --all --name-only sees every commit. "A file added and later deleted PASSES (a) and FAILS (b). (b) is the one that matters before a push, because the push publishes history, not the working tree."
  2. FALSIFIABILITY PRE-CHECK. From B1: before trusting a negative result, run the same probe against a known-positive control. "Put README.md through the same ls-files probe. It must come back tracked. If the probe reports README.md as untracked, the probe is broken and every clean result it gave is worthless." Domain-independent, and it guards the rule adopted in v5.
  3. FIXTURE DESIGN. From D: the probe is only half the check; the input must be able to distinguish. "A test board where everything is open cannot fail and is not a test." And: "a bare three-card board round-trips even when the encoder is dropping fields, so it could not have failed."
  4. A KEYWORD FOR CURIOSITY VERSUS DISSENT. From E, which operationalised rule 11 as a protocol rather than a label: "assume I am asking to understand unless I say the word 'reconsider'."

Convergence note

Candidate count is rising faster than adoption: 1 adopted per cycle against 4 to 6 harvested. But the KIND is narrowing. Cycles 1 and 2 produced new failure classes; all four of cycle 3's candidates are refinements of two already-adopted rules (6 and 13). If cycle 4 again yields only refinements, that is evidence of saturation and is worth reporting as a finding rather than looping on indefinitely. Neither escalation condition is met — no failures to attack, no adopt-then-revert pair.

v7 — 2026-08-15 — cycle 4, one candidate adopted

ADOPTED: candidate 17, FALSIFY THE PROBE. Appended to rule 13: before trusting a clean result, run the same probe against a known-positive control and confirm it comes back dirty.

PROTOCOL VIOLATION, caught and reverted mid-cycle. The first edit folded candidate 18 (fixture design) into the same change. Step 8 allows one candidate per cycle so a regression can be attributed; the fixture clause was reverted before the suite ran. v7 contains candidate 17 alone. 18 stays on the list.

Experiment 8 — full suite on v7

run outcome tokens duration
A pass 51,564 192 s
B run 1 pass 45,883 105 s
B run 2 pass 51,594 183 s
C pass 60,974 291 s
D pass 44,881 86 s
E pass 51,622 182 s

VERDICT: ADOPTED. Probe falsification in 6 of 6, up from 1 of 6.

C applied it to five separate checks and produced the best statement of it in any run: "a grep that finds nothing has proved nothing until it has proved it can find something." E went past the rule and built a NEGATIVE control too — grep for a string known to be absent, confirm zero hits — to catch a probe matching noise.

Candidates harvested from experiment 8

Scored under a stricter bar from this cycle on: a candidate counts only if it names a failure the brief's CURRENT rules would not already catch. A finer-grained restatement of an existing rule is "already contained" and does not count.

  1. DEFUSE THE DOOR BY REORDERING. From A: create the repo PRIVATE, verify, then flip to public — "private to public is one command later; public to private does not un-mirror anything." Rule 6 says name the door and verify before it. It does not say ASK WHETHER THE DOOR CAN BE MOVED LATER IN THE SEQUENCE. A run following rule 6 exactly would not produce this. COUNTS — and it is a new move, not a refinement.
  2. NEGATIVE CONTROL alongside the positive one. From E. Rule 13 now asks for a known-positive control; the mirror catches a different failure (a probe matching noise). Counts weakly.
  3. Resource consumption as a one-way door — issue numbers are permanently consumed. DOES NOT COUNT: rule 6 already asks for one-way doors and a run following it catches this, as E did.
  4. NEVER PRESENT A MITIGATION AS THE REQUIREMENT. From C: "whenever you propose a guard, warning, lock or refusal, state in the same breath the missing capability that makes the guard necessary, and offer that capability with its cost." No current rule covers offering a guard where a capability was wanted. COUNTS — new failure class.

Convergence assessment

Under the stricter bar, cycle 4 yielded 3 counting candidates, one of them a new failure class. Cycles 1 and 2 produced new classes freely; cycle 3 produced none, cycle 4 produced one. The rate is falling but has not reached zero.

Structural note on the stop condition: step 4c makes a dry cycle require an EMPTY candidate list, while step 9 harvests every improvement a passing run produced. As the brief improves, runs improve, and better runs generate more sophisticated material — so the list grows faster than one-per-cycle adoption drains it. Under a literal reading the loop cannot terminate. The STOP CONDITION's own wording is the better test: "no improvement the brief does not already contain." The stricter bar above is how that is being applied. Neither escalation condition is met — no failures, no adopt-then-revert pair.

v8 — 2026-08-15 — cycle 5, one candidate adopted

ADOPTED: candidate 23, NEVER OFFER A MITIGATION AS THE REQUIREMENT. New rule 14: when proposing a guard, warning, lock or refusal, name the missing CAPABILITY it stands in for and offer that capability with its cost. Bounded: warnings are not forbidden, and concluding a capability is too expensive is not forbidden — presenting the guard alone is.

Experiment 9 — full suite on v8

run outcome tokens duration
A pass 53,748 207 s
B run 1 pass 52,982 201 s
B run 2 pass 53,598 200 s
C pass 45,331 105 s
D pass 45,986 104 s
E pass 45,140 94 s

VERDICT: ADOPTED. Rule fired in 5 of 6, up from 1 of 6. The sixth run (E) correctly did not apply it — its turn proposed no guard. A rule that fires when it does not apply would be worse than one that fires rarely, so 5-of-6-with-a-correct-abstention is the result wanted, not a miss.

Two runs applied it past the case it came from. A caught it in the camera decision: "the prohibition was a mitigation; the capability it stood in for — the sender chooses what a link carries — was never on the menu at all." B2 turned it backward on the project's own premise: "five rounds of design assumed one tab and one board; that assumption is a mitigation wearing the costume of a requirement."

Candidates harvested from experiment 9

Stricter bar still applied.

  1. QUESTIONS MUST SURVIVE BEING ECHOED BACK. From B2. Rule 7 covers rendering damage in the OUTGOING channel. This is the return channel: the user answers by pasting the question block back and deleting the lines they reject, so the format must survive that edit. "Hard-wrap every question at 78 columns; one decidable item per line; never let an option body wrap; keep a stable short id on every line the user might delete." COUNTS — new channel, not a refinement of rule 7.
  2. DO NOT OFFER AN OPTION AN EXISTING CONTROL ALREADY COVERS. From B1: "check whether any option is a state an already-designed control can produce; if so, delete it and say which control produces it." The all-of-them row catches false exclusivity; this catches redundancy with existing machinery. COUNTS, narrow.

Not counted: nesting-is-presentation (domain-specific to tags), "no users yet" scoping (case-specific), durable-state-first (project triage, not prompt conversion).

Convergence

Counting candidates per cycle: 5, 6, 4, 3, 2. New failure classes: 2, 2, 0, 1, 1. Both declining, neither at zero. Continuing.

v9 — 2026-08-15 — cycle 6, one candidate adopted, FIRST DRY HARVEST

ADOPTED: candidate 24, QUESTIONS MUST SURVIVE BEING ECHOED BACK. New rule 15: one decidable item per line, no option body wrapping, a stable id on every strikeable line. Bounded to option lists and question blocks. It is the return half of rule 7 — rule 7 protects what reaches the user, rule 15 protects what comes back.

Experiment 10 — full suite on v9

run outcome tokens duration
A pass 55,033 212 s
B run 1 pass 44,757 79 s
B run 2 pass 46,089 98 s
C pass 51,900 186 s
D pass 46,708 107 s
E pass 44,414 79 s

VERDICT: ADOPTED. Rule fired in 6 of 6, up from 1 of 6.

Runs did more than restate it. B1 read the actual damage in the corpus: "Q2 and Q3 came back with the option body intact but the '<- my pick' marker deleted, and the trailing options deleted entirely." B2 diagnosed why case B's edit nearly passed as agreement: "Q4's option (a) bundled six artifacts into one run-on line; that is what let a policy-level objection look like a typo." E applied the rule reflexively, writing its own open questions as a strikeable id'd list ending "if 18.3 and 18.4 are both true you are BLOCKED."

Candidates harvested from experiment 10: NONE

First cycle to harvest zero under the strict bar. Everything the runs produced was already covered:

  • Deleted-marker interpretation (B1) — rule 1 covers edited option text, rule 15 makes the deletion detectable. Between them an agent notices and flags; the interpretation policy is a nicety.
  • "'good idea' is a verdict, not a schedule" (C) — an instance of rule 12, a compound question answered once.
  • Measuring the longest line to prove the width rule held (D) — rule 13 applied to rule 7.
  • Answering a question that was not asked (A) — inside rule 12.

Stop-condition status

Counting candidates per cycle: 5, 6, 4, 3, 2, 0.

This is dry by the STOP CONDITION's own wording — "reading every passing run's output produced no improvement the brief does not already contain." It is NOT dry by step 4c, which requires an empty candidate list, and 18 candidates from earlier cycles remain unadopted.

Taking the conservative reading: the loop continues. But the result to report is that the SEARCH has gone dry, not that the backlog has emptied. The backlog is a queue of known improvements, not evidence that more remain undiscovered. Those are different things and the changelog should not blur them.

If cycle 7 also harvests zero, that is two consecutive dry harvests and the loop stops, with the backlog reported explicitly rather than silently drained one cycle at a time.

v10 — 2026-08-15 — cycle 7, one candidate adopted

ADOPTED: candidate 8, THE ALTITUDE TEST. Appended to rule 9: if the sentence would be equally true of a system you have not designed yet, it is not a description — it is a placeholder wearing the feature's name.

Experiment 11 — full suite on v10

run outcome tokens duration
A pass 46,516 111 s
B run 1 pass 53,545 196 s
B run 2 pass 57,133 226 s
C pass 50,074 160 s
D pass 48,048 123 s
E pass 55,357 217 s

VERDICT: ADOPTED. Applied in 4 of 6, up from 1 of 6, with 2 correct abstentions — B2 and E are execution turns whose user replies contain no quality complaint, so rule 9 has nothing to act on. As in cycle 5, a rule that fired where it did not apply would be the worse result.

C applied it to the sentence that produced it: "'needs its own drop model: rows are a FLAT list' is true of every tree outliner ever built, which means it describes nothing about Bucket Tree." B1 used it twice, once on research documents and once on storage design, generating a pass/fail pair each time. A stated it as an explicit ALTITUDE BAR on its own open question.

Candidates harvested from experiment 11

  1. AUDIT YOUR OWN QUESTION BLOCK BEFORE SENDING. From E: "Q6 asked which of the four never-asked items you want designed now, while Q3 and Q4 in the SAME block already decided two of those four. The answer came back 'all now', which is not on the menu, because the menu was malformed." Rule 4 checks the user's answers against each other; nothing checks the assistant's questions against each other. C found the related failure from the other direction — one line conflating "is this a good idea" with "is this in this round". COUNTS.

Not counted: bounding the AXES rule correctly (A) — that is rule 3 working. The second-tree breakage catch (D) — rule 5 working. Labelling curiosity questions (A) — rule 11.

Convergence

Counting candidates per cycle: 5, 6, 4, 3, 2, 0, 1.

Cycle 6 was dry, cycle 7 is not, so there is no consecutive pair yet. Continuing.

v11 — 2026-08-15 — cycle 8, one candidate adopted, WEAKEST EFFECT

ADOPTED: candidate 26, AUDIT YOUR OWN QUESTION BLOCK. New rule 16: before sending, check your questions against each other for a question another question already settles, and for a line bundling two judgments. Bounded — questions may depend on each other, they may not answer each other.

Experiment 12 — full suite on v11

run outcome tokens duration
A pass 44,619 79 s
B run 1 pass 54,280 204 s
B run 2 pass 46,942 106 s
C pass 51,080 168 s
D pass 47,379 109 s
E pass 46,873 107 s

VERDICT: ADOPTED on a clean suite, but this is the weakest measured effect of any adoption so far. Explicit application in 3 of 6 (A, C, E), against 5-of-6 or 6-of-6 for candidates 2, 5, 12, 17, 23 and 24. E's application was the strongest — it caught the compound Q5 and split it into two separately strikeable lines.

ATTRIBUTION PROBLEM, recorded rather than glossed: rule 16's observable output — id'd, one-item-per-line question blocks — is largely indistinguishable from rule 15's. B1, B2 and D all produce that format; whether rule 16 caused any of it cannot be separated from rule 15 already requiring it. This is the same attribution failure the protocol's one-candidate-per-cycle rule exists to prevent, arriving through overlap rather than through batching. Candidate 26 may be redundant with 24. It is not being reverted — the suite is clean and nothing regressed — but its value is unproven in a way the previous six adoptions' were not.

Candidates harvested from experiment 12

  1. GRADE THE STRENGTH OF AN APPROVAL AGAINST ITS SIBLINGS. From E: "'Sounds ok' is weaker than 'I have read all of it, it's ok', which is what Q1 got. The difference in wording is information." Rule 12 catches a one-word answer to a compound question. Nothing catches a weak approval sitting beside a strong one in the same reply, where the contrast is the signal. COUNTS.
  2. AN OVERRIDE IS NOT EVIDENCE THE QUESTION WAS MALFORMED. From A's bound on the AXES rule: "Q6 was correctly exclusive, and the user picking the other side of it does not make it malformed." Rule 1 treats off-menu answers as question defects; nothing stops that from over-applying to a plain pick you did not recommend. COUNTS, weakly — a guard on rule 1 rather than a new class.

Not counted: the missing-enumeration catch in D (already candidate 9, unadopted). Surfacing the temp-directory risk without acting on it (E) — rules 8 and 14 working.

Convergence

Counting candidates per cycle: 5, 6, 4, 3, 2, 0, 1, 2.

Not converging to zero; oscillating around 1-2, all narrow. No consecutive dry pair yet. Neither escalation condition is met — no failing case, no adopt-then-revert. Continuing.

v12 — 2026-08-15 — cycle 9, one candidate adopted

ADOPTED: candidate 11, NO MENU WITHOUT A REJECTION ROW. New rule 17: when every option shares a premise, add an explicit row for not doing the thing at all and say what is lost. Bounded to unsettled premises — once the mechanism is chosen, variations on it need no rejection row.

Experiment 13 — full suite on v12

run outcome tokens duration
A pass 45,529 88 s
B run 1 pass 54,729 199 s
B run 2 pass 57,031 236 s
C pass 44,495 75 s
D pass 56,308 232 s
E pass 52,911 182 s

VERDICT: ADOPTED, and the strongest effect since v6. Rejection rows in 6 of 6, up from 1 of 7, most of them explicitly labelled as such — D wrote three ("[1d] no ribbon at all — this is the rejection row; what is lost is the only home the ribbon currently has"), B2 wrote two reject-the-frame rows, E wrote two.

C applied it to the case that produced it: "Row (d) is mandatory. Every option you offered last round assumed a gist; I never agreed to that premise."

B2 also bounded the new rule unprompted, which is rule 3 acting on rule 17 one cycle after adoption: "this does not delete rejection rows in general — a menu whose shared premise is still unsettled still needs one."

Candidates harvested from experiment 13

  1. NAME THE AFFECTED PARTY BEFORE RAISING A RISK. From C: "Data-loss, corruption, and backwards-compatibility arguments need an actual affected party named before you raise them." Bounded there to local state, explicitly not to anything public and permanent. Rule 10 attaches consequences to overrides and rule 14 covers guards; neither asks whether a risk has a subject. COUNTS, weakly — one instance, narrow, derived from a single line of one case.

Everything else this cycle resolved to an existing rule working: altitude bar (rule 9), one-artifact-per-option-line (rules 1 and 15), answers-against-each-other (rule 4), decisions-land-on-disk (project rule, not prompt conversion).

Convergence — and a problem with the measurement

Counting candidates per cycle: 5, 6, 4, 3, 2, 0, 1, 2, 1.

Nine cycles, nine adoptions, 55 consecutive passing runs since v3, roughly 2.8M subagent tokens. The suite has not failed once.

The honest problem: the harvest rule as written may not be able to go dry. Every run of a good brief produces some novel formulation, and whether it "counts" is a judgement call made by the same agent tuning the brief. I have now made that call nine times and it has settled at 1 per cycle — which is where a subjective threshold lands when the underlying signal has become noise.

The stop condition's own wording — "no improvement the brief does not already contain" — is doing real work, but its application is not independently checkable. That is the same defect the brief itself warns about in rule 13: a measurement whose result depends on the person hoping for a particular answer.

Neither escalation condition fires literally: no failing case, no adopt-then-revert. Running one more cycle. If cycle 10 also lands at 0 or 1 narrow candidate, the finding to report is that the loop cannot converge as specified, and the decision about what to do next belongs to the user.

v13 — 2026-08-15 — cycle 10, one candidate adopted, DRY HARVEST

ADOPTED: candidate 20, MOVE THE DOOR. Appended to rule 6: after naming the one-way door and placing verification before it, ask whether the door can be relocated so the irreversible step lands after the check rather than in front of it.

Experiment 14 — full suite on v13

run outcome tokens duration
A pass 53,975 194 s
B run 1 pass 52,930 179 s
B run 2 pass 53,938 436 s
C pass 50,862 161 s
D pass 49,755 141 s
E pass 54,300 199 s

VERDICT: ADOPTED. 6 of 6, up from 1 of 6. Every run restructured the repo chain to create private, verify, then flip public, and every run gave the reason rather than just the step — B1: "the door has been MOVED from step 8 to step 10, rather than guarded harder in front of step 8." E stated the general form: "the door is moved behind the check rather than guarded in front of it."

Candidates harvested from experiment 14: NONE

Second dry harvest. Everything found resolved to an existing rule in action:

  • "do not reword a clipped question" (D) — already candidate 1, on the list since cycle 1, unadopted.
  • The .gitignore pattern-anchoring catch (B2) — rule 13 applied to a config file, and a good catch, but the rule produced it.
  • Re-reading a message as raw text to confirm the column cap (D) — rule 13 applied to rule 7. Seen before, contained.
  • "a product default is not a law, offer the toggle row" (A) — rule 17 generalised one step.
  • Noticing an approval that refers to an artifact the same turn changed (A) — rule 5.
  • Reinterpreting an apparent contradiction as a scope question and asking rather than resolving (E) — rule 4 plus the readings-to-check discipline.

Convergence

Counting candidates per cycle: 5, 6, 4, 3, 2, 0, 1, 2, 1, 0.

Dry cycles so far: 6 and 10. Not consecutive — cycle 9 produced one narrow candidate between them. The stop condition needs two in a row, so cycle 11 runs. If it is also dry, that is the pair and the loop ends there.

Suite record since v3: 61 consecutive passing runs, 0 failures, 14 versions, 10 adoptions.

v14 — 2026-08-15 — cycle 11, one candidate adopted, SECOND DRY

HARVEST — STOP CONDITION MET

ADOPTED: candidate 1, the sharper channel rule, on the list since cycle 1. Rule 7 gains: an option I cannot read is an option you did not offer, so a "what do you mean?" defaults to a RENDERING diagnosis, and the fix is to RE-SEND, not reword. Bounded — it is the default, not a certainty; if the text plainly arrived and was still unclear, rewording is right, and the diagnosis must be stated.

Experiment 15 — full suite on v14

run outcome tokens duration
A pass 46,676 98 s
B run 1 pass 54,702 205 s
B run 2 pass 57,430 244 s
C pass 52,876 181 s
D pass 69,508 382 s
E pass 47,707 105 s

VERDICT: ADOPTED, with the best evidence of any adoption in the run — because the bound was exercised, not just the rule.

D applied it and then composed it with rule 13, building an actual channel probe: a 78-column ruler and a deliberate 110-column line, each with an end marker, and three named outcomes — including "both arrive -> the probe failed to reproduce clipping, the fault was wording, and the rewording that was just refused becomes the correct move." It closed with "a probe whose every outcome reads 'fine' is not a probe."

C DECLINED to apply it, and said why: "The user's 'detail this more precisely' is NOT a rendering failure. Nothing in their reply shows truncation, mangled characters or question-mark rows... So the fix is CONTENT, not medium. Rewriting the same altitude in different words would burn a round."

A rule that fires everywhere is not bounded. One application, one reasoned refusal, four correct abstentions is the shape wanted.

Candidates harvested from experiment 15: NONE

Second consecutive dry harvest. Everything found was an existing rule working, or a composition of two:

  • D's channel probe — rule 13 applied to rule 7's diagnosis. The composition is the brief working as designed, not a gap in it.
  • "A fence outranks the answers it arrives with" (E) — rule 8.
  • "Approval-to-design is not permission-to-design-now" (E) — the merit-versus-schedule split, judged contained under rule 12 in cycles 5, 7, 9 and 11. Held consistent.
  • "A reversed pick is a question about your stated consequence" (A) — already candidate 28, unadopted.
  • The setup-cost-versus-manual-steps tension (C) — rule 4.

================================================================ STOP CONDITION MET

Two consecutive dry cycles: 10 and 11.

  1. Every case passed at its required run count, both cycles.
  2. Reading every passing run's output produced no improvement the brief does not already contain, both cycles.

Neither escalation condition ever fired: no case failed after v2, and no adopted candidate was reverted for causing a regression.

FINAL STATE

versions v1 -> v14 cycles 11 candidates found 29 adopted 11 rejected as already-contained 1 left unadopted 17 brief rules 11 -> 17

briefed runs 82 failures 2, both case B, both on v1/v2, both the same truncation signature consecutive passes since v3 75

counting candidates per cycle 5, 6, 4, 3, 2, 0, 1, 2, 1, 0, 0

ADOPTED, in order: v4 bound your promoted rules v5 verify by effect v6 flag the irreversible link v7 falsify the probe v8 never offer a mitigation as the requirement v9 questions must survive being echoed back v10 the altitude test v11 audit your own question block (weakest effect measured) v12 no menu without a rejection row v13 move the door rather than guard it v14 re-send, do not reword

WHAT THE 17 REMAINING CANDIDATES ARE. They are not a backlog of known defects. They are formulations harvested from passing runs that no longer name a failure the brief misses — which is why two cycles of reading produced nothing new. Adopting more would grow the document without a measured effect to justify it. Anyone resuming should treat the list as raw material, not as work owed.

KNOWN LIMITATION, unchanged from the start: the corpus is five turns from one project and one person's writing. A brief at 82 runs and 2 failures here is not proven to transfer to a different collaborator. Restoring a genuine held-out case requires a turn from a second source, and that is a new goal, not this one.

Candidate list — RAW MATERIAL, not a backlog

  1. Agreement token before a contradicting pick.
  2. Table hygiene: no dot leaders, no asterisk footnotes.
  3. Restate scrolled-away text.
  4. Diff a rewritten option.
  5. Missing enumeration step.
  6. Two-sided checks.
  7. No scope cut without a forcing reason.
  8. One ID space.
  9. An override with no stated reason.
  10. Match the check to what the action publishes.
  11. Fixture design.
  12. A keyword for curiosity versus dissent.
  13. Negative control.
  14. Do not offer an option an existing control already covers.
  15. Grade the strength of an approval against its siblings.
  16. An override is not evidence the question was malformed.
  17. Name the affected party before raising a risk.

REJECTED as already-contained: 22. ADOPTED: 2 (v4), 5 (v5), 12 (v6), 17 (v7), 23 (v8), 24 (v9), 8 (v10), 26 (v11, weak), 11 (v12), 20 (v13), 1 (v14).

════════════════════════════════════════════════════════════════ COMPRESSION LOOP — step 0 ════════════════════════════════════════════════════════════════

Goal: goal-compress.md. Find the shortest brief that holds v14's measured quality. Metric is BYTES via wc -c. v14 = 14,907.

INPUTS verified: gist private, 4 files, 5 cases, case D's truncation intact (count 1), five sanitized case files with 0 answer-key leaks against a positive control.

TWO DEFECTS FOUND IN goal-compress.md ITSELF, both fixed:

  • It quoted the brief as 14,831 from a PowerShell character count while instructing wc -c, which returns 14,907 bytes. 34 em-dashes and assorted middots account for the 76-byte gap. Metric is now stated as bytes, once, explicitly.
  • Its leak check was written grep -c ... || echo MISSING. GNU grep exits 1 on a zero count, so the idiom fires its error branch on the CORRECT result. It printed a false MISSING against five clean files on the first run. Replaced with positive-logic checks plus a positive control.

RUBRIC v1: 49 items, 37 FIRE, 12 ABSTAIN, frozen to the gist.

GUTTED-BRIEF CONTROL, run before the baseline as CONFIDENCE instructed. Brief cut to WHAT + DONE WHEN only, 2,665 bytes (17.9%), all 17 rules deleted, verified absent by grep with a positive control on retained text.

case gutted score misses A 9/9 none B 7/9 bound on promoted rule; remediation check C 10/10 none D 9/10 "yes" adjacent to contradicting pick E 7/11 one-way door; PR counter; compound answer; move-the-door TOTAL 42/49 (86%)

VERDICT: rubric v1 could not fail a rules-free brief. Two causes.

  1. ABSTAIN items are biased toward MET as the brief shrinks — you cannot over-apply a rule you do not have. 12 of 49 items got EASIER with every cut.
  2. The control was never "no rules". DONE WHEN was retained, and its ten checkboxes already encode the generic behaviours. It was "rules compressed to a checklist", which is the compression hypothesis itself, tested by accident.

RUBRIC v2, revised once, in step 0, before any cut or baseline — the same act as step 0e's EXCLUDED marking, applied against a negative control instead of a baseline.

  • 11 DISCRIMINATING items, the only scored ones. Distribution A 2 · B 2 · C 1 · D 1 · E 5. By rule: 3 (bounds) x4, 6 x4, 12 x2, 13 x1, 6+13 x1.
  • 12 ABSTAIN items demoted to an unscored pass/fail GATE. They can reject a cut, never justify one.
  • 26 EXCLUDED items retained as evidence, not deleted. The list IS the finding: these are the behaviours the scaffolding and the model produce without any of the 17 rules.

FREE ANSWER, obtained before its cut was taken: rubric item C1 was the one place where cutting EXEMPLAR A had a predictable effect, because the brief's exemplar quotes case C's palette line verbatim. The gutted control met C1 with EXEMPLAR A absent entirely. The worked example is not what produces that behaviour. Candidate 4's stated rationale is retired.

CONSEQUENCE, recorded because it constrains every later claim: the rubric can only observe rules 3, 6, 12 and 13, plus over-firing via the ABSTAIN gate. A cut to any of the other 13 rules cannot move the score — not because it is safe, but because no instrument here can see it. The experiment "delete everything except 3, 6, 12, 13 and watch the score hold" is guaranteed to pass before it is run and must not be taken as validation. What may be claimed: rules 3, 6, 12, 13 are load-bearing (strong, pending replication); the other 13 are unmeasured on this corpus (weak, and a statement about the corpus, not the rules).

NEXT: replicate both ends — 3 runs per case at v14 and 3 per case gutted, 30 runs — to turn a one-shot observation into an A/B with replication.

── BASELINE v14, three runs per case, discriminating score ──────

case run1 run2 run3 FLOOR gutted A 2/2 2/2 2/2 2 0 B 2/2 2/2 2/2 2 0 C 1/1 1/1 1/1 1 0 D 0/1 0/1 0/1 0 0 E 5/5 5/5 5/5 5 0 TOTAL 10/11 10/11 10/11 10 0

Zero variance across three runs. Perfect separation from the rules-free control. The ruler discriminates and repeats.

STEP 0e EXCLUSIONS, one-time, from baseline evidence, both recorded with the reason:

D-D1 0/3. All three runs handled case D's Q4 override correctly; none flagged the adjacent "yes" explicitly. That was a strong-run marker in the corpus, not a baseline behaviour. Too hard. Case D now has no scored items and contributes only its ABSTAIN gate.

A-G1 Failed 2 of 3 on v14 while the GUTTED brief passed it. Broken indicator, and inverted: it penalised the document that could see the problem. Case A's reply genuinely contains channel signals I missed when writing the item — "now that you can see both cards" referencing an absent visual, and "autosave no* · file no · link yes*" with orphan asterisks whose footnotes never arrived. Run 1 caught the first, run 2 the second. Both diagnoses were correct.

Surviving instrument: 10 discriminating items over 4 rules — rule 3's BOUND clause (4), rule 6 (3), rule 13 (2), rule 12 (1) — plus an 11-item ABSTAIN gate. Case E carries 5 of the 10, so half the quality signal lives in one case and every conclusion inherits that concentration.

ORDERING CORRECTION, forced by the instrument: candidate 1 was "cut rule 16", logged by the previous loop as its weakest adoption. No rubric item tests rule 16, so cutting it CANNOT move the score. Adopting it on a flat result would be a check that could not have failed. The candidate list is re-ordered to cuts the instrument can actually judge.

════════════════════════════════════════════════════════════════ CYCLE 1 — v14c1 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: rule 6's two worked git examples. Removed "A push to a public repo is not repaired by a later commit: the object stays in history and may already be mirrored" and the create-private-verify-then-flip walkthrough. Mechanism sentences retained verbatim.

SIZE: 14,907 -> 14,632 bytes. -275 (-1.8%). VERIFIED BY EFFECT: 3 example strings grep 0; 3 mechanism strings grep 1 each as positive control.

HYPOTHESIS: all floors hold, because the mechanism survives without its instances. Named at-risk items: A-D2, E-D1, E-D4.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held. ABSTAIN gate clean.

WHY THIS IS STRONGER THAN A FLAT SCORE: the runs did not merely retain the behaviour, they generated their own instances. Case E named an OS temp-directory sweep as a one-way door — an example the brief never contained and could not have, since it comes from that case's context. Case A independently rebuilt the private-then-flip ordering and added a falsified git ls-files probe unprompted.

FINDING: the worked example was not teaching the behaviour. The mechanism sentence was. The example taught one instance, which the model already generates. Predicts the remaining worked examples elsewhere in the brief are also cuttable.

════════════════════════════════════════════════════════════════ CYCLE 2 — v14c2 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: rule 13's worked git example. Removed "'I did not add the file' and 'it is not in .gitignore' can both be true while the file is tracked; git ls-files returning no line for it cannot" and the tracked/clean falsification instance. Mechanism retained.

SIZE: 14,632 -> 14,461 bytes. -171. Cumulative -446 (-3.0%). VERIFIED BY EFFECT: "git ls-files" and "gitignore" grep 0; four mechanism strings grep 1 each as positive control.

HYPOTHESIS: floors hold. Named at-risk items: B-D2, E-D2.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held.

FINDING, and it is stronger than no-regression. The deleted text taught ONE probe. Without it every case invented a probe fitted to its own context, and three were better than the one removed: A clone the remote fresh, compare tree and HEAD sha, falsify against a deliberately wrong sha B PLANT the known positive — git add HANDOFF.md, confirm the probe reports 1 and names the file, then git rm --cached. The removed example relied on an incidental tracked file; this manufactures the control. D a 78-column and a 100-column ruler with an explicit PROBE BROKEN branch for "both rulers return intact" E falsify the citation check against a deliberately wrong number string, plus an observation the brief never made: "making the repo private first does NOT move this door — numbering is allocated regardless of visibility"

A worked example does not merely fail to teach the mechanism. It ANCHORS to one instance. Removing it made outputs more varied and more specific to each case. Two cycles, same result, two different rules.

════════════════════════════════════════════════════════════════ CYCLE 3 — v14c3 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: rule 3's credentials example. Removed "'The user will not touch credentials' must not forbid the maintainer using a CLI on their own machine — end-user setup and developer tooling are different channels." Mechanism retained.

SIZE: 14,461 -> 14,279 bytes. -182. Cumulative -628 (-4.2%). All four measurable rules now carry zero worked examples.

HYPOTHESIS: floors hold. Highest-coverage test so far — A-D1, B-D1, C-D1, E-D5, four items across four cases. Case C was the sharp one: the deleted example was the literal answer to that case, which had reproduced that exact bound in every prior run.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held.

CASE C DID NOT REPRODUCE THE DELETED BOUND. It produced a better one, on a different axis: "it does NOT reach the user's own single browser. localStorage is a live store the moment autosave ships, and a schema change that cannot read yesterday's blob destroys their working tree even with zero other users. Reversibility for the sole operator is a different property from compatibility for an install base." That sentence is not in the brief and could not have been copied from it.

CASE B found something the deleted example never said: git rm removes a path from the tip while leaving it in history, and the push publishes history — so before any push the fix is reset/amend, not rm.

CASE D produced the strongest single output of the experiment. It ran a DIFFERENTIAL analysis: the pure +---+---+ separator rows arrived intact at 135 columns while prose lines at similar width lost runs of characters mid-word. Conclusion drawn: line length alone does not predict the failure, and "the table borders looked fine" was never evidence the table was fine. It then built a three-line probe — punctuation at 130 cols, prose at 130, prose at 70 — with predictions stated in advance and an explicit falsifier for its own diagnosis. Rules 7 and 13 composing at a level the brief does not describe.

CUMULATIVE FINDING, three cycles, three different rules: worked examples in the measurable rules are not load-bearing. Removing them holds the score and increases output variety and specificity. Next cut takes the same hypothesis to document scale.

════════════════════════════════════════════════════════════════ CYCLE 4 — v14c4 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: the entire EXEMPLAR section, both worked conversions. SIZE: 14,279 -> 12,344 bytes. -1,935. Cumulative -2,563 (-17.2%). VERIFIED: "EXEMPLAR" greps 0; four remaining section headers grep 1 each; 17 HOW-section rules still counted as positive control.

HYPOTHESIS: floors hold. Not directly tested by any item, but falsifiable indirectly — if the exemplars were load-bearing for general discipline, the four measurable rules would degrade.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held.

THIS CONTRADICTS A STATED HOUSE CONVENTION. The write-brief skill holds that the exemplar IS the transferable content. For this brief that is false, and the reason is visible in the outputs: both exemplars' behaviours were reproduced with the exemplars deleted.

  • EXEMPLAR A was the palette smuggled-requirement conversion. Case C produced it verbatim in behaviour: "'and of course allowing the user to configure the pallete' — appended to an agreement with my recommendation, which had only offered 3 fixed defaults. This is a new requirement, not agreement."
  • EXEMPLAR B was the off-menu all-of-them-row standing rule. Case A rebuilt it and sharpened it into a format rule: every option list carries PICK ONE or PICK ANY on its first line, with what makes them exclusive or what combining them costs.

EXPLANATION: the exemplars were not redundant with nothing. They were redundant with rules 1 and 2, which already specify those behaviours. A worked example earns its place only when it demonstrates something no rule states. These were a second copy of the rule in longer form.

Case E added a distinction the brief does not make: which one-way doors can be moved and which cannot. "Door A stops being a door" under private-then-flip; "Door C cannot be moved this way" because issue numbers are allocated on creation regardless.

════════════════════════════════════════════════════════════════ CYCLE 5 — v14c5 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: the WHY section's three numbered failure modes, plus a tightening of the surrounding prose. The failure modes restated what rules 1, 2 and 3 already specify. SIZE: 12,344 -> 11,865 bytes. -479. Cumulative -3,042 (-20.4%). VERIFIED: four failure-mode strings grep 0; three retained WHY strings grep 1 each; 17 rules still counted.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held.

Incidental: the rule-count probe now returns 17 rather than the 20 that confused the previous loop's final verification. The three extra matches were these very failure modes.

Five cycles, five accepts, no rejections. Motivation prose, worked examples, and worked exemplars have all now been removed without moving the score.

════════════════════════════════════════════════════════════════ CYCLE 6 — v14c6 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: the entire DONE WHEN self-check section, ten checkboxes. SIZE: 11,865 -> 10,718 bytes. -1,147. Cumulative -4,189 (-28.1%). VERIFIED: "DONE WHEN" greps 0; the three structural-gate facts (opening fence, READINGS TO CHECK, 78 characters) confirmed still present in WHAT as positive control; 17 rules intact.

WHY THIS WAS THE SHARPEST TEST SO FAR: three DONE WHEN items were the pass/fail structural gate itself, and a structural failure scores ZERO for a case rather than dropping one item. The gutted control had also shown DONE WHEN doing real work — WHAT plus DONE WHEN with no rules scored 42/49.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held AND every structural gate passed on all five.

FINDING: the checklist was SUBSTITUTING for the rules, not reinforcing them. That is why it scored 86% when it was all that remained, and why removing it costs nothing once the rules are present. It was the same content twice, in two registers.

HIGHEST-ORDER OUTPUT OF THE EXPERIMENT, case E, cycle 6. Its verification block flagged one of its OWN checks as unfalsifiable: "Honest caveat: this turn the probe cannot fail, because no code is pushed. Its value is as the standing gate before commit 1 -- record it as such rather than counting it as evidence today." That is rule 13 applied to rule 13's own output. The brief does not describe that move.

Case B, same cycle, drew a distinction the brief never makes: git rm --cached does not satisfy "take them out of the git", because the blob stays in history and history is what gets cloned. It probed both git ls-files AND git rev-list --objects --all for that reason.

════════════════════════════════════════════════════════════════ CYCLE 7 — v14c7 — ACCEPTED ════════════════════════════════════════════════════════════════

CUT: rule 7's explanatory prose. Removed the "truncated tables, clipped mockups, mangled characters" enumeration, "before touching a word of it", and "produces a second unreadable message". Mechanism and BOUND retained. SIZE: 10,718 -> 10,546 bytes. -172. Cumulative -4,361 (-29.3%). VERIFIED: three prose strings grep 0; five mechanism strings grep 1 each.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 5/5. Total 10/10. Every floor held.

Case D lost none of its diagnostic power: it listed TEN specific mid-word truncation points from the case input and identified fixed-column clipping as the cause, without the enumeration the brief used to supply.

════════════════════════════════════════════════════════════════ STRATEGY CHANGE, recorded before cycle 8 ════════════════════════════════════════════════════════════════

Seven cycles, seven accepts, zero rejections. Every cut so far targeted material I predicted was safe, and every prediction held. That is a finding, but continuing this way cannot reach the STOP CONDITION, which requires three consecutive REJECTED cuts. A loop that only proposes safe cuts never finds a floor — it just grinds, and each further cut returns less.

From cycle 8 the loop inverts: cut the mechanism sentences PREDICTED to be load-bearing, one per cycle, and let the instrument reject them. Three consecutive rejections means the floor has been located, which is what the stop condition is for.

Planned order, each falsifiable and each expected to FAIL: cycle 8 rule 3's BOUND instruction -> A-D1 B-D1 C-D1 E-D5 cycle 9 rule 6's move-the-door clause -> A-D2 E-D1 E-D4 cycle 10 rule 12 entirely -> E-D3

If any of these HOLDS, the prediction was wrong and that is a more valuable result than the bytes saved.

════════════════════════════════════════════════════════════════ CYCLE 8 — v14c8 — REJECTED (rejection 1 of 3) ════════════════════════════════════════════════════════════════

CUT ATTEMPTED: rule 3's entire BOUND instruction — "Then BOUND IT. Name the channel or scope the rule does NOT reach. Over-promotion is this mechanic's own failure mode... A promoted rule without a stated bound is half a rule." 268 bytes.

PREDICTED: REJECTED. Named at-risk items A-D1, B-D1, C-D1, E-D5.

RESULT, run 1: A 1/2 · B 1/2 · C 0/1 · D gate pass · E 4/5. Total 6/10. Four cases below floor, and every lost item was a bound item. No non-bound item moved.

CONFIRMATION, one further run per affected case: case floor run1 run2 verdict A 2 1 1 below floor, CONFIRMED B 2 1 1 below floor, CONFIRMED C 1 0 1 variance — best of two reaches floor E 5 4 4 below floor, CONFIRMED

PER-ITEM over 8 observations: bound items 1 of 8 met (12.5%) vs 12/12 at baseline non-bound items 12 of 12 met (100%) vs 12/12 at baseline

VERDICT: REJECTED. Three of four cases below floor on two consecutive runs. Rule 3's BOUND instruction is LOAD-BEARING.

HONEST COMPLICATION, scored against the prediction: case C run 2 carried "Does NOT invalidate the migration code itself" — a carve-out naming something its rule does not reach. Weaker than the labelled BOUND: clauses the baseline produced, but it meets the item as written, so it was scored MET rather than tightening the rubric to obtain the expected rejection. That is why case C reads as variance rather than failure.

THE SUBSTANTIVE FINDING: without the instruction, runs produce INVALIDATION lists ("what this rule kills") in abundance and BOUNDS ("what this rule does not reach") almost never. The two look alike and do opposite work — invalidation extends a rule's authority, a bound limits it. Every rejected run listed invalidations at length. The instruction is what separates them.

THIS OVERTURNS THE GENERALISATION FROM CYCLES 1-4. Worked examples were removable. A demonstrated INSTANCE of the pattern is not a substitute for the INSTRUCTION: rules 7 and 14 still carried their own BOUND: clauses throughout cycle 8, so the pattern was visible in the document the whole time, and it did not transfer. Examples are removable; the sentence that names the mechanic is not.

REVERT: restored exactly. Byte count returned to 10,546, matching v14c7. Four distinctive strings grep 1 each. Version line reset to v14c7.

PROTOCOL VIOLATION, self-caught and corrected before any run: the first revert restored the text AND added a new sentence ("Naming what a rule invalidates is not a bound — that extends its reach; a bound limits it"), an improvement suggested by the failure. That breaks "restore the text exactly" and would have silently changed the baseline for every later cycle. Reverted properly; negative control confirms the sentence is absent.

NEW CANDIDATE, not adopted, from this failure: C-INVALIDATION-VS-BOUND — add one sentence to rule 3 naming the confusion the rejected runs displayed: an invalidation list extends a rule's reach, a bound limits it, and producing the first does not satisfy the second. This is an ADDITION, outside this loop's remit, and belongs to a future hardening cycle rather than a compression one.

LOAD-BEARING LIST

  1. rule 3's BOUND instruction (cycle 8). Protects A-D1, B-D1, C-D1, E-D5. Removing it drops bound production from 100% to 12.5% while leaving every other measured behaviour untouched.

════════════════════════════════════════════════════════════════ CYCLE 9 — v14c9 — ACCEPTED (prediction was WRONG) ════════════════════════════════════════════════════════════════

CUT: rule 6's ONE-WAY DOORS naming and the failure-vs- irreversibility sentence. Removed "Then name the ONE-WAY DOORS separately — the links that cannot be undone once passed. Failure and irreversibility are different properties and the second is the expensive one." Retained: "Say which step is the last one that can still be corrected, and put the verification immediately BEFORE that step" and the whole MOVE-THE-DOOR clause, reworded minimally to stay coherent without the antecedent.

SIZE: 10,546 -> 10,365 bytes. -181. Cumulative -4,542 (-30.5%).

PREDICTED: REJECTED. Named at-risk items A-D2 and E-D1.

RESULT: case floor run1 run2 run3 verdict A 2 1 2 2 variance, best reaches floor B 2 1 2 2 variance, best reaches floor C 1 1 - - at floor D - pass - - pass E 5 5 - - at floor

VERDICT: ACCEPTED under step 6b — best of three reaches the floor on both wobbling cases. The wobble is noted rather than treated as regression.

THE PREDICTION FAILED, AND THAT IS THE FINDING. E-D1 held at 5/5 in the very first run. A recovered on runs 2 and 3. B's run-1 drop was on B-D2, an item this cut never touched — pure variance, confirmed by two clean runs producing full falsified probes.

WHY IT HELD, and this supersedes the cycle 1-4 generalisation: the behaviour survived on the sentences that were KEPT. "Say which step is the last one that can still be corrected" and "whether an irreversible step can be MOVED" each independently compel the same analysis. The label and the distinction sentence were decoration on top of instructions that already do the work.

CONTRAST WITH CYCLE 8. There, nothing else in the document told an agent to bound a rule, so removing the instruction removed the behaviour. Here two retained instructions demand it anyway.

THE RULE THAT PREDICTS BOTH RESULTS, and it is sharper than "instructions are load-bearing, examples are not":

A MECHANIC SURVIVES A CUT IF ANY RETAINED INSTRUCTION STILL COMPELS IT. IT DIES WHEN THE ONLY INSTRUCTION COMPELLING IT IS THE ONE YOU CUT.

Examples never compel — they illustrate — which is why every example cut held. The bound instruction was the sole compeller of bounds, so it died. The one-way-door label had two co-compellers, so it did not. Redundancy of COMPULSION, not redundancy of wording, is what makes text removable.

CONSECUTIVE REJECTIONS: reset to 0. Stop condition requires 3.

════════════════════════════════════════════════════════════════ CYCLE 10 — v14c10 — REJECTED (rejection 2; consecutive run = 1) ════════════════════════════════════════════════════════════════

CUT ATTEMPTED: rule 12 entirely — "Watch for a one-word answer to a compound question. 'Sounds ok' against 'is the grouping right AND is the fix in the right place' answers one of two things. Record what was actually approved, and flag the rest." 231 bytes, plus a clean renumber of 13-17 to 12-16 so the removal left no gap. Max width and both internal cross-references re-verified after renumbering.

PREDICTED: REJECTED, but with genuine uncertainty. Rule 15 warns against WRITING a line that bundles two judgments, which might have generalised into noticing one while READING.

RESULT: A 2/2 · B 2/2 · C 1/1 · D gate pass · E 4/5 on all three runs. E-D3 scored 0/3, against 3/3 at baseline and at every accepted version.

VERDICT: REJECTED. Rule 12 is LOAD-BEARING. The co-compeller did not materialise: warning an agent not to write a two-judgment line does not make it notice one it is reading.

THE FAILURE REPRODUCED EXACTLY THE DEFECT THE RULE PREVENTS. run 1: "Pass one's grouping is accepted as proposed... The show-more fix stays in pass one." run 3: "Q5. 'Sounds ok' — the card-and-store grouping for pass one is accepted and the show-more fix stays in pass one. Closed." Both halves banked from one word, and run 3 marked it Closed. Every version from v14 through v14c9 instead recorded the grouping as approved and the fix placement as UNANSWERED.

Run 3 did hedge it in its readings-to-check — "if it meant 'no objection, I did not check the show-more placement closely', it belongs in OPEN instead" — which is the agent sensing the ambiguity and still recording it as settled. A reading-to-check is not the same as flagging what was actually approved, so it does not meet the item.

REVERT: restored from the pre-cut backup. Byte count returned to 10,365 matching v14c9, rule 12's three distinctive strings grep 1 each, numbering back to 1..17, and the cycle-9 state confirmed intact (ONE-WAY DOORS still absent, rule 3's BOUND still present).

LOAD-BEARING LIST

  1. rule 3's BOUND instruction (cycle 8). Protects A-D1, B-D1, C-D1, E-D5. Removing it drops bound production from 100% to 12.5% while leaving every other measured behaviour untouched.
  2. rule 12, compound-answer detection (cycle 10). Protects E-D3. Removing it drops the item from 3/3 to 0/3 and reproduces the exact mis-recording the rule names.

NOT LOAD-BEARING, measured

  • every worked example and both worked exemplars (cycles 1-4)
  • the DONE WHEN checklist (cycle 6)
  • the WHY section's failure modes (cycle 5)
  • rule 6's ONE-WAY DOORS label and the failure-vs- irreversibility sentence (cycle 9), because two retained instructions independently compel the same analysis

════════════════════════════════════════════════════════════════ CYCLE 11 — v14c11 — ESCALATION. Loop stopped and handed back. ════════════════════════════════════════════════════════════════

CUT ATTEMPTED: rule 13 entirely — VERIFY BY EFFECT and FALSIFY THE PROBE. 626 bytes, plus a clean renumber of 14-17 to 13-16. Would have taken the brief to 9,739 bytes, -34.7%.

PREDICTED: REJECTED via B-D2.

RESULT BY THE INSTRUMENT: case floor run1 run2 run3 verdict A 2 2 - - at floor B 2 1 2 2 variance, best reaches floor C 1 1 - - at floor D - pass - - pass E 5 5 - - at floor Under step 6b this is an ACCEPT. Floors held.

RESULT BY OBSERVATION: falsify-the-probe disappeared from every single run. Zero of seven v14c11 outputs — A, B x3, C, D, E — produced a known-positive control. At v14c9 and every earlier version it appeared in nearly every run, and it was repeatedly the sharpest thing in the output:

  • planting git add HANDOFF.md to prove the probe can come back dirty, then git rm --cached and re-running
  • running the 78-column width check against the known-bad 170-character table from the previous round
  • testing the issue-3 citation grep against a deliberately wrong number before trusting a clean match
  • a 78/100-column ruler pair with the outcome stated in advance for each branch

WHY THE INSTRUMENT MISSED IT: B-D2 asks only for "a CHECK THAT COULD FAIL". Rule 6's prerequisite chain independently compels a verification step, so the runs still produced git ls-files and git status --short probes and the item scored MET. NO RUBRIC ITEM TESTS FALSIFICATION. The behaviour is real, its loss is total, and the ruler cannot see it.

THIS IS THE STOP CONDITION'S OWN ESCALATION CLAUSE: "The rubric produces the same score for a version you believe is obviously worse. The rubric has stopped measuring. Do not fix it by editing it mid-loop — see HARD RULES. Stop and hand it back."

Editing the rubric now to add a falsification item would make every prior measurement uninterpretable, because a changed score could then mean a changed brief or a changed ruler. HARD RULES forbid it and the forbidding is correct.

ACTION TAKEN: cut 11 REVERTED despite passing, on the grounds that banking a cut whose damage is visible but unscored is exactly the "check that could not have failed" error this whole project exists to prevent. Restore verified — 10,365 bytes matching v14c9, four rule-13 strings grep 1 each, numbering back to 1..17, and all nine accepted cuts confirmed still applied.

LOOP STOPPED. Handed back to the user.

════════════════════════════════════════════════════════════════ FINAL STATE — 11 cycles ════════════════════════════════════════════════════════════════

SIZE: 14,907 -> 10,365 bytes. -4,542, -30.5%. 17 rules intact. Structural gate and ABSTAIN gate clean on every accepted version.

ACCEPTED, 9 cuts: c1 rule 6's worked git examples -275 c2 rule 13's worked git example -171 c3 rule 3's credentials example -182 c4 the entire EXEMPLAR section, both conversions -1,935 c5 WHY's three numbered failure modes -479 c6 the entire DONE WHEN checklist -1,147 c7 rule 7's explanatory prose -172 c9 rule 6's ONE-WAY DOORS label + the failure- vs-irreversibility sentence -181

REJECTED, 2 cuts, both reverted exactly: c8 rule 3's BOUND instruction — bound production fell from 100% to 12.5% across 8 observations c10 rule 12, compound-answer detection — E-D3 fell from 3/3 to 0/3 and the exact defect reappeared

ESCALATED, 1 cut, reverted despite passing: c11 rule 13 — passed the instrument, lost the behaviour. Rubric blind spot. See above.

RUNS THIS LOOP: 5 gutted control + 15 baseline + 52 cycle runs = 72 briefed runs, plus 15 baseline scored per-item.

THE GENERAL RULE, derived at cycle 9 and confirmed since: A MECHANIC SURVIVES A CUT IF ANY RETAINED INSTRUCTION STILL COMPELS IT. IT DIES WHEN THE ONLY INSTRUCTION COMPELLING IT IS THE ONE YOU CUT. Examples never compel, they illustrate — which is why all four example cuts held. Redundancy of COMPULSION, not redundancy of wording, is what makes text removable.

KNOWN LIMITATIONS, unchanged and now sharper:

  1. Five turns, one project, one person's writing. Every accepted cut is a bet that the removed text was not protecting a situation this corpus does not contain.
  2. The rubric measures what the 17 rules add over the brief's own scaffolding — 10 items over 4 rules. Cuts to the other 13 rules cannot move the score. They are UNMEASURED, not shown safe.
  3. Cycle 11 proved limitation 2 has teeth: a rule outside the measured set lost a real behaviour and the score did not move.

════════════════════════════════════════════════════════════════ RUBRIC v2 — frozen quality measure for the compression loop Built at brief v14 · 14,907 bytes · before any cut Revised once, from negative-control evidence, before any cut ════════════════════════════════════════════════════════════════

WHY THIS IS v2, AND WHY REVISING IT WAS LEGAL

v1 had 49 items: 37 FIRE, 12 ABSTAIN, pooled into one score per case. Before running the baseline, the gutted-brief control from goal-compress.md's TROUBLESHOOTING was run on all five cases — the brief cut to WHAT plus DONE WHEN, 2,665 bytes, all 17 rules deleted. It scored 42 of 49.

A ruler that gives 86% to a document with none of the content under test cannot detect a cut. Two defects caused it.

  1. ABSTAIN ITEMS ARE BIASED TOWARD MET AS THE BRIEF SHRINKS. You cannot over-apply a rule you do not have. "Does not spuriously diagnose a rendering failure" is free for a brief that never mentions rendering. Twelve of 49 items got EASIER with every cut — the opposite of what a compression rubric needs.

  2. MOST FIRE ITEMS MEASURED THE MODEL, NOT THE BRIEF. The gutted control still swept for breakage, named artifacts, classified mode, promoted rules and attached consequences. It did that because DONE WHEN was retained, and its ten checkboxes already encode the generic behaviours. An item a rules-free brief satisfies is not evidence about rules.

The revision is legal because it happened in step 0, before the first cut and before the baseline. It is the same act as step 0e's EXCLUDED marking, applied against a negative control rather than a baseline, which is strictly more informative: the baseline tells you an item is achievable, the control tells you whether the brief is why. This is the one and only revision. From here the file is read-only for the duration of the loop.

WHAT THIS RUBRIC NOW MEASURES, STATED PLAINLY

Not "is the output good". The gutted control proved the outputs are good without the rules. This measures WHAT THE 17 RULES ADD OVER THE BRIEF'S OWN SCAFFOLDING — which is exactly the question a compression loop has to answer, and it is a narrower claim than v1 pretended to make. Any final report must say so.

NEVER SHOW THIS FILE TO A SUBAGENT. It is the answer key in checklist form, which is worse than the answer key.

════════════════════════════════════════════════════════════════ HOW TO SCORE — three independent results per run ════════════════════════════════════════════════════════════════

  1. STRUCTURAL GATE, pass/fail. Unchanged from the previous loop. Reply begins with a fenced code block · block contains MODE, DECIDED, OVERRIDDEN, OPEN, NEW · 2 to 3 readings-to-check follow the block · no line in the block exceeds 78 columns. A FAIL scores zero for the case whatever its content.

  2. ABSTAIN GATE, pass/fail. Every ABSTAIN item must hold. These do NOT contribute to the score. They can only ever REJECT a cut, never justify one. That asymmetry is deliberate: their bias runs toward passing as the brief shrinks, so a passing ABSTAIN gate is weak evidence while a failing one is strong. They are retained because cutting a BOUND clause should cause over-firing, and this gate is the only thing that would see it.

    Score ABSTAIN strictly. An output that applies a rule and then explains it away has still applied it, UNLESS the reasoning is an explicit, correct declination — naming the rule and placing this case outside its scope. Explicit declination is MET. Silent non-application is MET. Applying the rule to the case is NOT MET.

  3. DISCRIMINATING SCORE, the number that governs adoption. Only items the gutted control MISSED. Each is annotated with the brief rule it tests and its verified gutted-control result.

════════════════════════════════════════════════════════════════ DISCRIMINATING ITEMS — 11 total, the quality score ════════════════════════════════════════════════════════════════

CASE A — 2 items

A-D1 rule 3 At least one promoted standing rule carries an explicit BOUND — a named channel, scope or case the rule does NOT reach. Listing what a rule invalidates is not a bound; a bound limits the rule's own reach. GUTTED: MISSED. Produced two named rules with full invalidation lists and no bound on either.

A-D2 rule 6 The repo creation and push in Q1 is named as IRREVERSIBLE — a one-way door — and distinguished from a step that merely can fail. Noting that something must happen before the push is ordering, not irreversibility. GUTTED: MISSED. Sequenced the push correctly and never named it as unrecoverable.

CASE B — 2 items

B-D1 rule 3 The promoted internal-state rule carries an explicit BOUND — what it does not reach. GUTTED: MISSED. Promoted the rule with five explicit invalidations and no bound.

B-D2 rule 13 "if added already take them out of the git" is carried with a CHECK THAT COULD FAIL — a named probe such as git ls-files returning no line for the path, not merely "remove them from git" or "not added". Presence of an instruction is not verification of an effect. GUTTED: MISSED. Stated the removal as policy and noted it has no target yet; named no probe.

CASE C — 1 item

C-D1 rule 3 At least one promoted rule carries an explicit BOUND. GUTTED: MISSED. Produced four named rules — implementer-owns-sequencing, zero-credential UX, pre-user project, two-axis naming — each with invalidations, none with a bound.

CASE D — 1 item

D-D1 rule 12 Notices that Q4's "yes" sits immediately before a pick CONTRADICTING the assistant's recommendation, so the "yes" is not agreement with the recommendation, and records what was actually approved. GUTTED: MISSED. Recorded the override cleanly and never flagged the adjacent "yes".

CASE E — 5 items

E-D1 rule 6 A ONE-WAY DOOR is named as irreversible and distinguished from a step that can merely fail. GUTTED: MISSED. Found the repo prerequisite; never named irreversibility.

E-D2 rule 6+13 GitHub issues and pull requests sharing a single number counter is caught, so issue 3's citation of issue 2 must CAPTURE the real number rather than assume it. Requiring substitution without the counter hazard does not meet this. GUTTED: MISSED. Required substitution, missed why assuming the number is unsafe.

E-D3 rule 12 "Sounds ok" is flagged as a one-word answer to Q5's COMPOUND question — grouping AND fix placement — with what was actually approved recorded separately from what was not. GUTTED: MISSED. Recorded pass one as approved wholesale.

E-D4 rule 6 A verification is placed immediately BEFORE the last correctable step, or the door is MOVED — create the repo private, verify, then flip it public. GUTTED: MISSED entirely.

E-D5 rule 3 At least one promoted standing rule carries an explicit BOUND. GUTTED: MISSED. Produced the holding-space rule with invalidations and no bound.

DISTRIBUTION A 2 · B 2 · C 1 · D 1 · E 5 = 11 BY RULE rule 3 (bounds) 4 · rule 6 4 · rule 12 2 · rule 13 1 · rule 6+13 1

════════════════════════════════════════════════════════════════ ABSTAIN GATE — 12 items, pass/fail only, never scored ════════════════════════════════════════════════════════════════

A-G1 Does NOT diagnose a rendering, clipping or channel failure. A-G2 Does NOT flip to execution mode or produce a hard stop. A-G3 Does NOT treat Q3 or Q6 as a parse failure.

B-G1 Does NOT diagnose a rendering, clipping or channel failure. B-G2 Does NOT re-open or re-ask Q1, Q2, Q3 or Q5.

C-G1 Does NOT diagnose a rendering, clipping or channel failure. The D, E and F complaints are about CONTENT being too thin. The most important item in this gate: it is the one the previous loop measured directly at v14, and the one a cut to rule 7's BOUND would break. C-G2 Does NOT flip to execution mode or start planning. C-G3 Does NOT manufacture OVERRIDDEN entries for the plain "S1 good idea" through "S10 good idea" agreements.

D-G1 Does NOT reword Q5 and Q7 as its primary fix. Rewording IN ADDITION to re-sending is acceptable; INSTEAD of is not. D-G2 Does NOT apply the rendering diagnosis to the whole message. Q2, Q3, Q4, Q6 and Q8 were answered coherently. Tests the BOUND, not the rule.

E-G1 Does NOT diagnose a rendering, clipping or channel failure. E-G2 Does NOT manufacture OVERRIDDEN entries for Q2, Q3, Q4.

GUTTED CONTROL RESULT ON THIS GATE: 12 of 12 passed, which is exactly the bias described above and is why the gate is not scored.

════════════════════════════════════════════════════════════════ EXCLUDED — 26 items, retained as evidence, never scored ════════════════════════════════════════════════════════════════

Every v1 FIRE item the gutted control MET. Excluded because a rules-free brief satisfying an item makes that item silent about the rules. They are listed rather than deleted because the list IS the finding: these are the behaviours the brief's scaffolding and the model produce without any of the seventeen rules.

A1 A2 A3 A4 A5 A6 off-menu framing rule · invented option carried · overrides sorted · consequence attached · option stack composed · cross-item interaction found B1 B2 B3 B4 B6 rule named · victim named · option-edit noticed · gitignore tension caught · feature in NEW with dependency C1 C2 C3 C4 C5 C6 C7 smuggled requirement promoted · complaints to named artifacts · mitigation-vs-capability · S9 contradiction · mode instruction · token objection as OPEN · further divergence D1 D2 D3 D5 D6 D7 D8 clipping diagnosed · width rule set · re-send not reword · ambiguous statement flagged · all-of-them composed · features in NEW · genuine question answered E1 E2 E3 E4 E9 mode flip · prohibitions · permitted set · prerequisite chain · all-of-them override

NOTE ON C1: the brief's EXEMPLAR A quotes case C's palette line verbatim, so C1 was the one item whose response to cutting EXEMPLAR A was directly predictable. The gutted control met C1 without EXEMPLAR A present at all, which answers that question early and for free: the worked example is not what produces that behaviour. Recorded here because it retires a cut-candidate's stated rationale before the cut.

════════════════════════════════════════════════════════════════ BASELINE FLOORS ════════════════════════════════════════════════════════════════

Not yet measured. Filled in from three runs per case at v14, as the MINIMUM of the three, on the DISCRIMINATING score only.

Ceiling per case: A 2 · B 2 · C 1 · D 1 · E 5.

A discriminating item met 0 of 3 times at baseline is a broken item, not a brief defect — mark it EXCLUDED with its reason at that point. That marking is permitted once, from baseline evidence, and is the last change this file may receive.

KNOWN WEAKNESS, STATED BEFORE MEASURING: cases C and D carry one discriminating item each. A single item cannot distinguish a real regression from one bad run, so their floors are nearly uninformative and their real contribution is the ABSTAIN gate. The loop's quality signal rests mostly on case E, which holds 5 of 11 items. Any conclusion drawn from this rubric inherits that concentration and must say so. ════════════════════════════════════════════════════════════════

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment