thesix 0.4.0

Policy-driven six-tier cache orchestration with an explicit HPA data-continuity contract
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
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
# bugs.toml — review findings against PR3 (`feat/hpa-continuity-contract`)
#
# This file IS a gate input. `merge_readiness` reads it, via the contract's
# `[verification.merge_readiness].tracker` key, and fails while any finding with
# `blocks_merge = true` is open. An earlier version of this header said nothing
# read it yet; that was true when written and stopped being true when the gate
# landed, which is exactly the failure mode B8 and B13 are about — a stale claim
# about the checking apparatus, sitting inside the apparatus.
#
# Two consequences worth stating plainly:
#
#   * `severity` is documentation. The gate splits findings on `blocks_merge`
#     alone, so a `should-fix` entry with `blocks_merge = true` reads as blocking
#     and vice versa. Both fields are set consistently on every entry below.
#   * the expected counts live in `theSix.toml`, not in `[meta]` below. A tracker
#     that declares its own expected contents can be edited to agree with whatever
#     it currently holds, so `[meta]` is informational and deliberately unread.
#
# A green `merge_readiness` means every merge-blocking finding is cleared. It does
# NOT mean every finding below is closed: B15–B20 are open, non-blocking, and are
# listed because they are real remaining work rather than because they should hold
# the branch.
#
# Each finding below was re-derived from the source at the recorded commit before
# being written down. The review's own claims were not taken on trust; where the
# review was right, the confirming line is cited. Where the review overstated
# something, that is recorded too.

[meta]
# Tracker's own record of the review this file came out of. `cargo xtask
# merge_readiness` deliberately does not read any of it -- including these counts --
# because a tracker that grades its own homework is not a check. The counts that
# *do* gate live in `theSix.toml` under `[verification.merge_readiness]`, so a
# finding cannot be deleted or downgraded without editing the contract.
branch = "main"
commit = "99b4a5f"
reviewed_commit = "99b4a5f"
reviewer = "ChatGPT, external code review; then a 0.4.0 backlog pass over B15-B21"
review_date = "2026-10-04"
verdict_architecture = 9.0
verdict_verification_strategy = 9.5
verdict_implementation_correctness = 7.5
merge_ready = false
findings_blocking = 11
findings_should_fix = 12
findings_praised = 4
independently_verified = true

# Why `merge_ready` is false while every finding but one is resolved: B21 is
# open, and it is the rule that would make any of this enforced. `main` currently
# has no required status check, so the aggregated gate is advisory until it is
# restored with a token holding effective Administration write.
blocking_reason = "B21: main's required_status_checks rule is disabled"

# The reviewer's summary judgement, kept verbatim in substance because it is the
# most useful single sentence in the review:
#
#   "PR3's architecture is ahead of its recovery semantics."
#
# i.e. the contract describes a system more correct than the one implemented, and
# the verification machinery is now good enough to expose the gap. The remedy the
# review recommends is to close the named failure windows, not to redesign.

[verdict]
architecture = """
Strong, and not in a generic sense. The contract-driven gate model, the
control/data-plane split, the capability axes, and the explicit L6 authority
boundary are all real improvements rather than restatements of intent.
"""
implementation = """
Three genuine semantic holes, two integrity inconsistencies. All five were
confirmed against the source; none were stylistic.
"""
merge_criterion = """
Do not merge yet. Do not redesign. Close B1, B2 and B3 with the specific tests
named below, then re-review. A 95%-correct implementation is not "pretty good"
for a crate making ACID, continuity and cancellation-safety claims, because the
remaining 5% lives in exactly the failure windows the system exists to handle.
"""

# ---------------------------------------------------------------------------
# BLOCKING
# ---------------------------------------------------------------------------

[[bug]]
id = "B1"
title = "set() has no RAII guard on its commit intent, so cancellation wedges the key"
severity = "blocking"
status = "resolved"
resolved_at = "2026-10-04"
accepted_by = "leo"
rationale = """
Fixed by `IntentGuard`, an RAII guard held across the write await in both `set`
and the move path. Its Drop aborts the token; `abort` is idempotent, declines when
a commit already won, and restores the state the intent interrupted. Two regression
tests in tests/recovery, both confirmed to fail against the pre-fix code.

The symptom was narrower than first reported. `set` was never wedged, because
`prepare` has no claimability precondition and a second write simply re-prepares
over the abandoned intent. `get` was never wedged either; it reports Miss on a
Prepared entry. Only `get_or_fetch` wedged: it must claim the entry to populate it,
`acquire` declines while `population_owner` is set, and the caller burned the full
timeout as a waiter against an owner that would never arrive.

Fixing the move path also closed two leaks that were not cancellation-related and
were not in the original report: the unbound-tier check and the key re-encode both
returned while the entry was still Prepared.
"""
verified = true
blocks_merge = true
locations = ["src/manager.rs:94", "src/manager.rs:853", "src/manager.rs:1140", "src/control/cachelito.rs:892"]
violates = ["cancel_safe = true", "theSix.toml:249"]
summary = """
`set()` ran prepare -> await tier.set() -> commit/abort with no guard object
anywhere in the sequence. `PopulationGuard` solves exactly this problem for
`get_or_fetch` and was constructed only in that path — the write path never
instantiated it.
"""
mechanism = """
prepare()                        entry.state = Prepared
                                 population_owner = true
                                 intent_present = true
  await tier.set(...)            caller is cancelled here
future dropped                   no Drop impl runs
  -> nothing aborts the intent

The entry stays Prepared with an owner no one will ever satisfy. It is not
readable (correct) but it is not claimable either, so every subsequent operation
on that key waits out the full bound and fails. The intent survives only until a
recovery sweep older than INTENT_RECOVERY_AGE clears it.
"""
why_this_is_not_a_test_gap = """
The mechanism required to fix it is already written and already proven in this
crate — `PopulationGuard`'s Drop releases the claim. The implementation simply
does not apply it to the write path. This is an omission, not a design gap.
"""
resolution = """
`IntentGuard` in src/manager.rs. Shape mirrors `PopulationGuard` — it holds the
token and an `armed` flag — with one addition: `abort(&mut self, error)` is a
single method rather than `disarm()` followed by `abort(token())`. An earlier
version removed the token from an `Option` on disarm, so that ordering panicked;
the cancellation test is what caught it. Keeping the token and tracking liveness
separately makes the mistake unrepresentable.

Held across the await in both `set()` and `move_entry()`.
"""
tests_added = [
  "tests/recovery: a_cancelled_set_releases_its_commit_intent",
  "tests/recovery: a_cancelled_write_does_not_wedge_the_population_path",
]
anti_vacuity_note = """
Both tests assert the stall actually fired before asserting the abort — the first
via `HangingTier::reached() > 0`, the second via `ledger.fired(FaultClass::Latency)`.
The second uses a one-shot latency fault rather than a permanently hanging tier,
because with a permanently hanging rung the follow-up call times out on the data
plane either way and a duration assertion would prove nothing about the claim.
Both were confirmed to fail against the pre-fix code with the guard's Drop neutered.
"""

[[bug]]
id = "B2"
title = "A failed tier.set can leave data-plane residue the abort does not remove"
severity = "blocking"
status = "resolved"
resolved_at = "2026-10-04"
accepted_by = "leo"
rationale = """
Fixed by compensating removal on `CacheError::WriteIndeterminate`, plus the error
variant that makes the condition expressible. Also added `FaultClass::PartialWrite`,
the only fault that stores bytes and then fails, so the property finally has a test
that can fail.
"""
verified = true
blocks_merge = true
locations = ["src/manager.rs:815", "src/manager.rs:843", "src/manager.rs:851"]
violates = ["partial_commit_visible = false", "theSix.toml:54"]
note_on_second_clause = """
`cancelled_operation_may_commit_partially` is no longer listed as violated. B1's
`IntentGuard` made cancellation resolve the intent, and residue from a cancelled
write is indistinguishable from residue from a failed one — both are handled by the
same indeterminate-write path. The clause is better read as a property of the
recovery mechanism than of the error class, and it is now covered by the recovery
layer rather than contradicted here.
"""
summary = """
The commit-failure path correctly removes the residue it created; the
tier.set-error path does not. The asymmetry is the bug.
"""
mechanism = """
tier.set() succeeds, commit() fails  -> tier.remove() THEN abort()   (clean)
tier.set() returns Err after writing   -> abort() only              (residue)

Concretely, at src/manager.rs:815 the commit-failure arm calls
`tier.remove(&key_ref)` before aborting, with the comment "Uncommitted: the
destination copy is residue." The tier.set-error arms at :843 and :851 call
`abort` and nothing else. So a backend that writes bytes and then reports an
error leaves the control plane saying "aborted" and the tier holding a value the
control plane has no record of.
"""
why_this_is_not_a_test_gap = """
It is a test gap AND an implementation gap, and they compound. The existing
`partial_write` test exercises the control-plane intent only; it never has a
backend write bytes and then fail. So the property the contract states is not
merely unimplemented, it is untested.
"""
resolution = """
Added `CacheError::WriteIndeterminate` and removed the key from the rung when a
write reports it. The discriminator is the error, not a tier capability flag — the
first attempt used `CapabilityFlags::ATOMIC_WRITE_OR_ERROR` and was wrong, which
the pre-existing `write_failure_fails_a_write_and_leaves_the_old_value` test caught
immediately. A blanket per-tier claim cannot distinguish a rejected write from an
accepted one: `WriteFailure` and `PartialWrite` share a tier and produce opposite
requirements, so the flag over-removed and destroyed committed values. Only the
tier knows what happened, so the tier has to say so, per operation.

`ATOMIC_WRITE_OR_ERROR` is retained as reported capability — true of every in-tree
backend, and useful to a consumer choosing a rung — but it does not govern cleanup,
and its doc comment says so.

Where the harm actually occurs is narrower than first assumed, and the tests record
it: on a *fresh* key the residue is invisible either way, because reads consult the
control plane first and an aborted entry reads as `Absent`. The damage requires a
previously-committed value, where the rung silently becomes the new bytes while the
control plane still describes the old one.
"""
tests_added = [
  "tests/fault_injection: the_partial_write_fault_really_stores_bytes_before_failing",
  "tests/fault_injection: a_failed_write_does_not_silently_replace_a_committed_value",
  "tests/fault_injection: a_definite_write_failure_leaves_the_committed_value_alone",
]
verification_note = """
Only `a_failed_write_does_not_silently_replace_a_committed_value` fails against the
pre-fix code — it is the regression test. The first proves the fault is real and is
routed through the tier directly, because the manager's job is to delete the residue
and a manager-level fixture assertion would assert its absence. The third guards
against over-correction and passes either way by design.
"""
review_addendum = """
The review's framing is correct and slightly stronger than stated: this is not
only a residue problem. Because `abort` restores the previously committed state,
a residue left behind can also be *served* to a later reader if the entry is
re-populated at the same rung — the abort makes the slot claimable again while
the stale bytes are still on the rung.
"""

