---
title: Can a task finish with the codebase cleaner than it started?
kind: paper
version: 1
date: 2026-11-06
authors: [Claude (LIN-4315, implementation), for John Kershaw]
model: "claude-haiku-5-5 (Haiku 5.5), Claude Code CLI, dispatched by Harbour as an implementation (dispatch 385c54e1-20a9-4ae3-b805-467f23eb72a2); effort not recorded in this session. Close-out text fixes by claude-sonnet-5-5 (Sonnet 5.5), Claude Code CLI, dispatched by Harbour as a close-out (dispatch item 354fc849-0f08-49e0-b4d9-fb1bdf1354f2); effort not recorded. Fresh readers (6 Nov, new to this work each time): an accuracy reader checked the paper against the evidence folder at 0fdae4da, 9bc203e5, 63fc0550 and, on the whole file, at 30e47b0a (head 82e9be9b, in review); a reader new to Harbour read it for clarity at 0fdae4da, 9bc203e5 and 30e47b0a. After the review, three further fresh accuracy readers checked the close-out edits: the diff 82e9be9b..70470389 (blob f245e3ed; it found two substantive errors, both fixed in 56edb5fb), the diff 70470389..56edb5fb (blob f4ee91e4; three small citation and wording slips, fixed in 2ad8c6e9), and the diff 56edb5fb..2ad8c6e9 (blob bdbfa007; two wording slips and a nit). Those last three wording edits, the `model:` line and nothing else were then applied and checked by the close-out author against that reader's report; the reader's last blob therefore differs from the merged one by those wording edits and this line. Unchecked by a second measurement."
grounded_at: "LinearViewer 1d10f9b3 and simple-dispatcher 07c88f7 (origin/main, 6 Nov 2026). Evidence frozen 2026-11-06 between 09:05Z and 09:12Z in docs/papers/harbour/cleaner-than-it-started-evidence/2026-11-06/."
cites:
  - "LIN-4150 comments: batch A (5 Nov 07:49), B (07:48), C (07:54), D (07:55), and 38 single or area passes from 09:06 to 21:09 (frozen at cleaner-than-it-started-evidence/2026-11-06/comments/LIN-4150.json)"
  - "docs/plans/survey/place-ledger.md@1d10f9b3:19 (LIN-4178: 'a new twin, invited by the ticket's own wording')"
  - "docs/plans/survey/place-ledger.md@1d10f9b3:106 ('Main question: failed'; the ledger's '+0.37 against +0.38')"
  - "docs/plans/survey/place-ledger.md@1d10f9b3:127 ('From here, the balance column is the blind read')"
  - "docs/plans/survey.md@1d10f9b3:5 (the 17 / 3 / 1 / 0 status, replaced here by a pointer)"
  - "docs/reviews/drift-coherence-review-2026-11-05-run4.md@1d10f9b3:11,29 (the window `2eb73ae0..af55cb73`; overall: better, small)"
  - "docs/reviews/seams-tangles-review-2026-11-05-run8.md@1d10f9b3:9-14,33 (other features: worse as a map; the window and its times)"
  - "docs/reviews/seams-tangles-review-2026-11-05.md@1d10f9b3:22 (run 7's window `d7ceb373..2eb73ae0`)"
  - "docs/reviews/comprehension-debt-review-2026-11-05.md@1d10f9b3:4,11,158,164 (the window from 23 October; 12 of 21 areas better, 2 worse; the two worse areas)"
  - "docs/reviews/drift-coherence-review-2026-11-05.md@1d10f9b3:9,14,17,24 (simple-dispatcher grounded at 07c88f7; d8d186c..07c88f7 and d7ceb373..2eb73ae0 read; the small window)"
  - "tests/unit/fake-dom-census.test.js@1d10f9b3:52-71 (the hand-written fake-DOM list)"
  - "lib/dispatch-lineage.js@1d10f9b3:162 and lib/recent-runs.js@1d10f9b3:46 (the comparators the LIN-4276 reads left in place)"
  - "lib/providers/linear/index.js@1d10f9b3:1516 (the issue read with no first: argument; 50-comment cap)"
  - "lib/stage-writes.js@1d10f9b3:1-3 (LIN-4253, LIN-4251; added by d9c0f1ca, PR #2290)"
  - "docs/papers/standard.md@1d10f9b3:59-69 (the order of a paper), :106 (Next feeds proposals.md)"
  - "docs/papers/proposals.md@1d10f9b3:6-10 (the lines this evidence answers)"
  - "PR #2300 (LIN-4276, 473cc865), PR #2287 (LIN-4248, 29f14bf6), PR #2321 (LIN-4306, 165c61e7)"
  - "lib/task-page-loader.js@1d10f9b3:1069-1160 (rowStateOf 1069-1107, buildRowStates 1128-1160; blame 8ecce6bc, 4a0d90eea, 4b3ceca1, c343ba37) and LIN-4143 (2eb73ae0, 5 Nov)"
  - "cleaner-than-it-started-evidence/2026-11-06/prompts/blind-read-prompt.md (the blind-read template, verbatim from the operator's answer on LIN-4315, 6 Nov 08:59 UTC)"
  - "cleaner-than-it-started-evidence/2026-11-06/analysis.json (the numbers in this paper, with their n; arithmetic on them is shown in the text)"
