1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
//! One-shot repair for a savings ledger polluted by unit-test rows (#7569).
//!
//! Why: #7514 let the instruction-compression producer resolve a *fixture*
//! path to a session id, so every test run that wrote a compiled prompt
//! appended a row to the OPERATOR's real `~/.trusty-mpm/usage/savings.jsonl`.
//! #7514's fix stops new rows arriving; it cannot retract the 228 already
//! there, and those rows claim 1,498,419 of the ledger's 1,501,558
//! instruction-compression tokens — the `💸` statusline average is computed
//! over them. Nothing else in the tree can edit this file: the ledger has
//! exactly one writer ([`crate::core::savings::append_row`]) and three
//! readers, none of which rewrites it.
//!
//! What: [`plan`] classifies every row on the ledger and [`apply`] moves the
//! matched ones to a timestamped sidecar, rewriting the ledger atomically
//! (temp file plus rename in the same directory) from the kept rows' ORIGINAL
//! bytes. Rows are never deleted and never re-serialised, so a reader folds
//! the survivors exactly as it folded them before. [`quarantine_markers`] does
//! the same for the `usage/no-fold-warned/` marker directory #7514 also filled.
//!
//! Two properties the command's safety rests on:
//!
//! - **A malformed line loses nothing.** #7579 left ten physical lines holding
//! two complete rows with no separator. [`plan`] splits such a line and
//! judges each half on its own; a half that does not parse is quarantined
//! under [`Reason::Malformed`] rather than dropped.
//! - **Every write lands after every read.** [`apply`] builds both output
//! buffers in memory before it opens anything for writing, so a parse or IO
//! failure aborts with the original ledger untouched.
//! - **A live producer's append is not stranded.** The ledger's writer runs on
//! a Claude hook and can append at any moment, including between [`plan`]'s
//! read and [`apply`]'s rename. [`apply`] carries those bytes across rather
//! than replacing the inode they landed on.
//!
//! Test: `savings_repair_tests.rs` — `the_predicate_matches_only_fixture_rows`,
//! `plan_classifies_a_mixed_ledger`, `apply_quarantines_and_rewrites`,
//! `a_second_apply_finds_nothing`, `apply_keeps_the_original_bytes`,
//! `apply_carries_a_row_appended_after_the_plan`.
use Write as _;
use ;
use ;
use crate;
/// The `basis` substring that identifies a row written by this crate's own
/// unit tests (#7569).
///
/// Why: the fixture compiled prompt behind #7514 is the 13-byte string
/// `COMPILED-BODY`, and `basis` records the compiled size verbatim. A real
/// compiled prompt is tens of kilobytes — the smallest on the operator's
/// ledger is 22,559 B of sources against a 24,667 B compile — so 13 bytes
/// cannot arise from a genuine launch. The other candidate discriminators were
/// measured and rejected: `session_id` is a fixture directory name (`b`) on
/// only 113 of the 228 rows, the remaining 115 carrying the real session UUID
/// exported into the test process, and `sources 22559 B` appears on a
/// surviving genuine row too.
/// What: the literal `compiled 13 B`. The trailing ` B` is what keeps it from
/// matching `compiled 130 B`.
/// Test: `the_predicate_matches_only_fixture_rows`.
pub const FIXTURE_COMPILED_BASIS: &str = "compiled 13 B";
/// Directory under `usage/` holding the per-project "nothing folded" markers.
///
/// Why (#7569): a second copy of this name would let the producer's directory
/// and the repair's sweep drift apart silently — `--markers` would move
/// nothing, count nothing, and still exit 0. So this aliases the producer's own
/// constant rather than re-spelling it.
/// What: [`crate::core::savings_sidecar::NO_FOLD_WARNED_DIR`], re-exported under
/// this module's public name.
/// Test: `marker_dir_nests_under_usage`,
/// `the_repair_sweeps_the_directory_the_producer_writes`.
pub const MARKER_DIR: &str = crateNO_FOLD_WARNED_DIR;
/// Why a row is being moved off the ledger.
///
/// Why: the sidecar records the rule that matched each row, because a repair
/// that cannot say why it took a row is one an operator cannot audit.
/// What: `TestFixture` for [`is_test_fixture_row`]; `Malformed` for a fragment
/// that is not parseable JSON at all; `Duplicate` for a repeat of an
/// `instruction-compression` measurement already seen earlier in the file
/// (#7658).
/// Test: `plan_classifies_a_mixed_ledger`, `plan_collapses_duplicate_rows`.
/// One row's worth of ledger text, with the verdict [`plan`] reached on it.
///
/// Why: `text` is the row's ORIGINAL bytes rather than a re-serialisation of
/// the parsed struct, so a kept row is written back byte-for-byte. Round-
/// tripping through `serde_json` would renormalise float formatting and key
/// order, which the three ledger readers would parse identically but a diff
/// would not — and a repair nobody can diff is one nobody can check.
/// What: `line` is the 1-based physical line the fragment came from (two
/// fragments share it after a #7579 split); `quarantine` is `None` for a row
/// the repair keeps.
/// Test: `apply_keeps_the_original_bytes`, `plan_splits_a_concatenated_line`.
/// What [`plan`] found, and what [`apply`] would do with it.
///
/// Why: planning and applying are separate so `--dry-run` — the default — can
/// print the whole verdict having opened the ledger read-only.
/// What: every fragment in ledger order, plus the line numbers that need
/// structural repair. `blank_lines` are the empty lines #7579's interleave
/// leaves behind; they carry no row, and dropping them is part of the repair.
/// Test: `plan_classifies_a_mixed_ledger`, `plan_of_a_missing_ledger_is_clean`.
/// What [`apply`] did.
///
/// Test: `apply_quarantines_and_rewrites`.
/// One quarantined fragment, as written to the sidecar.
///
/// Why: the sidecar is not a ledger — giving it the ledger's own schema would
/// let a mis-aimed reader fold the rows this repair just removed. Wrapping the
/// original text in an envelope makes it inert to every ledger reader while
/// keeping the bytes exactly recoverable.
/// What: the matched rule, the physical line it came from, and the row's
/// original text.
/// Test: `apply_quarantines_and_rewrites`.
/// Was this row written by one of this crate's unit tests (#7569)?
///
/// Why: THE predicate. Every caller — the dry run, the apply, and the tests —
/// routes through this one function, so the rule a dry run prints and the rule
/// an apply enforces cannot drift apart.
/// What: an `instruction-compression` row whose `basis` records a 13-byte
/// compiled prompt. See [`FIXTURE_COMPILED_BASIS`] for why that, and why not
/// `session_id` or the source-byte count.
/// Test: `the_predicate_matches_only_fixture_rows`.
/// Has this `instruction-compression` measurement already been seen on this
/// ledger (#7658)?
///
/// Why: the producer-side guard stops NEW duplicates; a ledger that already
/// carries 312 copies of one measurement needs them collapsed, and the repair
/// is the only surface that may remove a row. Keying on `basis` alongside
/// `session_id` is what separates "the same fold recorded again" from "a second,
/// genuinely different fold in the same session" — the latter is real data and
/// must survive. Only `instruction-compression` is keyed this way because it is
/// the only technique whose producers re-run against an unchanged input; a
/// `divert` row repeating its basis is a second real diversion.
/// What: records the key on first sight and reports `true` on every sight after
/// that. A row of any other technique is never a duplicate here.
/// Test: `plan_collapses_duplicate_rows`,
/// `plan_keeps_rows_whose_basis_differs`,
/// `plan_keeps_a_repeated_divert_row`.
/// Split one physical ledger line into the row fragments it actually holds.
///
/// Why (#7579): the ledger's writer issued a row and its newline as two
/// `O_APPEND` writes, so two racing producers could land `{…}{…}` on one line.
/// A reader that treats a physical line as a row loses BOTH halves of such a
/// line; this repair must lose neither.
/// What: streams JSON values off the line, returning each value's original
/// slice beside the parsed row. The first slice that fails to parse is
/// returned with `None` and ends the walk — `serde_json`'s stream cannot
/// resume past an error, and a trailing fragment that is not JSON has no
/// further structure to find.
/// Test: `plan_splits_a_concatenated_line`,
/// `split_line_reports_an_unparseable_line_once`.
/// Read the ledger and classify every row on it, writing nothing.
///
/// Why: `--dry-run` is the command's default, so the whole verdict has to be
/// reachable from a read-only pass.
/// What: walks the ledger line by line, splits each line into fragments (see
/// [`split_line`]), and records a [`Reason`] for each fragment the repair would
/// move. A missing ledger plans to nothing — that is the ordinary state on a
/// machine that has run no producer, not a fault. Any other read error is
/// returned, because a repair must never treat an unreadable ledger as an
/// empty one.
/// Test: `plan_classifies_a_mixed_ledger`, `plan_of_a_missing_ledger_is_clean`,
/// `plan_propagates_a_read_error`.
/// Where the quarantined rows for a repair run at `now` are written.
///
/// What: `<ledger>.quarantine-<YYYYMMDDTHHMMSSZ>.jsonl`, a sibling of the
/// ledger so the rename in [`apply`] stays within one filesystem.
/// Test: `quarantine_path_is_a_timestamped_sibling`.
/// `<path>` with `suffix` appended to its file name.
/// The compact UTC stamp both sidecar names carry.
/// Move the quarantined rows to a sidecar and rewrite the ledger.
///
/// Why: the operator's ledger is the only copy of every genuine row on it, so
/// this is written to fail rather than to half-succeed.
/// What: serialises both outputs into memory FIRST, then writes the sidecar
/// (refusing to clobber an existing one), then writes a temp file in the
/// ledger's own directory and renames it over the ledger. Every failure path
/// returns before that rename, leaving the ledger exactly as it was; the
/// sidecar, if it was written, is a copy and costs nothing. A clean plan
/// writes nothing at all and reports zero.
///
/// The ledger has a LIVE producer — a Claude hook appends to it at any moment —
/// so the rename cannot simply replace what [`plan`] read: a row that arrived
/// since then sits on the old inode and the rename would strand it. So the last
/// thing written to the temp file is [`tail_since`]'s bytes, carried across
/// verbatim and counted in [`Applied::carried`]. That narrows the loss window
/// to the rename itself, which no lock the producers take could close; a row
/// carried this way is unclassified, and the next run classifies it. A ledger
/// that SHRANK since the plan is not the file the plan describes, so it is
/// refused rather than rewritten.
/// Test: `apply_quarantines_and_rewrites`, `a_second_apply_finds_nothing`,
/// `apply_keeps_the_original_bytes`,
/// `apply_leaves_the_ledger_untouched_when_the_sidecar_exists`,
/// `apply_carries_a_row_appended_after_the_plan`,
/// `apply_refuses_a_ledger_that_shrank`,
/// `apply_leaves_no_temp_file_when_the_directory_is_read_only`.
/// The ledger's bytes past `offset`, which arrived after [`plan`] read it.
///
/// Why (#7569): see [`apply`] — these are a live producer's appends, and the
/// rename would strand them on the old inode.
/// What: the bytes from `offset` to end of file, verbatim. A ledger no longer
/// than `offset` yields nothing; one SHORTER than `offset` is a different file
/// from the one the plan describes, so it is an `InvalidData` error naming both
/// lengths rather than a rewrite from a stale plan.
/// Test: `apply_carries_a_row_appended_after_the_plan`,
/// `apply_refuses_a_ledger_that_shrank`.
/// How many non-blank lines `bytes` holds.
///
/// What: counts what an operator would call rows, so a tail of `"\n"` reports
/// zero rather than one. Invalid UTF-8 is counted lossily — this is a report,
/// never the bytes written.
/// Test: `apply_carries_a_row_appended_after_the_plan`.
/// Where the "nothing folded" markers live under a framework root.
///
/// Test: `marker_dir_nests_under_usage`.
/// How many marker files the directory holds.
///
/// What: a count of its entries; a missing directory counts zero.
/// Test: `quarantine_markers_moves_the_whole_directory`.
/// Move the whole marker directory aside (#7569).
///
/// Why: the operator's directory holds ~3,809 markers, one per distinct
/// project path, where a real machine has a handful of projects. The content
/// does NOT discriminate: the markers were measured arriving in bursts of tens
/// per minute under EVERY byte pair present, this session's genuine
/// `26810 29172` pair included, so no per-file rule separates a test marker
/// from a real one. What makes moving all of them safe instead is what the
/// marker IS — a log-once cache read by
/// [`crate::core::savings_sidecar::log_no_fold_once`]. Losing one costs a
/// single repeated `debug!` line on the next launch of that project and nothing
/// else.
/// What: renames `usage/no-fold-warned` to
/// `usage/no-fold-warned.quarantine-<stamp>`, one atomic operation that keeps
/// every file. A missing directory yields `None`. The directory is never
/// deleted, and the next producer recreates an empty one.
/// Test: `quarantine_markers_moves_the_whole_directory`,
/// `quarantine_markers_of_a_missing_directory_is_none`.