[[bug]]
id = "B3"
title = "Move recovery is declared complete-forward but cannot be completed after a crash"
severity = "blocking"
status = "resolved"
resolved_at = "2026-10-04"
accepted_by = "leo"
rationale = """
Resolved by redefining the contract, not by implementing the recovery.
`recovery_direction_prepare_move` is now `external-reconciliation`, which is what
the runtime can actually do. Accepted as a deliberate, documented limitation rather
than a defect: the alternative was persisting enough identity to reconstruct a
move, which is a feature and not a fix.

Also made the limitation structural rather than prose: `RecoveryDirection::
for_kind(Move)` now returns `ExternalReconciliation`, `Cachelito::resolve_intent`
declines it, and `RecoveryReport` counts these separately from `failed` so a caller
can tell "the sweep could not do this" from "the sweep lacks the information".
"""
verified = true
blocks_merge = true
locations = ["src/manager.rs:386", "src/manager.rs:411", "src/control/cachelito.rs:106"]
violates = ["recovery_direction_prepare_move", "theSix.toml:64"]
summary = """
`RecoveryDirection::for_kind(IntentKind::Move)` correctly returns
CompleteForward, and `Cachelito::resolve_intent` can complete a move when handed
a key. The production path can never hand it one.
"""
mechanism = """
Cachelito persists only `key_hash: u64` (src/control/cachelito.rs:106). Completing
a move needs the actual key bytes plus source and destination rungs: read source,
write destination, remove source, commit. After a crash the key bytes are gone,
so recover_older_than counts the intent as failed at src/manager.rs:411
(`IntentKind::Move => failed += 1`) and moves on.
"""
the_trap = """
A recovery algorithm that works in isolation, with no recovery path capable of
invoking it after the failure it was designed for. `partial_promotion` passes
because it drives resolve_intent directly with a key in hand, which is exactly
why the suite is green and the behaviour is still absent.
"""
status_of_the_knowing = """
Partially disclosed. `living.toml`'s pending_work and AGENTS.md both state that
move recovery reports failed and needs an external reconciliation source. The
defect is that `theSix.toml` still promises complete-forward, so the machine-
checked contract and the runtime disagree. The disclosure in prose does not
satisfy a machine-checked clause.
"""
resolution = """
Option (b) was chosen. `theSix.toml` now declares
`recovery_direction_prepare_move = "external-reconciliation"`, with a comment
recording why neither complete-forward nor abort is available.

Three structural changes so the limitation cannot drift back into a promise:

* `RecoveryDirection::for_kind(Move)` returns `ExternalReconciliation`, not
  `CompleteForward`. A sweep holding only a hash has no direction it can execute,
  and the type now says so.
* `Cachelito::resolve_intent` declines `ExternalReconciliation` with an error.
  Committing the control-plane half of a move whose data half never happened would
  publish a move that did not occur.
* `recover()` returns `RecoveryReport { recovered, failed, needs_reconciliation }`
  instead of a two-tuple, because "the sweep tried and lost" and "the sweep has no
  information" need different responses and were sharing a counter.
"""
tests_added = [
  "tests/continuity (unit): only_abort_is_executable_without_the_key",
  "tests/recovery: an_unresolvable_move_is_reported_separately_from_a_failure",
  "tests/contract: declared_recovery_directions_match_what_the_runtime_can_execute",
]
anti_vacuity_note = """
The contract test asserts the declared string against `RecoveryDirection::for_kind`
and was confirmed to fail when the clause was set back to `complete-forward`. That
is the only test in the suite that compares a declared invariant to runtime
behaviour rather than to the runner and the test inventory, and its absence is
precisely why this defect survived review.
"""
deliberately_not_done = """
Option (a) — persisting the key bytes, or a durable handle to them, in
`CommitIntent` — would let recovery actually finish a move. Not attempted: it
changes the control plane's payload-free guarantee, which is a contract invariant
in its own right. `CommitIntent` holding key bytes is exactly the kind of thing
`commit_protocol` exists to forbid.

A related limitation, also left in place: a move removes the source rung *before*
it commits, so a crash in that window leaves the value only at the destination. Any
future reconciliation pass must account for that window rather than assuming the
source is still authoritative.
"""

# ---------------------------------------------------------------------------
# SHOULD FIX
# ---------------------------------------------------------------------------

[[bug]]
id = "B4"
title = "The blanket IntegrityCheck digest is not 128-bit; its own comment claims it is"
severity = "should-fix"
status = "resolved"
resolved_at = "105bf05"
accepted_by = "user"
blocks_merge = false
locations = ["src/integrity.rs:98", "src/integrity.rs:104", "src/integrity.rs:56", "src/integrity.rs:131"]
violates = []
summary = """
`impl<T: Hash> IntegrityCheck for T` constructs two `DefaultHasher`s, hashes the
same value into each, and mixes the results. Both hashers see identical input
with identical construction, so `a == b` always, and the 128-bit result is a
deterministic transformation of one 64-bit hash rather than 128 bits of entropy.
The comment on line 93 says "Two independent hashers" and that is false.
"""
three_semantics_in_one_module = """
  ContentDigest::of_bytes   two FNV seeds          genuinely 128-bit   (:56)
  KeyFingerprint::of        two FNV seeds          genuinely 128-bit   (:131)
  IntegrityCheck blanket    two DefaultHashers     effectively 64-bit  (:98)
"""
impact = """
Not a vulnerability: the digest never leaves the process, so this is corruption
detection and not tamper resistance, which the module already documents. But the
collision model differs by a factor of 2^64 depending on which constructor a
caller happened to use, and the code claims a uniformity it does not have.
"""
required_fix = """
Either seed the two hashers differently so they are genuinely independent, or
reduce the blanket impl to an honestly-named 64-bit digest and document the
weaker collision bound. The second option is defensible for in-process use.
"""
required_test = """
A digest test that asserts two distinct values produce distinct digests is not
sufficient — it passes today. Assert the *stated* entropy instead, or drop the
128-bit claim from the doc comment so nothing depends on it.
"""
rationale = """
`SeededFnv`, a seeded FNV-1a `Hasher`, now backs the blanket impl, and the two
lanes are started from `FNV_OFFSET_A` and `FNV_OFFSET_B`. `DefaultHasher` cannot
be seeded, which is what made the honest construction impossible to express
before: two of them, built the same way and fed the same bytes, finished
identically. This also removes the `Self2` shim, which existed only to name the
return type.

The first candidate test was wrong in an instructive way. "The two lanes differ"
looks like it proves independence and does not: the broken impl stored
`high ^ high.rotate_left(32)`, which differs from `high` for every hash except
zero, so that assertion passed against code carrying 64 bits of entropy. Two
derived quantities being numerically unequal says nothing about whether they were
computed independently. The test that actually discriminates
(`blanket_digest_is_two_seeded_fnv_lanes_over_the_hash_stream`) records the exact
byte stream a `Hash` impl emits and pins the digest to the documented
construction.

Both `blanket_digest_is_two_seeded_fnv_lanes_over_the_hash_stream` and
`blanket_digest_lanes_are_not_a_rotate_and_xor` were run against the old
construction and fail; the rest pass either way, which is why they are corpus and
lane-variety checks rather than the regression test.
"""

[[bug]]
id = "B5"
title = "Cachelito identifies control-plane entries by a bare 64-bit hash"
severity = "should-fix"
status = "resolved"
resolved_at = "105bf05"
accepted_by = "user"
blocks_merge = false
locations = ["src/control/cachelito.rs:106", "src/control/cachelito.rs:419", "src/control/cachelito.rs:504"]
violates = ["no_cross_key_corruption = true", "theSix.toml:341"]
summary = """
`ControlEntry` stores `key_hash: u64` and `find_slot` treats
`entry.key_hash() == key_hash` as identity (line 419). Two distinct keys with the
same 64-bit hash resolve to one control entry, so one key's generation, owner,
intent and tier would be applied to the other's key.
"""
the_inconsistency = """
This is the finding the reviewer puts best. `src/integrity.rs` goes out of its way
to separate placement identity from logical identity, and explains in a comment
that conflating them is why the previous stub aliased two keys onto one slot. The
data plane took that lesson — `KeyFingerprint` plus injectable `Placement`. The
control plane did not: it still collapses placement and identity into one 64-bit
value. The branch is philosophically inconsistent with itself.
"""
why_it_is_not_merely_theoretical = """
The data-plane stub has adversarial collision tests because `Placement` is
injectable and a collision can be produced on demand. Cachelito has no injection
point and no equivalent test, so `no_cross_key_corruption` is asserted for the
control plane but never demonstrated — the property is untestable there, not
merely untested.
"""
required_fix = """
Store a `KeyFingerprint` (128-bit) alongside the placement hash in
`ControlEntry`, and compare fingerprints for identity while using the hash only
to pick a start slot — mirroring the data plane's split. If a 64-bit placement
hash is to remain, make the placement strategy injectable so a collision can be
forced and the identity check demonstrated, as `Placement::AllToZero` already
does for the stub.
"""
required_test = """
Force two distinct keys onto one placement hash in Cachelito and assert they hold
independent state — separate generations, separate owners, separate intents.
"""
rationale = """
`KeyAddress` now bundles a 128-bit `KeyFingerprint` (identity) with a 64-bit
placement hash, bundled rather than passed separately so no call site can hold a
placement without the fingerprint that justifies it. `ControlEntry` and
`CommitToken` carry the address; `find_slot` compares fingerprints and uses the
placement only to pick the start slot, mirroring `FixedTierStub`.

`Cachelito` gained `with_placement`, sharing `integrity::Placement` with the data
plane. That is what converts the finding from "untestable" to testable, and it is
the part that matters: the property was previously asserted for the control plane
with no way to produce the adversarial case.

`a_placement_collision_does_not_alias_two_control_entries` and
`a_chosen_collision_pair_stays_distinct` were run against the old conflated
comparison and fail — committing one key resolved the other to `Ready`, and two
colliding keys produced one entry instead of two. That is B5 demonstrated rather
than asserted, which is what the finding asked for and could not previously get.
"""