---

# Can a task finish with the codebase cleaner than it started?

**Tasks on average: not shown. Areas and finished moves: yes, on few cases.** Over 4 to 6 November the loop ran on 53 place merges across LinearViewer and simple-dispatcher. Its 62 place rows, on 59 tickets, include nine baseline place rows from the ledger's baseline window. On the one like-for-like blind read, the ordinary tickets came out level with the baseline or behind it, and two of them (LIN-4241 and LIN-4212) read worse in at least one pass. Those ordinary tickets did not visibly make the codebase better. Where a move was finished (its planned work merged), or a tidy-after cleaned up after its parent, the area read better in both blind passes: six area readings covering eleven tickets, every pass better and none worse. The Periodicals give a weaker picture. Each reads its own window. Drift & Coherence run 4 reads `2eb73ae0..af55cb73` (29 commits on 5 November) as "better, small"; Seams & Tangles run 8 reads the same 29 commits, gives per-area verdicts and names one loop-touched area that got worse, the other-features catch-all that LIN-4253 grew; Comprehension-Debt run 5 reads from 23 October to `af55cb73` and rates 12 of 21 areas better. The later 4 November rows were read by Seams run 7 and Drift run 3 (`d7ceb373..2eb73ae0`), and Comprehension-Debt run 5 spans all of 4 November; Drift run 4 and Seams run 8 start at `2eb73ae0`. Comprehension-Debt's two worse areas are not caused by a loop change (Finding 3). So, over the windows the Periodicals read, the area readings and the Periodicals point the same way, small and better. That is not a finding about tasks on average. Three limits matter most. The blind area reads ask every change whether it added a second copy and what it deleted, which is the question a tidy-after answers, so they are partly circular. Nothing outside the loop was scored per area the same way, so "better in both passes" is not a comparison with untouched code. And the independent Periodicals read only to `af55cb73`, so the five LinearViewer merges after it have no independent reading. The Limits section lists the rest.