# ---------------------------------------------------------------------------
# ACKNOWLEDGED STRENGTHS
# ---------------------------------------------------------------------------
#
# Recorded so a later reader does not "fix" these by accident, and so the review's
# positive findings are part of the record rather than lost in a chat log.

[[strength]]
id = "S1"
area = "test architecture"
assessment = "excellent"
detail = """
The anti-vacuity discipline is the strongest part of the branch: asking whether
the fault fired, whether the stall stalled, whether the corruption corrupted,
rather than asserting `is_err()`. Coverage registries compared for equality
against the contract mean a required case cannot be silently dropped.
"""

[[strength]]
id = "S2"
area = "control/data-plane boundary"
assessment = "strong"
detail = """
Control plane -> owned snapshot -> release mutex -> await data plane, rather than
holding a shard guard across an await. The `Notified::enable()` ordering is real
race investigation: register before deciding to wait, then re-read.
"""

[[strength]]
id = "S3"
area = "L6 authority isolation"
assessment = "strong"
detail = """
`last_cache_tier = L5` with authority as a configured role, and a fail-open scan
bounded to the ladder. This forecloses the failure mode where an unavailable L5
causes the authority rung to be queried and authority data surfaced as cache
data — a violation that survives ordinary functional testing.
"""

[[strength]]
id = "S4"
area = "capability model and explicit contract"
assessment = "strong"
detail = """
Three orthogonal axes rather than one enum, and `theSix.toml` machine-checked
against the crate by `tests/contract` instead of asserted in prose.
"""

# ---------------------------------------------------------------------------
# HONEST CAVEAT
# ---------------------------------------------------------------------------
#
# Three of the blocking findings are contradictions between `theSix.toml` and the
# runtime. `cargo xtask contract` passes today because it checks the contract
# against the *runner and test inventory*, not against runtime behaviour. So the
# gate is green while B1, B2 and B3 are open. That is a real limitation of the
# current gate design, not a claim that the findings are minor.

[gate_coverage_gap]
summary = """
`cargo xtask contract` verifies that the declared architecture matches the runner
and the test inventory. It does not verify that the runtime honours the declared
invariants. `cancel_safe`, `partial_commit_visible`,
`cancelled_operation_may_commit_partially` and `recovery_direction_prepare_move`
are all declared `true`/complete-forward and are all currently false in the
implementation.
"""
implication = """
A green gate run is not evidence against B1, B2 or B3. It is evidence that the
contract is internally consistent and fully covered by declared targets.
"""
possible_followups = [
  "Have `tests/contract` assert that every clause in `theSix.toml` marked as a runtime guarantee has a corresponding test registered in the coverage registries, so a clause with no proving test is a contract failure rather than a documentation gap.",
  "Register B1-B3 in `theSix.toml` as known deviations with an explicit `known_deviation` marker, so the contract states them rather than the prose docs doing it.",
  "Gate on this file: assert no `blocks_merge = true` entry is `status = \"open\"` before release, so the tracker cannot drift from the gates.",
]
not_done = """
None of the above are implemented. They are recorded as options because
`bugs.toml` is currently a note, and a note that silently grew enforcement
semantics would misrepresent what the gates actually check.
"""

[[bug]]
id = "B6"
title = "abort restores Ready over a rung of unknown contents, so an uncommitted write becomes readable"
severity = "blocking"
status = "resolved"
resolved_at = "105bf05"
accepted_by = "user"
verified = true
blocks_merge = true
locations = ["src/control/cachelito.rs:abort", "src/control/cachelito.rs:abort_intent_by_address", "src/manager.rs:IntentGuard"]
violates = ["partial_commit_visible = false", "no_silent_data_loss = true"]
source = "second external review of PR3, at 105bf05"
summary = """
The live `WriteIndeterminate` path B2 fixed left the recovery and cancellation
paths with the same defect. On an already-populated key:

    Ready("old") -> Prepared -> tier.set("new") -> cancel -> IntentGuard::drop
                 -> abort -> Ready

The rung holds "new" and the control plane says `Ready`, so the next read serves a
value nobody authorised. The old justification — "the read path consults the
control plane first, so residue is unreachable" — held only while the entry stayed
`Prepared`, and restoring `Ready` is exactly what ended `Prepared`. The same window
existed on the recovery sweep, which has no tier handle and so cannot remove
residue even in principle.
"""
wider_than_reported = """
Two things the review did not have. First, `abort`'s own doc comment claimed it
"advance[d] the generation to invalidate anything that did land" while an inline
comment twelve lines below said the generation was deliberately not advanced. The
function did not do what its documentation said, in either direction.

Second, the root cause is that `CacheError` is asymmetric. B2 added
`WriteIndeterminate` for "my bytes may have landed" and no converse, so no other
error may be read as "they definitely did not" — including `TierUnavailable` and
`Timeout`, which are both compatible with a write that landed. `CacheError` has no
variant that means "provably stored nothing", which is why the control plane
cannot classify and must assume the worst.
"""
rationale = """
`abort` is now conservative by default: it sets `Failed` (the one state the read
path will not serve) and advances the generation, instead of restoring
`intent_prev_state`. `abort_intent_by_address` does the same, since a sweep has no
tier handle.

The restoring behaviour is preserved where it is sound, as
`abort_proven_clean`, used only for `SerializationFailed` and `CapacityExhausted`
— the two errors decided before any bytes are sent. This is a separate method
rather than a `bool` argument because the caller is what knows which errors carry
the guarantee, and a boolean eventually gets passed `true` by someone who had not
proved it.

Reviewer's option 3 (versioned writes validated on read) was not taken:
`CacheTier::get` returns bare `V`, so it would mean changing the trait across every
tier and backend. The cost of the chosen fix is one extra repopulation, not data
loss — the rung still holds whatever is there and repopulation reads it back.
"""
required_test = """
Cancellation after a write has landed, and recovery sweeping such an intent, must
both leave the entry unservable. A tier that fails cleanly proves nothing here: it
stores no residue. The test needs a tier that writes and *then* reports a failure
nobody can classify.
"""
test_note = """
`testkit::MisreportingTier` was added for this and is deliberately not a
`FaultClass`: every fault class is contract-named, and the contract already has an
honest answer (`WriteIndeterminate`, which `FaultyTier` reports via
`PartialWrite`). What the contract has no name for is a backend that returns a
clean-looking error *after* storing. Asserting against a well-behaved tier would
have proved nothing about residue, which is how this gap survived.

Three tests changed because their premise was unsupported rather than because
behaviour regressed. `a_prepared_write_aborts_and_keeps_the_committed_value`
asserted the bug: it required abort to restore `Ready`. Two fault-injection tests
asserted that an old value stays *readable* after `TierUnavailable`, which is only
sound for a provably-rejected write. Each was rewritten to assert what actually
holds — the uncommitted value is never readable, no intent leaks, the key is not
wedged — and the provably-clean case is now covered explicitly via
`CapacityExhaustion`. All three failed against the old behaviour.
"""

[[bug]]
id = "B7"
title = "The CI fuzz job's shell block has an unmatched `done`, so the smoke loop has never run"
severity = "blocking"
status = "resolved"
resolved_at = "105bf05"
accepted_by = "user"
verified = true
blocks_merge = true
locations = [".github/workflows/ci.yml:fuzz"]
violates = ["verification gates must be executable"]
source = "second external review of PR3, at 105bf05"
summary = """
The fuzz job's `run:` block ended with an `echo "::endgroup::"` and a `done` after
the closing `fi` of an `if`. GitHub runs a multiline `run:` as one shell script, so
the block is a syntax error: the step fails before the loop executes. The job is
`continue-on-error: true`, so the failure was reported as an allowed advisory
failure rather than a red job — meaning every fuzz target the job claims to
smoke-run has never actually been run in CI.
"""
why_it_matters_here = """
A branch whose stated purpose is making verification incapable of lying shipped a
verification step that could not run, hidden behind the one mechanism designed to
hide failures. The local `fuzz` gate only builds the targets; the smoke loop is
CI-only, so no local gate could have caught it.
"""
rationale = """
Removed the stray `echo`/`done`. All 22 `run:` blocks in the workflow were then
parsed with `bash -n` and are valid.

Not converted into a permanent gate, which is the real fix and is recorded as
follow-up: `xtask` would need a YAML dependency to extract the blocks, and
`xtask_unit` already runs its test suite, so a lint there would be picked up
without a contract change. Left undone rather than rushed.
"""
required_test = """
A check that every `run:` block parses. Not added — see resolution.
"""

[[bug]]
id = "B8"
title = "The workflow claimed `cargo xtask contract` validated it; nothing ever read the file"
severity = "should-fix"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = false
locations = [".github/workflows/ci.yml", "tests/contract/main.rs", "xtask/src/contract.rs"]
violates = ["verification_required = true", "anti_vacuity_required = true"]
source = "own audit of the second-review head, after an external review flagged CI as unconfirmed"
summary = """
`.github/workflows/ci.yml` carried this comment, above the job list:

    Every job below is a *contract gate*. `cargo xtask list` prints the same set
    with the contract's own descriptions; `cargo xtask contract` fails if this
    workflow and the contract disagree about which gates are mandatory.

No code read `.github/workflows/ci.yml`. `grep -r ci.yml` across `xtask/` and
`tests/` returned nothing. `tests/contract` compared the contract to the crate and
to test *registries*; `xtask/src/contract.rs` parsed `theSix.toml` alone. So the
sentence described a cross-check that did not exist, and the workflow and the
contract could have disagreed arbitrarily for the life of the repository without
anything noticing.
"""
why_this_class_of_defect_matters_here = """
This is the exact failure the repository was built to prevent, sitting in the file
that enforces the prevention. It is also self-concealing: the comment asserts the
check exists, so a reader auditing for *missing* checks finds one documented, and
a reader trusting the documentation finds no reason to look. Every prior review
round — including two that found real defects — passed this file because the
defect was a claim, not a behaviour.
"""
resolution = """
The claim is now implemented rather than deleted. `tests/contract/workflow.rs`
parses `ci.yml` with `serde_yaml` and asserts four things, each of which is
defeable on its own and so is checked in both directions:

* every gate in `[verification.gate]` is covered by some `[[verification.ci_job]]`;
* every `covers` entry names a gate that exists, so a typo cannot read as coverage;
* every job in the workflow is declared, so an undeclared job cannot verify nothing
  and still report green;
* every declared `check_name` equals the name the workflow reports, so a job
  renamed in one file and not the other fails instead of quietly ceasing to be
  required — branch protection matches on the reported name, not the job key.

`serde_yaml` is added as a dev-dependency for the same reason `toml` already was:
a hand-rolled parser is not a check. The `on:` key is read under both its string
and boolean spellings, because YAML 1.1 resolves it to `true` and the checker
should not depend on which schema the parser implements.
"""
rationale = """
Implemented in `tests/contract/workflow.rs` and mutation-tested: each of the four
assertions was verified to fail against a workflow mutated to break exactly its
property, including a job renamed in the workflow only and a job added to the
workflow but not the contract.
"""

[[bug]]
id = "B9"
title = "No declared runtime invariant was bound to a proving test"
severity = "should-fix"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = false
locations = ["theSix.toml", "tests/contract/main.rs", "tests/property/main.rs"]
violates = ["verification_required = true", "anti_vacuity_required = true"]
source = "external review of the second-review head, named as the remaining meta-level weakness"
summary = """
The contract declares 95 invariant leaves across seven semantic sections. Before
this revision, exactly one — the move recovery direction — was checked against
runtime behaviour. Everything else was checked only for *shape*: that flags were
set, that layers had test targets, that negative cases had cases, that property
invariants were enabled.

`every_property_invariant_is_enabled` is representative. It asserts each named
property invariant equals `true` in the contract. It does not assert any test
exercises it. The registry lists `no_deadlock` and `no_lock_across_await`; the
only thing connecting them to a test is a comment above `proptest!` at
`tests/property/main.rs:349`. So declaring a new invariant cost nothing, which is
the over-promise the contract exists to make impossible.
"""
audit_result = """
Every one of the 95 was assigned a proof or a waiver by reading the tests rather
than by matching section names. 89 have a proving test. 6 are waived with a stated
reason, and the six are real gaps rather than bookkeeping:

* `cia.availability.unbounded_retry` — nothing counts retries. Ladder descent is
  bounded by `LAST_CACHE_TIER`, but no test asserts a retry count.
* `cia.integrity.silent_stale_data_acceptance` — nothing distinguishes *silent*
  stale acceptance from explicit stale service.
* `capabilities.must_distinguish.recovering_from_available` — the state is
  representable and required, but no test drives a rung into `Recovering`.
* `concurrency.blocking_runtime_thread` — every tier is an in-process stub, so
  there is no blocking call for a test to catch.
* `concurrency.nested_block_on` — nothing in the suite nests `block_on`, so the
  invariant is unobserved rather than verified.
* `concurrency.testing.promotion_eviction_races` — eviction is not implemented, so
  there is no race to schedule. Tied to the known eviction limitation.
"""
extra_gap_found_by_the_audit = """
The twenty `required = true` flags under the semantic sections were asserted by
nothing at all. `required_verification_flags_are_all_set` checks
`verification.required`, a different table. So `acid.consistency.required = false`
— a section withdrawing its own guarantee — would have passed every gate. Adding
`every_semantic_section_is_marked_required` closed it, and its floor assertion
(`checked >= 13`) caught a miscount in the check itself during development.
"""
resolution = """
Split so neither side can satisfy itself: `testkit::coverage::INVARIANT_PROOFS`
holds invariant to `path::fn` (what the tests exercise), and
`[[verification.invariant_waiver]]` in `theSix.toml` holds invariant to reason
(what is admitted to be unverified). `tests/contract/invariant.rs` requires the
union of the two to equal the declared set exactly, so adding, renaming or deleting
an invariant all fail until the registry moves with it, and every cited test must
resolve to a real function in a real file.
"""
rationale = """
All six assertions mutation-tested. The registry is deliberately split rather than
duplicated into the contract so the test side owns test knowledge and the contract
side owns the admitted gaps; a self-graded registry would be the `expected_blocking`
defect repeating one level down.
"""

[[bug]]
id = "B10"
title = "Five mandatory gates ran in no CI job, and CI never ran for a stacked PR at all"
severity = "blocking"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = true
locations = [".github/workflows/ci.yml", "theSix.toml", "tests/contract/workflow.rs"]
violates = ["verification_required = true", "partial_commit_visible = false"]
source = "own audit, prompted by an external review noting CI execution was unconfirmed"
summary = """
Two independent defects, both meaning that "the gates are green" was a local fact.

**CI could not run for this branch.** The triggers were `push` and `pull_request`,
both filtered to `branches: [main]`. Every PR in this repository is stacked on a
feature branch, so the filter excluded all of them. `gh run list --branch
feat/hpa-continuity-contract` returned nothing; the last CI activity in the
repository was 2026-10-03, on the PR2 base. All four PR3 commits had never been
executed by CI, which is why an external reviewer could not confirm execution and
had to say so.

**Five mandatory gates were executed nowhere.** Of the 25 gates in
`[verification.gate]`, `fmt` ran as a raw `cargo fmt --check` rather than the gate,
`xtask_unit` had no job at all — so the tests for the code that decides which gates
pass ran only on the maintainer's machine — and `deny` and `machete` were shadowed
by `cargo-deny-action` and `cargo-machete@main`, which are third-party actions that
merely resemble the gates and can drift from them. `fuzz` built targets directly
instead of through its gate.
"""
further_defects_found_while_fixing_this = """
Three more, all from reading the file rather than trusting it:

* `cargo xtask run check -- --verbose || cargo xtask run check` — the first command
  rejects `--verbose` and *always* fails, so the `||` fallback is what actually
  ran. A blanket retry reporting success on the strength of its second attempt,
  present on every CI run of the `lint` job.
* `cargo-machete@main` was a floating branch ref, as are
  `taiki-e/install-action@nextest` and `dtolnay/rust-toolchain@stable`. On a branch
  whose thesis is that verification cannot lie, an unpinned action is a supply-chain
  hole. `nextest` is now pinned to `@cargo-nextest` and the floating `cargo-machete`
  is gone with the action; `rust-toolchain@stable` remains, and the *toolchain*
  version is pinned by `env.RUST_TOOLCHAIN`, so the residual risk is the action's
  own code rather than the compiler version.
* `main` had no branch protection, so all eleven `verification.required` flags were
  decorative. Nothing enforced them at merge time.
"""
resolution = """
`pull_request` is now unfiltered — safe here because the only secret used is
`GITHUB_TOKEN`, which GitHub still supplies read-only to fork PRs. Every unwired
gate now runs as `cargo xtask run <gate>` in the job that covers it, so CI executes
the contract's gate rather than a lookalike. `[[verification.ci_job]]` in the
contract declares the mapping and `tests/contract/workflow.rs` holds both ends to
it, which is what makes C5's coverage claim checkable rather than asserted.

For branch protection, requiring the individual jobs is not viable: `test` is a
10-leg matrix reporting `Tests (unit)`, `Tests (negative)`, ... so a required-check
list built from those names silently stops matching when the layer list changes. A
`verify` aggregator job with `if: always()` reports one stable check name, and the
contract test asserts every non-advisory job is in its `needs` — so a new job that
forgot to be added fails the gate instead of running outside the aggregate.
"""
rationale = """
`if: always()` is load-bearing and separately asserted. Without it a failed
dependency makes the aggregator *skipped*, and GitHub scores a skipped required
check as passing, so the one job branch protection requires would report success
precisely when something broke. Verified that the trigger, the gate-coverage
mapping and the aggregator wiring each fail when mutated.
"""

[[bug]]
id = "B11"
title = "A committed cargo config made sccache mandatory, so every CI job failed before compiling"
severity = "blocking"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = true
locations = [".cargo/config.toml", ".github/workflows/ci.yml"]
violates = ["verification_required = true"]
source = "first execution of CI on this branch, after B10 made CI run at all"
summary = """
The first CI run on this branch failed *every* job, at the `cargo xtask` step,
with one error repeated fourteen times:

    error: could not execute process `sccache .../bin/rustc -vV` (never executed)
    Caused by: No such file or directory (os error 2)

`.cargo/config.toml` sets `build.rustc-wrapper = "sccache"`, which makes sccache
a *hard prerequisite* for any cargo invocation — not an accelerator that is used
when present. GitHub's runner image does not ship it. So no job could run a single
cargo command, and the failure appeared in the rust-cache action's post step as
`cargo metadata` exiting 101, some distance from the cause.
"""
provenance = """
The config was added in `38887d2`, dated 2026-10-04. The last CI run in the
repository was 2026-10-03, on the PR2 base. So this file had never been executed
by CI at all before B10 made CI run — the same failure mode as the original B7
fuzz job, one level up: a verification path that could not execute, discovered
only once something finally executed it.

Worth noting because it inverts the usual expectation. CI had been *green* for
this code locally, `cargo xtask run all` passes on a machine that happens to have
sccache, and the committed config actively hides the dependency rather than
declaring it. Nothing in the repository said "sccache is required to build"; the
only evidence was a comment describing how to bypass the cache.
"""
resolution = """
CI now installs sccache explicitly with `mozilla-actions/sccache-action@v0.8` in
all fourteen jobs that invoke cargo, rather than relying on the runner image.
Adding it per job rather than centrally is deliberate: GitHub has no shared step
list, and a composite action would hide the dependency behind an indirection that
reads like the runner provides it.

The committed config is kept rather than removed, because local and CI should
compile the same way and the cache is worth having on the overlapping feature
matrix. The comment now states the actual failure mode — that the wrapper must
exist, that CI installs it rather than inheriting it, and that the override on a
machine without sccache is `--config 'build.rustc-wrapper=""'` rather than an
environment variable.
"""
rationale = """
Discovered only by running CI, which is the argument for B10 rather than an
endorsement of it. The honest sequence is that fixing "CI does not run" revealed
"CI cannot run", and both were invisible until the first was fixed.
"""