**Terms.** *Harbour* is the product whose codebase this is; LinearViewer is its repository, and simple-dispatcher is the second repository the loop touched. A *ticket* is a Linear issue; a *merge* is a first-parent commit on `main`. The *place* is what a later change has to work within: its owners, copies, lists and guards. A *place row* is a merge that a loop ticket landed as part of its work on the place; the place ledger (`docs/plans/survey/place-ledger.md`) keeps one row per such merge. A *tidy-first* is a small tidy filed and landed ahead of a broad ticket; a *tidy-after* is the follow-on that removes what a parent left behind. A *blind pass* is a reader that scores a commit from its code only, without the ticket, and writes a sign (better, neutral, mixed or worse); its sign is the *Balance* cell of that reader's table. The blind passes are labelled batches A to D (four comments, each with 14 rows) and E to AP (one change or one area each). A *Periodical* is a periodic review report in `docs/reviews/` (Seams & Tangles, Drift & Coherence, Comprehension-Debt), which reads the codebase directly. *Census* is the list of hand-written fake DOMs in the test suite. A *Survey* is the read-only step before a ticket's work, and an *after-answer* is the builder's reply after the work. The *scope call* is the "How to go about it" section of a ticket. The *operator* is the person who ran the Survey loop and kept its notebook, with Claude. The *loop* is the sequence run on each ticket: a read-only Survey before the work, a scope call (written by the person, or by Claude on the person's delegation), the build, and a place reading with the builder's after-answer at merge. An *area* is a parent with its tidy-after or its pieces, read as one unit. A *pass* is one blind reader's scoring of one batch or one change; pass 1 and pass 2 are the two sweeps over batches A to D. The *baseline* is the place rows in the ledger's baseline window (`015aa4c6..5334c81a`): nine rows, four from 3 November and five from 4 November, one of the five being the simple-dispatcher half of LIN-4202. They are compared with the loop's forward rows and are not loop changes.

## Findings