[[bug]]
id = "B12"
title = "The gate runner leaked cargo's description of its own package into every gate it spawned"
severity = "blocking"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = true
locations = ["xtask/src/gates.rs", "xtask/src/contract.rs", "theSix.toml"]
violates = ["verification_required = true", "tool probing and argv construction are under test rather than trusted"]
source = "second CI run on this branch, after B11 was fixed"
summary = """
With CI running, the `Dependency audit` job failed at `machete`:

    Analyzing dependencies of crates in machete...
    Error: Errors when walking over directories:
    machete: IO error for operation on machete: No such file or directory

`cargo machete` had been told to analyse a directory called `machete`. The cause
is that `cargo xtask run <gate>` is `cargo run --package xtask --`, and cargo
exports `CARGO_MANIFEST_DIR` plus the `CARGO_PKG_*` family describing *xtask's own
package* into the process it runs. xtask spawned gates with that environment
intact, so `cargo machete` read `CARGO_MANIFEST_DIR`, decided it had been pointed
at `xtask/`, and walked the wrong tree.

The gate passed when xtask was invoked as `./target/debug/xtask`, which inherits
none of those variables, and failed under `cargo xtask` -- which is what the
README, `AGENTS.md` and the CI workflow all tell you to use. The documented
invocation was the broken one and the working one was undocumented.
"""
resolution = """
`scrub_cargo_env` strips `CARGO`, `CARGO_MANIFEST_DIR`, `CARGO_MANIFEST_PATH`,
`CARGO_CRATE_NAME`, `CARGO_BIN_NAME`, `CARGO_PRIMARY_PACKAGE`, `CARGO_TARGET_TMPDIR`
and every `CARGO_PKG_*` from each spawned gate. xtask is a gate runner, not a cargo
subcommand; its children should see the caller's environment. The `CARGO_PKG_*`
family is enumerated rather than hard-coded because it grows with manifest fields.
`LD_LIBRARY_PATH` is deliberately left alone -- it is how cargo locates the freshly
built binary and it has caused no observed misbehaviour, so removing it would
exceed the evidence.
"""
rationale = """
The regression test reads `CARGO_MANIFEST_DIR` from the test process instead of
assigning it, because `std::env::set_var` is unsafe in edition 2024 and the crate
forbids unsafe code. That is not a compromise: `cargo test` sets exactly these for
the test binary, so the test observes the real condition. It fails if the scrubbing
is removed, and needs no edit when cargo adds another variable.
"""

[[bug]]
id = "B13"
title = "The check and clippy gates never compiled or linted the gate runner or the test harness"
severity = "should-fix"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = false
locations = ["theSix.toml", "xtask/src/gates.rs", "xtask/src/contract.rs"]
violates = ["clippy_warnings_as_errors = true", "verification_required = true"]
source = "own audit, surfaced while fixing B12"
summary = """
`check` and `clippy` ran `cargo check/clippy --all-targets --all-features` with no
`--workspace`. TheSix's `Cargo.toml` is both a package and the workspace root, so
cargo defaulted to the current package: the crate under test was linted and the two
other workspace members were not. `xtask` and `testkit` are separate crates.

So `verification.required.clippy_warnings_as_errors = true` was true of the library
and silent about the gate runner -- the code that decides which gates pass. Four
warnings had accumulated there, including one that would have been caught the moment
the gate existed. Nothing noticed, because no gate looked.
"""
further_divergence_found_while_fixing_it = """
`[verification.merge_readiness].tracker = "bugs.toml"` was declared in the contract
and ignored: the gate joined a literal `"bugs.toml"` onto the root. A declared
setting the code never read, which is the same shape as the workflow comment in B8.

Separately, `bugs.toml`'s own `[meta]` counts are *deliberately* not consulted, and
the struct fields that parsed them were dead code. That part is right -- a tracker
that states its own expected contents can be edited to agree with whatever it
currently holds -- so the fields were removed with the rationale kept in a comment
rather than "fixed" into use.
"""
resolution = """
Both gates now pass `--workspace`. Four latent warnings became hard failures and
were fixed: the misplaced `#[must_use]` described in B12's companion commit, two
collapsible `if let` chains in the merge-readiness count check, and two
`useless_format` calls in the gate's own tests.

The contract's `tracker` value is now read and used instead of hardcoded, with a
test that rewrites the declared path in a fixture and asserts the loaded contract
follows it -- asserting the default value would not have caught the divergence.
"""
rationale = """
`--workspace` on a linter is the same argument as `serde_yaml` for the workflow
check: a gate that claims to cover the repository should ask the tool to cover the
repository. Both new assertions were mutation-tested.
"""

[[bug]]
id = "B14"
title = "The fuzz job named an installer tag that does not exist, so cargo-fuzz was never installed"
severity = "blocking"
status = "resolved"
resolved_at = "second-review-remediation"
accepted_by = "user"
verified = true
blocks_merge = true
locations = [".github/workflows/ci.yml"]
violates = ["verification_required = true"]
source = "second CI run on this branch, from the advisory fuzz job's exit-3 result"
summary = """
B7 fixed the fuzz job's shell syntax, and the smoke loop became structurally
correct. It still could not run, because the fuzzer it drives was never installed:

    INPUT_TOOL:
    ##[warning]no tool specified; this could be caused by a dependabot bug
    where @<tool_name> tags on this action are replaced by @<version> tags

`taiki-e/install-action@cargo-fuzz` refers to a tag that does not exist. The action
handles an unrecognised ref by warning and installing nothing, then exiting 0 -- so
the step reports success and the job proceeds with no `cargo-fuzz` binary. Every
`cargo +nightly fuzz run` in the loop then fails, and under `continue-on-error`
that reads as an allowed advisory failure.

Confirmed by querying the action rather than guessing: among its 1347 tags,
`cargo-nextest`, `cargo-deny` and `cargo-machete` each exist exactly once and
`cargo-fuzz` exists zero times, and `TOOLS.md` never mentions the tool. So this was
never going to work, and the tag predates this branch's changes -- B7's fix made a
loop correct that had never had a fuzzer to run.
"""
resolution = """
`cargo +nightly install cargo-fuzz --locked` in the job. The fuzz job already
installs nightly with `llvm-tools-preview`, which is what cargo-fuzz needs, so
compiling it from source adds no new prerequisite. `--locked` because an unlocked
`cargo install` resolving different transitive versions on a nightly compiler is
how an advisory job starts failing for reasons unrelated to the code under test.
"""
rationale = """
The general defect is a build step that reports success having done nothing. This
workflow had two of them -- B11's missing sccache and this -- and both were
invisible locally because both only fail where the tool is absent. The honest
summary is that CI executing for the first time found three separate things that
had never run, which is an argument for the unfiltered `pull_request` trigger and
against every claim in this repository that the gates were already covering it.
"""

# ---------------------------------------------------------------------------
# OPEN, NON-BLOCKING — REMAINING WORK
# ---------------------------------------------------------------------------
#
# B15–B20 come from an independent review of both PRs at the current heads, which
# returned MERGEABLE for each with no blocking finding. The six items below are
# that review's "remaining engineering debt", recorded here so they are tracked by
# a gate rather than living only in prose.
#
# None of them blocks a merge, and the mechanics are deliberate rather than
# accidental: `merge_readiness` inspects `status` only for entries with
# `blocks_merge = true`, so an open non-blocking finding is counted by the check
# and does not fail it. That is the behaviour wanted here — the work is real and
# should not be forgotten, and it is also genuinely not a reason to hold a branch
# whose blocking findings are all cleared.
#
# `status = "open"` is therefore accurate, not a euphemism. If any of these is
# promoted to `blocks_merge = true` before it is fixed, the gate goes red
# immediately, which is the intended pressure.

[[bug]]
id = "B15"
title = "A swept Move intent wedged its key's population path permanently"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [
  "src/manager.rs:recover_older_than",
  "src/control/cachelito.rs:release_population_claim",
  "src/continuity.rs:RecoveryReport",
]
violates = []
source = "independent review of both PRs at 5ab1aaa; confirmed against source during the 0.4.0 backlog pass"
relates_to = "B3"
summary = """
B3 made the direction honest -- a `Move` maps to `ExternalReconciliation`, not
`complete-forward` -- and left a capability gap with a permanent cost. The sweep
counted a move in `needs_reconciliation` and left the entry `Prepared` with
`population_owner = true`. Both `acquire` and the write path decline a `Prepared`
entry that holds an owner, so nothing could ever write or populate that key
again; only an external reconciler holding the key bytes could clear it, and one
that never arrived left the key wedged for the life of the process.
"""
fix = """
The claim is now released while the intent is deliberately **kept**.

`Cachelito::release_population_claim(address)` marks the entry `Failed`, advances
the generation and drops the population owner, without clearing the intent.

Two decisions inside that, both load-bearing:

* `Failed` rather than the restored pre-intent state. Restoring would point the
  control plane at a source rung the interrupted move had already emptied, and a
  read would serve that emptiness as though it were the value -- turning a
  visible wedge into silent wrong data. `Failed` points nowhere: reads miss, and
  a later write supersedes whatever the move left behind. It is sufficient to
  unblock the key because `acquire` already accepts `Absent | Failed | Stale`.
* The intent is retained rather than cleared. Clearing it, as
  `abort_intent_by_address` does, destroys the only record that a move was in
  flight, and the control plane keeps only a key hash -- so the report could say
  "one move needs reconciliation" without saying which key. Retaining it costs
  nothing operationally because `prepare` overwrites an existing intent rather
  than refusing, so the key stays writable and the evidence survives until the
  key is next written.

`RecoveryReport` gains `released_for_reconciliation`, kept separate from both
`recovered` (nothing was recovered) and `needs_reconciliation` (that is the
obligation, this is the remedy taken for the wedge). Folding them together would
make a stuck key look like ordinary contention, which is the confusion this
finding was filed against.
"""
verification = """
`an_unresolvable_move_is_reported_separately_from_a_failure` extended rather than
replaced. Its three original assertions (recovered 0, needs_reconciliation 1,
failed 0) are untouched and still hold. The state assertion changed from
`Prepared` to `Failed`, with the reason stated in the test, and the retained
intent assertion is unchanged -- so the evidence property is still proven.

New assertions: the population owner is cleared, and a fresh `set`/`get` through
the released key succeeds. Mutation-checked: with the release made a no-op the
test fails on the state assertion.

One test detail worth recording: the second sweep phase originally reused the
same key, and its move count went to zero because the write added above had
legitimately superseded the retained intent. That is the intended lifecycle, not
a defect, so the phase now uses a distinct key and says why.
"""
rationale = """
Fixed rather than accepted. The crate's refusal to resolve the move is correct
and unchanged; what was wrong was paying for that honesty with a permanently
unusable key. Releasing the claim while keeping the evidence makes the cost
proportional -- an obligation reported, not a wedge.
"""

[[bug]]
id = "B16"
title = "Four declared invariants had no proving test; one cannot be closed without a contract decision"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [
  "src/manager.rs:refresh_detailed",
  "src/capability.rs:OperationalState",
  "theSix.toml:verification.invariant_waiver",
  "testkit/src/coverage.rs:INVARIANT_PROOFS",
]
violates = [
  "capabilities.must_distinguish.recovering_from_available",
  "cia.availability.unbounded_retry",
  "cia.integrity.silent_stale_data_acceptance",
  "concurrency.nested_block_on",
]
source = "0.4.0 backlog pass; re-examined each waiver individually rather than in bulk"
relates_to = "B19, B20"
summary = """
Five declared invariants had no proving test and were waived. Each waiver is a
statement that a clause exists with nothing behind it, which is the same defect
B18 and B20 describe for other parts of the contract.

Four are now proven. The fifth turned out not to be a missing test but a missing
mechanism, and is reported rather than closed.
"""
fix = """
`cia.integrity.silent_stale_data_acceptance` required an implementation, not a
test. `refresh` returned `Option<V>`, so a value served because revalidation
failed was byte-identical to one the fetch had just produced, and the caller could
not tell. Two changes:

* `refresh_detailed` returns `Lookup<V>` with a `Freshness` of `Fresh` or `Stale`.
  `refresh` is now the lossy wrapper over it, so existing callers are unaffected
  and revalidating callers can opt into the distinction.
* `refresh` fails *closed* on the fetch and applies its own documented
  stale-while-revalidate fallback. Previously the policy's fail-open mode let
  `become_population_owner` scan other rungs and return their value as a
  successful population -- indistinguishable from a fresh value. That was the
  invariant failing at the only place it could: not by serving stale bytes, but by
  serving them with a success status claiming they were current.

`capabilities.must_distinguish.recovering_from_available` needed a tier that can
report the state at all. Every in-tree stub reports one state, so the waiver said
"no test exists" when the truth was "no test could exist". `StatedTier` in testkit
overrides only `state`, leaving `backend` to the inner tier so a test cannot claim
a backend the rung was not built with.

`cia.availability.unbounded_retry` counts rather than assumes. Each of the three
retry loops is asserted separately, because any one could be made unbounded alone.

`concurrency.nested_block_on` is a source scan backed by a mechanism: the test
also asserts that nested `block_on` *panics*. Without that half the scan would be
textual opinion, and a `block_on` on a non-runtime thread would pass it while
reintroducing the deadlock.
"""
verification = """
`stale_service_is_reported_rather_than_silent` mutation-checked: labelling the
stale arm `Fresh` fails it.

`retry_counts_are_bounded_and_observed` initially asserted the write was offered
to every rung once, and failed with 2 of 6. That assertion was wrong, not the code:
the walk starts at the rung policy chose and steps toward L0, so it does not visit
rungs the policy never routed to. The test now asserts the property the invariant
actually names -- no rung is offered more than once -- and says why coverage is not
the claim. Worth recording as a case where reading the failure would have been easy
to misattribute.

`nested_block_on_is_absent_from_the_crate_and_would_be_caught` scans non-comment
lines only, since the trait docs and the test itself discuss the hazard by name.

`concurrency.blocking_runtime_thread` is the one that stays waived, and it is not a
test gap. `spawn_blocking` appears nowhere in `src/` and the contract has no clause
requiring it; the obligation exists only as prose in the `CacheTier` doc comment,
which places it on backend implementors -- user code this crate cannot instrument.
Closing it honestly requires either narrowing the clause to what the crate
guarantees, or adding a real offload path plus a blocking in-tree backend. The
waiver now states both options instead of describing a missing test that could
have been written.
"""
rationale = """
Four closed because each had a real property behind it and a real proof available.
The fifth is left open with a decision attached rather than closed with a test that
would have proven something else.
"""

[[bug]]
id = "B17"
title = "Nothing evicted, so a cache whose whole ladder is full refused new writes"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [
  "src/manager.rs:set",
  "src/control/cachelito.rs:reserve_eviction",
  "src/tier/trait.rs",
  "src/tier/fixed_tier_stub.rs",
]
violates = ["concurrency.testing.promotion_eviction_races"]
source = "independent review of both PRs at 5ab1aaa; scope re-derived during the 0.4.0 backlog pass"
relates_to = "B16"
summary = """
`FixedTierStub::set` returns `CapacityExhausted` when its slot table is full, and
`set` degrades down the ladder on that error. The walk reaches L1 and then L0,
and when both are full there is nothing left to degrade to, so the write was
refused. Measured on `main` at `e46a041`: 1_024 keys accepted at L1, 953 at L0,
then `CapacityExhausted` on write 1_977 -- and never again.

`find_empty` already reclaimed empty, self-owned and *expired* slots, so the
real gap was narrower than the finding implied: only a full table of live
non-expiring entries could never be reclaimed.
"""
fix = """
Eviction, in three parts so the data plane never decides anything:

* `CacheTier` gains `eviction_candidate()` and `remove_if_address()`, both
  defaulted pessimistically (`None` / `Ok(false)`) in the spirit of
  `capability()`. A tier nominates; it does not authorise.
* `Cachelito::reserve_eviction(address)` is the authority. Under the shard lock
  it admits only an entry that is `Ready`, unowned and intent-free, and it
  advances the generation *before* returning, so a commit holding a token for the
  old generation is refused rather than landing in a slot about to be reused.
* `set` calls eviction only once the ladder walk is exhausted, coldest bound rung
  first, and re-walks. It is a last resort, not the first move: degrading
  preserves a hotter rung's contents, whereas evicting at the first full rung
  destroys them.

Evicting from the data plane alone would have been unsafe, and the reason is
worth recording because it shaped the whole design: an eviction that did not
touch the control plane would leave the generation untouched, so a writer
between `prepare` and `commit` would still commit successfully -- into a slot
now holding a different key's value. That is silent stale data, the same family
as B2/B6/B19.
"""
verification = """
`eviction_reclaims_a_saturated_ladder` is a declared negative case in
`theSix.toml` and `NEGATIVE_CASES`, proven in the negative layer: 4_000 writes
are all accepted where `main` refused at 1_977, and every read is checked to
return either the correct value or a miss -- never a wrong one.

Two authorisation tests in the concurrency layer prove the safety properties:
an entry with an outstanding commit intent is not evictable, and a settled
`Ready` entry is. `removing_by_a_stale_address_refuses_and_keeps_the_value`
covers the address-conditional removal.

The conditional removal was mutation-checked: made unconditional, it fails with
"a foreign address must never remove a resident slot" (`left: true,
right: false`). The generation bump is defence in depth and is *not* covered by
that mutation -- the eligibility refusal is what closes the tested window -- so
it is recorded as belt-and-braces rather than claimed as load-bearing.

Two soak assertions changed, and deliberately so. `the_default_ladder_survives_a_key_flood`
previously required every accepted value to still be readable, which was true
only *because* a full ladder refused writes. It now requires the narrower and
stronger property: a read returns the correct value or a miss, never a different
value. 1_031 of 3_000 reads report a miss (evicted) and none report a wrong
value. `the_manager_degrades_down_the_ladder_before_it_fails` was left untouched
and still passes, which is the check that eviction did not quietly become the
first move.

Three mistakes during this work are worth recording because each was caught by a
test rather than by reading:

* evicting hottest-rung-first, which kept L1 accepting every write and meant the
  ladder never degraded -- caught by the untouched degradation test;
* gating eviction to `pass == 0`, which allowed exactly one eviction per process
  and then refused again -- caught by the flood test still stopping at 1_964;
* several edits that silently failed to apply, producing false readings. Every
  later edit asserts its anchor.
"""
rationale = """
Fixed rather than waived. "A cache that eventually stops accepting writes" is a
defect in the thing the crate exists to be, and the safe version needed the
control plane involved, which is now how it works.
"""

[[bug]]
id = "B18"
title = "Every third-party CI action was pinned by a mutable tag rather than a commit SHA"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [".github/workflows/ci.yml", "tests/contract/main.rs", "theSix.toml"]
violates = []
source = "independent review of both PRs at 5ab1aaa"
relates_to = "B20"
summary = """
All 64 `uses:` references across the workflow resolved to only seven distinct
actions, and every one of them was pinned by a tag or branch: `actions/checkout@v4`,
`Swatinem/rust-cache@v2`, `dtolnay/rust-toolchain@stable`, `@nightly`, and three
`taiki-e/install-action@<tool>` refs. `mozilla-actions/sccache-action` was the
sole exception, already SHA-pinned.

A tag is a mutable pointer. Whoever controls the tag can repoint it at new code,
which then runs with this repository's credentials and cache-write access.
"""
fix = """
All 64 references are now pinned to full commit SHAs, each retaining its version
label as a trailing comment so the pin stays readable and updatable:

    actions/checkout@11d5960a... # v4

Pinning alone fixes today's workflow and does nothing about next quarter's, so
`engineering.ci_actions_sha_pinned` is declared in the contract and enforced by
`every_ci_action_reference_is_pinned_by_sha` in the contract layer. The clause
is read from the TOML rather than hardcoded, so weakening the contract weakens
the check honestly instead of quietly.
"""
verification = """
Mutation-checked: re-tagging a single reference makes the contract gate fail and
name the offending lines. With the pins in place the gate passes over all 43
references in the file.

Note the tradeoff this accepts: pinning `dtolnay/rust-toolchain` to a SHA stops
it tracking the toolchain automatically, so toolchain bumps are now a
deliberate, reviewed change. That is the intended cost -- an unreviewed
automatic bump of a credentialed action is the risk being bought down.
"""
rationale = """
Closed rather than waived. It was mechanical, it had a one-line regression guard,
and leaving mutable refs in a release-boundaried repository while claiming a
supply-chain-conscious dependency posture (`deny` gate, `machete` gate) would
have been inconsistent.
"""