**1. Ordinary tickets stayed level with the baseline, or behind it.** In the two blind passes the eight baseline changes (the ledger's own baseline window, `015aa4c6..5334c81a`, which holds merges from 3 and 4 November; LIN-4202 is scored with its simple-dispatcher half as one change) scored +0.38 in pass 1 and +0.50 in pass 2. The forward rows the ledger calls surveyed, excluding LIN-4212, which it calls unsurveyed, scored +0.39 over 18 rows in pass 1 and +0.37 over 19 rows in pass 2. With LIN-4212 counted, pass 1 is +0.32 over 19 rows and pass 2 is +0.35 over 20. The ledger's "+0.37 against +0.38" (`docs/plans/survey/place-ledger.md@1d10f9b3:106`) sets pass 2's forward figure against pass 1's baseline. The +0.37 reproduces, as pass 2's figure over 19 rows; the comparison crosses passes, and the same-pass pairs are +0.39 against +0.38 in pass 1 and +0.37 against +0.50 in pass 2. With eight and nineteen rows, a gap of a tenth is one row's sign (one row moves the baseline mean by 0.125), which these counts cannot resolve; no variance is computed here. Pass 2 has the baseline ahead of the ordinary rows (+0.50 against +0.37), and pass 1 has them level (+0.38 against +0.39). Two forward rows read worse: LIN-4241 in both passes, and LIN-4212 in pass 1 ("mixed, leans worse" in pass 2). The reading is: the ordinary tickets were scored one commit at a time, so these numbers cannot show whether they lifted their areas. Two of them read worse, and in pass 2 the forward rows scored behind the baseline. Neither gap is one to lean on.

**2. Finished moves and tidy steps: no pass read worse, and twelve subjects read better in both.** Nineteen single or area subjects were each read in two passes. A subject is either an area or a single ticket, and an area can read better while one of its tickets alone reads mixed. Twelve read better in both: six areas covering eleven tickets (LIN-4247+4246+4293, LIN-4251+4277, LIN-4252+4255 (the area took the census from 56 to 25, and LIN-4255 routed the 16 movable stubs it did not attempt to LIN-4254; the count reached 22 only after LIN-4296 removed three `// stop:` entries), LIN-4255 alone, LIN-4263+4276, LIN-4292+4304) and six single tickets (LIN-4253, 4276, 4277, 4293, 4296, 4304). Two read better, then mixed (LIN-4251, LIN-4292). Five read mixed in both (LIN-4246, 4247, 4248, 4252, 4263). No pass wrote worse. The research comment on LIN-4315 counted five area reads and two single changes. The comments show one more area (LIN-4255 read alone, passes AA and AB) and four more single reads (the tidy-afters).

**3. The Periodicals agree on direction for 5 November's commits. One names a worse area the loop touched; the other's two worse areas are not loop changes.** Drift & Coherence run 4 reads `2eb73ae0..af55cb73`, 29 commits on 5 November, and rates it "better, small" overall (`docs/reviews/drift-coherence-review-2026-11-05-run4.md@1d10f9b3:11,29`). Seams & Tangles run 8 reads the same window, 08:39Z to 19:02Z (`docs/reviews/seams-tangles-review-2026-11-05-run8.md@1d10f9b3:33`). Seams run 7 and Drift run 3 read `d7ceb373..2eb73ae0`, the 11 commits after `d7ceb373` (4 November 17:18Z) up to `2eb73ae0` (5 November 06:00Z) (`docs/reviews/seams-tangles-review-2026-11-05.md@1d10f9b3:22`; `docs/reviews/drift-coherence-review-2026-11-05.md@1d10f9b3:14`), so they hold only the later 4 November rows and the earliest 5 November ones; their Drift verdict was a small window ("One 11-04b row resolved, four improved, and six rows are new", `:24`). The earlier 4 November rows precede that window, and the earlier editions that read them are not cited here. Comprehension-Debt run 5 spans 23 October to `af55cb73`, so it includes all of 4 November. So the Drift and Seams agreement below is about 5 November's commits. Seams & Tangles run 8 rates "other features: worse as a map": the catch-all grew from 16 to 17 files because of one new leaf file, `lib/stage-writes.js`, which LIN-4253 added (PR #2290). LIN-4253 is a tidy-first, and both its blind passes read better. Pass H reads the new file as having "an obvious home", and neither pass caught the catch-all. This is the one area the loop touched that a Periodical reads as worse, and it is why the research comment's summary, that no area the loop touched read worse, does not hold.

Comprehension-Debt run 5 rates 12 of 21 areas better for a cold reader, six unchanged, one mixed and two worse, over its own window from run 4 (23 October). Neither worse area was made worse by a loop change. `lib/task-page-loader.js`, which assembles Home's run offers, reads worse because of code merged before the loop's window: its `rowStateOf` (lines 1069 to 1107) blames mostly to `8ecce6bc` (25 October) and `4a0d90eea` (2 November, LIN-4104), and its `buildRowStates` (lines 1128 to 1160) to `8ecce6bc`, `4b3ceca1` (31 October) and `c343ba37` (30 October). The smaller changes to both functions (`c5245296`, `27ae64ad`, `c52a4f57`, `80afbb8f`, `24f448b5`) are also dated before 4 November. The one change to the file on or after 4 November is LIN-4143 (`2eb73ae0`, 5 November), a comment change in the ruling-read code. The second worse area is the rationale pointers that the report ties to files deleted under LIN-3912, LIN-4129 and LIN-4179. The first two merged before the window. LIN-4179 merged at 00:55 UTC on 4 November, inside the window's dates, but it is a ledger baseline row, not a loop change (`docs/reviews/comprehension-debt-review-2026-11-05.md@1d10f9b3:158,164`). So the Comprehension-Debt reading does not show the loop making anything worse, and the Seams reading shows one case that it did.

**4. One tidy-first finished its own move, one stopped part way, and one control read mixed.** LIN-4253 deleted two hand-kept name lists and derived them from each template, and read better in both passes. LIN-4252 added a shared fake DOM helper with 17 hand-written copies still outstanding (pass I), and read mixed in both. LIN-4247, which the evidence table groups as the 5 November control, read mixed in both as a single change. Its area reading with LIN-4246 and LIN-4293 read better in both passes (Finding 2). Each is one case. Three cases suggest the finish matters; they do not test tidy-firsts as a class.

**5. A pattern the readings describe: a new owner that leaves its copies running reads mixed, and deleting the copies reads better.** The pass comments give the detail behind several of these cases, such as the 16 suites in LIN-4246. Six single readings that read better in both passes each deleted or merged copies: LIN-4253 (two name lists), 4276 (a private comparator), 4277 (a reworded second copy of the endpoint hints), 4293 (`state.go` literals replaced by one constructor), 4296 (`<select>` selectedness moved to the shared fake) and 4304 (19 method-presence guards removed). Five readings that added code beside the old copies read mixed in both passes: LIN-4246 (the new vm layer, with 16 suites still building their own sandbox), 4247 (a new `runEnded` owner, with the object literals it sits beside still copied), 4248 (two templates that repeat the "Where to stand" paragraph, pass F), 4252 (the helper, with 17 copies left) and 4263 (a per-dispatch split whose rule is written out in five places, per the LIN-4263+4276 pass). The batch comments name the same pattern in their summaries: consolidations come in two steps, and a list one commit creates is often not updated by the next. This is eleven cases, read by one prompt, and the circularity limit below applies to all of them.

**6. The census count recorded the fake-DOM move; it does not measure it.** The list of hand-written fake DOMs was 56 when it was introduced at LIN-4265 (5 Nov 13:18). It was 25 at `af55cb73`, 22 after LIN-4296, and 18 at `1d10f9b3`: 12 movable and 6 marked `// stop:`, the entries that need a real browser API the fake cannot model (`tests/unit/fake-dom-census.test.js@1d10f9b3:52-71`). LIN-4254, the census move, is in flight, with seven pieces (0 to 6). At the freeze pieces 0 and 1 (LIN-4306, LIN-4307) were Done, piece 2 (LIN-4308) was In Progress, and pieces 3 to 6 were Todo. So 18 is where the count stands, not where the move finishes. The count moves when a file leaves the list, not when the copies behind it go. It is a proxy, and the blind reads, not the count, are the instrument for the deletions, subject to the limits below.

**7. One ticket walked through the loop: LIN-4276.** LIN-4263's `/cost` per-dispatch split was read mixed in both passes (Q and R). LIN-4276, its tidy-after, is the next step of that loop. Its ticket carries the pre-work Surveys (open-0 and global), a written scope call ("How to go about it"), and an after-answer ("Survey 1a (round 3)"). It merged at 14:17 on 5 November, before `af55cb73`, so the Periodicals cover it. Its blind reads (passes S and T) found the private `rankOf` comparator gone: its `Infinity - Infinity` gave NaN for two undated rows, and it reuses `byDispatchOrder`. They found the `[id, _id, loopId]` posting-key list written once instead of twice. They also noted a comparator the change left alone, `lib/dispatch-lineage.js@1d10f9b3:162`, and read the change better anyway. Both passes also name a second, `lib/recent-runs.js@1d10f9b3:46`. The ticket's pre-work Survey had already called the `Infinity - Infinity` NaN not a live bug, because the sort maps NaN to zero; the defect the change removed was the second copy. The paired read with LIN-4263 was better too (passes V and U). The cost was $6.77 against the parent's $14.37, 47%. This is the most detailed case in the record. It is also a case where the prompt's question about second copies points straight at the copies the tidy-after removes, which is the circularity limit below.

**8. Cost is measured here, not optimised.** Of the 62 place rows, 59 have an exact cost and three are partial: LIN-4173, 4177 and 4178, which include an unpriced model, so their cost is a floor. The median exact place row cost $8.41 (n = 59 rows; counting each ticket once, over 56 tickets, it is $8.56). Each tidy-after cost a share of its parent: 47% for LIN-4276 against LIN-4263, 65% for LIN-4277 against LIN-4251 ($7.82 against $11.94, live; the ledger's $5.93 for LIN-4277 is out of date) and 85% for LIN-4304 against LIN-4292. That is three pairs, so a range, not a rate. The 14 pieces of LIN-4255's fake-DOM work cost $95.03 in all, all exact (each ticket's cost is rounded to the cent before summing; the unrounded sum is $95.05). LIN-4255, its parent, cost $56.10 on its own, and its pieces are not in that figure. LIN-4271, a child of LIN-4255 and the parent of its own pieces, has no merge row of its own in the window; its own cost is $22.07 and is not included in the $95.03. The builders' after-answers are present on 30 place tickets. They were counted here and not scored.

**9. The person's role: the scope calls, where they were written, and where they were not.** The scope call ("How to go about it") is on 20 of 59 place tickets. Eight of the 20 (LIN-4048, 4143, 4151, 4187, 4203, 4218, 4219 and 4234) say that John asked Claude to take the human's role in the process, with a "how much to tidy" wording ("choose a large enough option" on LIN-4187, 4203, 4218 and 4219; "err on the side of larger tidies" on LIN-4048, 4143, 4151 and 4234). So those calls were written by Claude on John's delegation, not by John, and the record does not show who wrote the other twelve. The scope call is absent on 39, including the two tidy-firsts LIN-4252 and LIN-4253 and the follow-on LIN-4246. A pre-work Survey is visible on the ticket or on LIN-4150 for 17 of 59. Of the 42 without one, 16 are pieces of the fake-DOM work (LIN-4255's 14 pieces and LIN-4254's first two, which carry no Survey of their own), four are 3 Nov baseline rows whose Surveys, if they had any, were posted before the cap, and 22 are rows merged before 5 Nov 02:58 whose Surveys the proxy cannot show, for the reason given under Limits. The ledger records one scope wording that did damage: LIN-4178's copy is "a new twin, invited by the ticket's own wording" (`docs/plans/survey/place-ledger.md@1d10f9b3:19`). The record offers one case for one reading, and it is n = 1: the scope call is where copies get invited, and a tidy-first or tidy-after is where they are removed. LIN-4252 is a tidy-first that left 17 copies, so this is not a rule about tidy-firsts. That is a hypothesis for the Library to test, not a finding. The operator's account names two dials for each ticket, how much to tidy and whether to make no new mess. The record shows one dial, how much to tidy, in those eight delegated calls and in LIN-4201's, which carries the same delegation with no "How to go about it" heading and is counted absent. The 20 stays a count under the heading rule. The scope call is the only place the dials would appear, and it is absent on two-thirds of the place tickets.

The operator's second thread is that the mistakes were judgement points held by hand, and that they argue for moving those points into Harbour as structure, while the human calls (how big a move is, rulings, granting authority) stay human. The operator gives three cases, each one instance: a scope rule that invited a copy (LIN-4178, above); a sweep drawn by a method name (LIN-4292); and a scope description that became a false comment (LIN-4255, close-out `15061f40`, "fix stale scope wording"). Each is n = 1, and none is measured here. They say where a structure would have to sit, at the scope call and at a sweep's name, and they are the subject of Next 6.

## Method

The population is every first-parent merge from 4 Nov 00:00 UTC to the two pins: 62 in LinearViewer and 20 in simple-dispatcher, 82 in all. Of those 82, 53 are loop place merges and five are baseline place rows from 4 November (LIN-4178, LIN-4179, LIN-4198 and LIN-4202 in both repositories); the other 24 are nine merges the ledger marks as outside it, 14 Periodical, paper or notebook merges, and one parent issue. The 90 rows add four baseline place merges from 3 November (LIN-4166, LIN-4168, LIN-4173 and LIN-4177) and four UI context rows. The 62 place rows on 59 tickets are therefore the 53 loop merges plus all nine baseline rows. The population is frozen by `freeze.mjs`, which reads LIN-4150 first because the proxy returns at most 50 comments per issue. LIN-4150 returned exactly 50, and the freeze asserts that batches A to D, and all 42 blind passes, are inside them (`lib/providers/linear/index.js@1d10f9b3:1516`). Then it reads each ticket's issue, cost (per dispatch) and dispatch history, and the 73 custom prompts dispatched since 4 Nov, the after-answers among them. Every answer is saved raw with its read time.

The blind reads are the primary instrument. Each pass scores a commit, or a ticket or area, from the code only, in one of three forms: batches of 14 single commits, where batches A and B make pass 1 over 28 commits and C and D make pass 2 over the same 28 in a different order, except that pass 1's batch B row 12 (LIN-4240's LinearViewer commit) was scored together with LIN-4239's simple-dispatcher commit in B3 as one cross-repo unit, as the prompt instructs, so pass 1 has 27 signed units against pass 2's 28 (pass 2 scores them separately, D1 and D10) (`blind-codes.json`); one change per session; and one parent with its tidy-after or pieces per session. The sign is the Balance cell of the pass's own table, copied verbatim, and mapped to +1 for better, 0 for neutral or mixed, and -1 for worse. `code-blind.mjs` does the copying, so no sign was re-judged here. The operator's running tally of 17 better, 3 mixed, 1 neutral and 0 worse, kept in the notebook, was overturned by the blind reads, and the ledger says so (`docs/plans/survey/place-ledger.md@1d10f9b3:127`). The Survey status line in `docs/plans/survey.md@1d10f9b3:5` is replaced here by a pointer.

The Periodicals are the instruments that do not share the blind prompt. Seams & Tangles run 8, Drift & Coherence run 4 and Comprehension-Debt run 5 each ground LinearViewer at `af55cb73`. Drift run 3 grounds simple-dispatcher at `07c88f7` and reads `d8d186c..07c88f7` (`docs/reviews/drift-coherence-review-2026-11-05.md@1d10f9b3:9,17`). That corrects the research comment, which said Comprehension-Debt was the only reader of those commits. The census is read with `git show` at each merge. Costs are the frozen per-dispatch reads. The paper's numbers come from `analysis.json`, which reads the frozen folder alone and reproduces byte for byte. The few counts and ratios that are arithmetic on its keys are shown in the text: 53 is the 62 place rows less the nine baseline rows, and 65% is $7.82 over $11.94.

## Limits

- **Small numbers.** The baseline is eight changes in the blind passes. The forward rows are nineteen or twenty. The area readings are six, over eleven tickets. The cost pairs are three. The Finding 5 pattern rests on eleven cases, six that deleted copies and five that added code beside them, and the cases are the ones the blind prompt's question about copies picks out.
- **The blind reads are partly circular.** The blind prompt is frozen in the evidence folder (`prompts/blind-read-prompt.md`), copied verbatim from the operator's answer on LIN-4315. The circularity remains. One prompt asks every change whether it added a copy and what it deleted; the tidy-after is the change that answers that question, and the same prompt judges its result. The Periodicals answer this for area direction through `af55cb73`, because they read the same areas without the prompt. They do not answer it for any single change.
- **No like-for-like baseline for areas.** Nothing outside the loop was scored one change per session in the same framing. "Better in both passes" is a statement about the loop's own areas, not a comparison with untouched code.
- **"Covered" in the evidence table is loose.** The `periodical_reads` column of `evidence-table.tsv` says "covered" for a LinearViewer row inside at least one Periodical window. For the rows before that window (the 3 November rows, the earlier 4 November rows, and `d7ceb373` itself) that is, among the Periodicals cited here, Comprehension-Debt run 5 alone, and the frozen column does not say so.
- **No independent reading after `af55cb73`.** LIN-4292, 4296, 4304, 4306 and 4307, five LinearViewer merges, merged after it. (Drift run 3 grounds simple-dispatcher at `07c88f7`.) Three of the twelve better-in-both readings involve one of them: the pair LIN-4292+4304, and the single readings of LIN-4296 and LIN-4304. Those readings are unchecked by a reader who did not write them.
- **Surveys before 5 November are not in the record.** LIN-4150 holds 50 comments from 5 Nov 02:58 onward, and the 2 to 4 Nov Surveys were pushed out by the cap. For 42 of 59 place tickets the frozen record shows no pre-work Survey. The Surveys for the 4 Nov forward rows are visible only in the notebook's log narration. On the LIN-4315 ticket thread's account, the proxy cap is a Harbour defect in the class of LIN-3309 and LIN-4068. It is not fixed here, and it is named for John to file. The research comment's counts, the operator's two dials and three structure cases, and the LIN-3309 / LIN-4068 class all come from the LIN-4315 thread, which is not frozen in the evidence folder.
- **Which way the bias runs.** The circularity favours the tidy-after readings, because the prompt's question about copies is the one a tidy-after answers. The freeze's gaps (the Surveys before 5 Nov) may hide early loop evidence. This paper does not measure which way that cuts; it does make the record thinner than the loop was. The Periodicals do not share the prompt. They read the same direction and found one worse loop area (the catch-all), so they are the check on the first bias, and they stop at `af55cb73`. Whether "small, and net better" survives once the circularity is discounted, this paper cannot say: the only non-circular check covers the window to `af55cb73`, and the blind tallies cannot be separated from the prompt that produced them.
- **Cost is live and partial.** Three place rows are partial. A parent's cost excludes its children, so LIN-4255's $56.10 and its pieces' $95.03 are separate figures.
- **Where the notebook and the code disagree, the code wins.** The notebook's 17 / 3 / 1 / 0 is overturned, and this paper replaces it. The ledger's "+0.37 against +0.38" compares across passes. The ledger's cost for LIN-4277 is stale. The census is 18 at `1d10f9b3`, not the 22 the ticket's Surveys carried. The research comment listed LIN-4178 and LIN-4181 as partial; the frozen reads show LIN-4173, 4177 and 4178, and 4181 is outside the ledger. The notebook does not record LIN-4307's merge.
- **The Periodicals are instruments, not an audit.** They are written by the same kind of agent that wrote the code. They agree with each other on direction, and they disagree on one area.
- **LIN-4254 is in flight.** The 18 is a count at the pin, not a finish.

## Next

1. **Test whether larger standalone tidies move the worst areas.** Larger standalone tidies, chosen from the Periodicals' worst areas (the other-features catch-all, the task-page loader), against the same areas left alone. That is the test that could move the net direction, and this window cannot make it.
2. **Give an area read a baseline.** The blind-read prompt is frozen in the evidence folder (`prompts/blind-read-prompt.md`). Score an untouched area one change per session with that same prompt, and compare.
3. **Read the merges after `af55cb73` independently** before the essay cites them: LIN-4292 onward, and LIN-4308 onward, with a Periodical run.
4. **Check what the census should guard.** A count of files that still hand-write a fake DOM does not show whether the moved suites share one owner at the pin. Decide whether a guard on the shared thing would replace the count.
5. **Proposal lines for the Library.** Three are added to `proposals.md`: whether a one-owner change that deletes its copies reads better than one that leaves them for a tidy-after (LIN-4253 and LIN-4252 are the first two cases); what a larger standalone tidy does to the worst areas; and whether an area read with a baseline still reads better. Whether a written scope call predicts a finished move is not yet a line. Twenty of 59 place tickets have one, and that is the next thing to count. The existing lines are dispositioned here (base numbering, `proposals.md@1d10f9b3:6-10`): `:6` is narrowed; `:7`, the run-by-hand step, is retired, since its spike ran (`docs/plans/survey/log.md@1d10f9b3:22`); `:8`, the tidy-first step, is narrowed, since its round ran on two tracks but its plan-review rounds were not counted; `:9` is untouched; and `:10`, the ask-alone spike, is narrowed rather than retired, since its after-answers (30 on place tickets) were counted, not scored.
6. **Test the structure argument.** For the three operator cases in Finding 9, check whether a guard, or a list derived from the code, would have stopped the mistake, and whether the scope call is the place to put it. The Library decides whether that becomes a line.
7. **Not this paper.** A check over `docs/papers/`, catching up on the unchecked papers, a shared Library freeze helper, and where live experiment records should live. The essay can name them; this paper does not do them.