[[bug]]
id = "B19"
title = "A read overlapping an abort was handed a value the control plane had stopped describing"
severity = "blocking"
status = "resolved"
blocks_merge = true
verified = true
locations = [
  "src/manager.rs:719",
  "src/control/cachelito.rs:808",
  "src/tier/trait.rs:165",
]
violates = ["cia.integrity.silent_stale_data_acceptance"]
source = "settled by the test this finding asked for; the answer was the second of the two outcomes it named"
relates_to = "B6"
summary = """
This was the tracker's only `verified = false` entry, on the deliberate grounds
that nobody had forced the interleaving, so the concern was unproven in *either*
direction. It is now proven, and proven in the direction that promotes it.

`get` peeks, and on `Ready` awaits the tier. That is the one window in `get`
with no guard across it. An `abort` landing during the await leaves the entry
`Failed` with the generation advanced, while the rung still holds the residue of
the abandoned write -- and the caller received that value regardless.

Settled with `a_read_that_overlaps_an_abort_reports_what_the_control_plane_now_says`,
which parks the read inside the tier with `GateTier` so the abort is placed
deterministically rather than hoped for. Against the unfixed code it reports:

    B19 CONFIRMED as a defect: the caller received "seeded" while the control
    plane describes the entry as Failed at generation 1 (was Ready at 0)

which is the second outcome `what_would_settle_it` described, and that entry
instructed promotion to `blocks_merge = true` immediately.
"""
fix = """
`get` now revalidates after the tier read: if the settled entry is no longer
`Ready`, the value is discarded and `Miss` is reported, matching the existing
`InFlight` arm's treatment of a settled non-`Ready` entry.

Only the *state* is rechecked, not the generation. A benign concurrent commit
does not disown an entry -- the value is still one this cache committed -- while
`Failed` means the value is residue of an abandoned intent and must not be
served. Checking state keeps the read path's cost to one extra control-plane
observation rather than turning every generation bump into a miss.
"""
verification = """
Mutation-checked: with the revalidation removed the test fails with the
CONFIRMED message; with it in place all 7 concurrency tests pass. 23/23
mandatory gates green, `performance` and `soak` unaffected by the extra
observation.
"""
rationale = """
Promoted and fixed rather than closed. This was reachable in ordinary operation
-- a `get_or_fetch` that fails mid-flight, concurrent with a `get` already parked
on the rung -- and it served residue of an abandoned intent, which is the same
family as B2 and B6. The finding's own text said so.
"""

[[bug]]
id = "B20"
title = "The proof registries prove a test is named and exists, not that it exercises the clause"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [
  "testkit/src/coverage.rs:missing_locators",
  "testkit/src/coverage.rs:declares_clause",
  "testkit/src/lib.rs:proves",
  "tests/contract/invariant.rs",
]
violates = []
source = "independent review of both PRs at 5ab1aaa; stated by this repository's own documentation"
relates_to = "B9, B16"
summary = """
Three registries bind declared names to proving tests: `INVARIANT_PROOFS` (94
rows), `PROPERTY_CASE_PROOFS` (9) and `FAULT_CASE_PROOFS` (12). `missing_locators`
resolved each `path::fn` and checked a function of that name was defined in that
file. It did not check that the function was a test, and it did not check that the
test exercised the clause it was cited for. A row pointing at a real but
irrelevant function satisfied the gate.
"""
what_is_and_is_not_closed = """
Closed by the required fix: a locator that resolves but does not declare the clause
now fails, so citing the wrong test cannot pass quietly.

Closed earlier: a declared clause cannot exist without something responsible for
it, and a test cannot be renamed out of a citation. The locator match is
word-bounded after mutation testing showed the substring form let
`no_authority_inversion_RENAMED` satisfy a claim on `no_authority_inversion`.
"""
required_fix = """
Per-row fault-ledger assertion, which is the instrument the fault layer already
uses: each row asserts that the thing it injects actually happened, so a citation
to an irrelevant test fails rather than passing quietly. A stricter string match
cannot close this and should not be mistaken for progress toward closing it.
"""
fix = """
The label moved into the test. Every proving test now declares what it proves:

    testkit::proves!("clause.a", "clause.b");

which expands to a `const _` binding, so it is real code the compiler checks
rather than a comment a reader has to trust. The gate then requires the cited
function's *own* declaration to contain the cited clause. A mis-citation fails,
because the wrongly cited test's list does not contain that clause -- the registry
says which test it expects, the test says what it proves, and the two must agree.

75 functions annotated across all three registries, mechanically from the registry
itself so no row could be skipped by hand.

The span is delimited by line rather than by matching braces. A brace scanner has
to understand char literals, lifetimes, raw and byte strings, and braces in
comments; a first attempt failed on exactly that and reported a body it could not
close for a function that closes perfectly well.
"""
verification = """
Four mutations, each of which a substring implementation would have passed:

* M1 -- repoint a row at a real, unrelated test: caught.
* M2 -- repoint it at a different test in the same file that discusses the same
  behaviour: caught, because the span is per-function.
* M3 -- replace the declaration with a comment naming the clause. **This one was
  not caught at first.** `// proves!("clause")` contains the same bytes as the
  declaration, so the substring check passed with the declaration commented out.
  `declares_clause` is now anchored to the start of a trimmed line, and skips
  comment lines inside the argument list.
* M4 -- rename one clause inside a multi-clause declaration: caught, because
  literals are compared whole, so `a.b` cannot match a declared `a.b.c`.

Two implementation faults were found by the gate itself rather than by reading:

* `enumerate()` supplies an item index, not a byte offset. Used as one it truncated
  every span to sixteen characters, so all 115 rows looked undeclared and the
  failure looked like a missing-annotation problem. The Python model of the same
  logic tracked bytes and passed, which is what identified the discrepancy.
* After that fix, 38 rows still failed because `cargo fmt` wraps the `proves!`
  call when a test proves several clauses, and the single-line parser read an empty
  argument list. Not a data problem: a formatting interaction.

A `git checkout` of `tests/integration.rs` during M3 also wiped that file's
annotations, which the re-annotation pass had to restore. Worth recording because
the restored state was verified by re-running the gate rather than assumed.
"""
rationale = """
Fixed, because the required fix is available in the same shape as an instrument
the crate already trusts. What remains irreducible is a test that asserts the wrong
thing while declaring the right clause: a declaration is a claim by the test about
itself, so it can be wrong in the same way any test can be wrong. That is what the
mutations above bound -- not truth, but the ability of a reviewer to catch a false
claim mechanically rather than by reading 76 tests.
"""
do_not_evolve_into_a_parser = """
Recorded because an external review of PR #7 raised it unprompted, and because the
instinct to "improve" this code is the most likely way to make it worse.

`function_span` and `declares_clause` are line heuristics, and they are acceptable
*because of which way they fail*. A test that declares nothing, or that declares the
clause in a different function, is reported as undeclared -- so the gate goes red and
a human looks. The dangerous direction is a false positive, where a declaration is
credited to a test that does not contain it, and that is the direction the design
avoids: the span is per-function, literals are compared whole, and the opener must
begin a trimmed line.

So: do not replace this with a real Rust parser. A parser would be more correct and
would fail in a new direction -- it would start *rejecting* valid declarations for
subtle reasons, and the pressure to loosen it would reintroduce the false positive
this shape avoids. That is humanity's traditional solution to a systems problem: add
machinery until the original failure is nobody's memory.

If stronger semantic proof is wanted, the route is explicit coupling -- per-row
fault-ledger assertions, the instrument `fault_injection` and `declare_cases!` already
use -- not cleverer source reading. A registry row that must also say *which assertion*
in the test carries the proof can be checked without parsing Rust at all.
"""
scope_limit = """
The parser reads `tests/` and `xtask/src/` through the same path, which is why
`verification.merge_readiness.tracker` can be proven by an `xtask` unit test: the gate
requires no particular file kind, only that the path resolves and the cited function
declares the clause. Making `proves!` reachable from `xtask` needed `testkit` as an
xtask dev-dependency, chosen over duplicating the macro so there is one definition of
what a declaration is.
"""

[[bug]]
id = "B21"
title = "main's required_status_checks rule is DISABLED and must be re-enabled after the 0.4.0 merge"
severity = "should-fix"
status = "open"
blocks_merge = false
verified = true
locations = ["AGENTS.md", "living.toml"]
violates = ["verification_required = true"]
source = "own audit, while merging PR2 under branch protection"
summary = """
`main` branch protection no longer requires `Verification (all gates)`. Every other
rule is intact — `enforce_admins: true`, force-push disabled, deletions disabled,
conversation resolution on — but the required-check rule is absent, so **any PR can
merge to main without the aggregated gate passing**.

This is deliberate and temporary, not a regression to be dismissed. PR2 predates the
contract: its workflow has nine jobs and no aggregator, so it can never report a
check named `Verification (all gates)`, and with `enforce_admins: true` there is no
bypass. The rule was therefore dropped for the duration of the PR2 merge and is to be
restored immediately afterwards.
"""
why_the_order_is_what_it_is = """
The requirement can only be restored once `main` runs the *contract* workflow, because
that workflow is what emits the check's name. On the pre-merge `main` the name
referred to nothing any CI run would ever produce, so re-enabling it before the merge
would block every subsequent PR. Restoring it after 0.4.0 lands is the first moment the
requirement is meaningful.
"""
what_could_not_be_done_here = """
The automation token can `DELETE` the protection rule but every create/update path
returns 404 — `PATCH .../protection`, `PUT`/`POST .../required_status_checks`, and
`POST .../protection` were each attempted. `GET` succeeds and reports
`permissions.admin: true`, which is the signature of a fine-grained token whose
repository metadata says admin while the token itself lacks **Administration: write**.
This finding therefore requires either the web UI or a token with that permission.
"""
required_fix = """
Settings -> Branches -> main -> Require status checks: add
`Verification (all gates)`, with "Require branches to be up to date" enabled.

Or, with a token holding Administration: write:

    gh api -X POST repos/Metis-Avionics/theSix/branches/main/protection/required_status_checks \\
      --input '{"strict":true,"checks":[{"context":"Verification (all gates)"}]}'

The original binding was `strict: true` with `app_id: 15368` (GitHub Actions). Omitting
`app_id` and restoring via `checks[].context` is preferred over guessing at a payload
that could not be tested against a working writer.
"""
residual_risk = """
Until it is restored, nothing mechanically prevents a merge that skips the aggregated
gate. `merge_readiness` inside that gate is the check that would have caught an open
blocking finding, so the protection is the last line rather than the first — but it is
the one that cannot be argued with. This finding being non-blocking means **no gate
enforces that it be closed**; it relies on this record being read.
"""

[[bug]]
id = "B22"
title = "set() descended the ladder on a lost commit race, and could surface a control-plane error from a public API"
severity = "blocking"
status = "resolved"
blocks_merge = true
verified = true
locations = [
  "src/manager.rs:1038",
  "src/manager.rs:218",
  "tests/soak/main.rs:257",
]
violates = ["cia.availability.unbounded_retry"]
source = "own audit after CI reddened on main at f64b4ea; reproduced locally at 2/25 soak runs"
relates_to = "B19"
summary = """
Found because `main` went red on its first CI run after the 0.4.0 merge:
`Performance + soak` failed with `write: StaleGeneration` in
`concurrent_traffic_never_wedges_a_key`. The main tree was byte-identical to
PR3's green head, so it was an intermittent defect rather than a merge
regression, and it reproduced locally at 2/25.

Two faults, both in `set`:

* **D1** -- a lost commit race exhausted the per-rung retry budget and then
  fell out of the inner loop to `last_error = StaleGeneration;
  rung = previous_rung(rung)`, *descending* on the loss. This is backwards:
  the race was won by a newer write, so descending put a losing, older value
  into a colder rung.
* **D2** -- the descent consumed the budget, so `MAX_COMMIT_ATTEMPTS = 2`
  across six cache rungs allowed twelve attempts before `Err(last_error)`
  handed a control-plane error to the caller. That contradicts AGENTS.md,
  which states `set` "retries a lost commit race" and "returns an error only
  when every rung below refuses".
"""
fix = """
D1: the inner loop now retries the *same* rung on a lost race and yields
between attempts; the descent after exhaustion is gone, because every exit from
the loop is a `return` or a `continue 'outer` and nothing falls through.

D2: the budget is now per-rung and race-only (`MAX_COMMIT_ATTEMPTS = 64`), and
exhaustion returns a new `CacheError::WriteContended` rather than
`StaleGeneration`. `WriteContended` is deliberately not rung-level, so it never
triggers descent, and its `Display` ("write contended") carries no key or
payload so it satisfies `cia.confidentiality.payload_in_error_messages`.
`CacheError` is now `#[non_exhaustive]`, which this release was always going to
break anyway (last published version is 0.2.3; neither 0.3.0 nor 0.4.0 has
shipped), so the addition costs nothing extra.
"""
verification = """
`write_contended` is a declared negative case in `theSix.toml` and in
`testkit::coverage::NEGATIVE_CASES`, proven by `tests/negative/main.rs`, so the
new failure mode is not merely implemented but declared and proven.

The proving tests were mutation-checked: with D1 and D2 reverted to their
merged-`main` behaviour the tests fail, and the D1 assertion reports
`L0 was written Tally { writes: 1 } (result Ok(()))` -- which is the bug stated
exactly, because the old code did not error at all, it succeeded by writing to
a colder rung.

Two tests, deliberately both required. A test that forces only a *single* lost
race passes against the broken code, because even the old two-attempt budget
absorbs one loss; that version of this test was written, observed passing
against the bug, and discarded as vacuous. `ThiefTier` in testkit wins every
race deterministically so the budget is genuinely exhausted. The soak layer is
the endurance witness and went from 2/25 failing to 0/25.
"""
rationale = """
Fixed rather than waived. This was a live data-path defect on merged `main`
that silently wrote stale values into colder tiers under concurrency, and it
red the only signal (`Performance + soak`) that would have caught it -- at a
moment when `main` had no required status check to act on it (B21).
"""

[[review]]
id = "R1"
subject = "External code review of PRs #4-#8, reviewed against the diffs and the contract"
reviewer = "independent reviewer, after the 0.4.0 backlog pass merged at 0d40e41"
dispositions = """
#4 APPROVE   lost commit race + B19
#5 APPROVE   eviction + move recovery
#6 APPROVE   four invariant closures
#7 APPROVE WITH COMMENT   `proves!` proof binding
#8 APPROVE   documentation reconciliation
"""

note_on_numbering = """
There is no PR #9. The numbering gap is a merge-order fact rather than a missing
pull request: B16 landed in #6, B20 in #7, and the compliance reconciliation in #8,
so the work the reviewer expected to see as a ninth PR was distributed across the
three that closed review comments.
"""

sequence_reading = """
The reviewer's observation, recorded because it is the most useful characterisation
of the 0.4.0 series found so far: these were not six unrelated patches but a
progressive tightening of one system --

    runtime correctness -> recovery semantics -> eviction authority
      -> invariant observability -> proof attribution -> documentation truth

with the tests becoming instrumentation around architectural claims rather than
coverage beside an implementation.
"""

comments_accepted = """
PR #4 -- `WriteContented` is a second error path, so "an error only when every rung
below refuses" is no longer literally true. Accepted and closed as
`cia.availability.write_race_exhaustion_reports_contended`, proven by the test that
already asserted no descent occurred. Without the clause the documentation could
drift back and someone could "fix" the retry by descending again.

PR #5 -- the contract says eviction exists while the policy remains tier-defined, and
that should stay explicit. Accepted as `capabilities.eviction_policy_is_tier_defined`,
proven by a test contrasting a delegating rung against a wrapper inheriting the
default on one populated store. `blocking_runtime_thread` and the three
`engineering.design.*` claims went the other way and were re-scoped rather than
promised, because no proof existed.

PR #6 -- `refresh()` is intentionally lossy and the `Recovering` test proves reporting
rather than operational unavailability. Accepted: both are now stated where a reader
meets them, since a later reader could otherwise infer that `Recovering` tiers are
safe to serve.

PR #7 -- the source parser is acceptable because it fails closed, and should not grow
into a Rust parser. Accepted and recorded in B20: the span heuristics bias to false
negatives, and the route to stronger proof is fault-ledger coupling.

PR #8 -- B21 means the documentation correctly describes an unenforced protection
state. Accepted; it was already the position, and `merge_ready = false` in `[meta]`
now says so in the tracker rather than only in prose.
"""

agreed_with = """
B21 named the release blocker. The reviewer's framing of it is the sharper one: CI
passing and CI being enforced are different claims, and only the first was true. That
is also the mechanism by which the unreviewed `SECURITY.md` reached `main` during
this pass -- a commit pushed straight to a feature branch and merged unchecked. The
review is right that a green gate run is evidence the contract is internally
consistent and fully bound, which is a weaker and different claim from correctness.
"""

[[bug]]
id = "B23"
title = "The proof obligation was enforced in test code and declared nowhere, leaving 45 clauses unbindable"
severity = "should-fix"
status = "resolved"
blocks_merge = false
verified = true
locations = [
  "theSix.toml:verification.every_invariant_has_a_proof_or_waiver",
  "tests/contract/invariant.rs:SEMANTIC_SECTIONS",
  "testkit/src/coverage.rs:INVARIANT_PROOFS",
]
violates = []
source = "found while scoping the PR #4-#8 review comments, from the principle that a proof obligation is itself an invariant"
relates_to = "B9, B13, B20"
summary = """
Every leaf under the seven semantic sections was bound to a proving test or a stated
waiver. Nothing enforced that for the rest of the contract: `SEMANTIC_SECTIONS` named
only those seven, so `[verification]`'s 29 leaves and `[engineering]`'s 16 were
normative claims no gate could reach. 45 clauses governed nothing.
"""
mechanism = """
The obligation lived entirely in `tests/contract/invariant.rs`, which the contract
cannot see. That is the shape B8 describes -- a check in a place the declaring
artefact does not read -- and it had the same consequence B13 recorded for
`verification.merge_readiness.tracker`: a declared setting nobody was reading.

Nothing detected it because the rules were all internally consistent. The registry
equalled the declared set; the declared set was computed from seven sections; and
"which sections are guarantees" was a constant in a test file rather than a decision
recorded anywhere.
"""
fix = """
Three parts.

The obligation is now declared: `verification.every_invariant_has_a_proof_or_waiver`,
proven by `every_declared_invariant_has_a_proof_or_a_waiver` -- the proof is the audit
enforcing the obligation. That needed one exemption, named rather than pattern-matched:
a proof may not cite `tests/contract/invariant.rs` (a real invariant needs a test that
exercises the runtime), and this clause has no runtime to exercise. Renaming it to end
in `.required` would have satisfied the pattern while concealing the exception.

`SEMANTIC_SECTIONS` now names nine sections, so `[verification]` and `[engineering]`
are walked and their leaves must be bound. The declaration went from 95 leaves to 140.

The 45 were discharged rather than waived. 31 bound to tests that already existed --
including all three eviction clauses, which the review's PR #5 comment had noted were
policy-light while carrying no proof obligation at all. 14 needed new tests.
"""
new_work = """
`the_crates_own_source_carries_no_unsafe_and_no_blocking_calls` covers four clauses at
once (`rust_memory_safety_required`, `unsafe_requires_justification`, `hidden_blocking`,
`runtime_block_on`) and is the pattern B16's `nested_block_on` scan already used.
Mutation-checked: a `std::thread::sleep` added to `src/manager.rs` fails it, naming the
clause and the line.

`every_adversarial_layer_is_enabled_and_bound_to_a_target` exists because the ten
`verification.adversarial.*` flags were read by nothing -- the pre-existing layer check
hardcoded its own list of layer names. Reading them found a real divergence: `fuzz` is
adversarial but bound to no test target, because its targets live in the excluded
`fuzz/` workspace. It is covered by the `fuzz` gate instead, so the test accepts
target-or-gate and asserts both paths are live.

`tier_topology_is_replaceable` is proven by substitutivity rather than inspection: the
same operations against two sets of tier implementations must agree on hits, on
misses, and on removal. Comparing only the happy path would let a topology assumption
hide in the error path, which is where B17 and B22 both lived.

`eviction_policy_is_tier_defined` is proven against one populated store. The weaker
version -- assert `None` somewhere -- passes for the wrong reason, since `None` is also
what a delegating rung returns when it holds nothing.
"""
re_scoped_rather_than_proven = """
`engineering.design.requirements_drive_ontology`, `ontology_drives_pipeline` and
`implementation_follows_contract` moved to a top-level `[design]` table, outside the
proof-bound set. There is no mechanical form for "requirements drove the ontology"; a
test would assert the manifesto's own wording and pass vacuously, which is B20's
failure mode with extra steps. Leaving them as waived booleans would have admitted
they are guarantees nobody checks, so the section is named and its exclusion stated.
"""
verification = """
Set equality is enforced in both directions, so an added or renamed clause fails until
the registry moves with it. 140 leaves, 139 proofs, 1 waiver
(`concurrency.blocking_runtime_thread`, whose waiver now explains that the missing
thing is a mechanism rather than a test).

Every new test carries `testkit::proves!` and the registry requires the cited
function's own declaration to contain the cited clause, so a mis-citation fails. The
mechanism that would have caught a rename during this work did: seven tests already
declared a clause for another registry row, and the "already declared" guard skipped
adding the second name, so the gate reported them until the declarations were merged.
"""
rationale = """
Fixed, because the principle that a proof obligation is itself an invariant is the
one rule the verification system was silently exempting itself from. It is now the only
part of the contract that cannot be quietly widened: a new clause anywhere in nine
sections is unmergeable until something is responsible for it.
"""