File size: 40,805 Bytes
d452c40
 
18f4386
 
 
d452c40
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
d452c40
 
 
 
 
6df4c6e
d452c40
6df4c6e
 
 
 
d452c40
6df4c6e
 
 
 
 
 
 
 
d452c40
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
 
 
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
 
 
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
 
 
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
 
 
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
6df4c6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d452c40
18f4386
 
d452c40
18f4386
 
d452c40
6df4c6e
 
18f4386
6df4c6e
 
 
18f4386
 
 
6df4c6e
 
 
 
18f4386
6df4c6e
18f4386
 
 
 
 
 
6df4c6e
 
 
 
 
 
 
 
 
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
# Limitations

An honest, exhaustive catalogue of everything SatQuery AI does **not** do, does poorly, or does not
know. Negative results and open items are listed here rather than omitted, because a limitation that
is not written down is a limitation that will be discovered by someone else at the worst moment.

**Status tags:** `OPEN` · `NOT RUN` · `REJECTED` · `DEFERRED` · `BY DESIGN` · `MEASURED`.

**How to read this document.** Limitations are numbered `L-01 …` and grouped by area. Each entry
states the limitation, the measured or observed detail behind it, and the file that records it. Where
a value is a status, it is stated exactly as the project's own records state it — a `REJECTED` is never
softened to "usable", an `OPEN` ruling is never presented as settled, and a validation number is never
promoted to a test result.

**Companion documents.** [`BENCHMARKS.md`](BENCHMARKS.md) and [`EVALUATION.md`](EVALUATION.md) hold
the metric honesty rules; [`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) holds the findings behind several
entries here; [`DEPLOYMENT.md`](DEPLOYMENT.md) §8/§13 holds the operational blockers B-07 and B-02;
[`architecture/04-router.md`](architecture/04-router.md) documents the router residuals.

---

## 1. Model quality

### L-01 — Grounding IoU is low in absolute terms (`MEASURED`)

The grounding head's mean best IoU is **0.2838** (canonical protocol) and **0.2566** (matched6
protocol) on VRSBench eval, n = 16,159. The trained head clearly beats the zero-shot baseline
(**0.0972**), but 0.28 is not "solved". Recall@0.5 is only **0.2198** (canonical) / **0.1938**
(matched6).

**Evidence:** `artifacts/grounding/remoteclip_grounding_v001/eval_result_canonical.json`,
`eval_result_matched6.json`; `docs/PHASE7_RESOLUTION_DECISION.md`; `docs/FINAL_DELIVERY_TODO.md` §1.6.

### L-02 — Grounding is protocol-sensitive; an absolute value is meaningless without its protocol (`MEASURED`)

The same head reports very different numbers under different decode variants:

| Variant | Protocol | mean best IoU | recall@0.5 |
|---|---|---|---|
| `head_threshold` | canonical | 0.2838 | 0.2198 |
| `head_threshold` | matched6 | 0.2566 | 0.1938 |
| `head_argmax` | canonical | 0.1215 | 0.0795 |
| `zero_shot_matched` | canonical | 0.0972 | 0.0234 |

So a single grounding number quoted alone is misleading: the head/threshold versus head/argmax split
changes IoU by more than a factor of two. **Never quote one without the other.**

**Evidence:** `artifacts/grounding/remoteclip_grounding_v001/eval_result_canonical.json` and
`eval_result_matched6.json`; `release/DOCS_STYLE_GUIDE.md` §3.

### L-03 — The grounding head did not beat the zero-shot baseline on the validation curve (`MEASURED`)

The Benchmark page carries this as an honest label: the grounding head did not beat the baseline on
validation (`docs/FINAL_DELIVERY_TODO.md` §4 P6-T01). The head's advantage over zero-shot is a
**test-split** result (0.2838 vs 0.0972), not a validation result.

**Evidence:** `docs/FINAL_DELIVERY_TODO.md` §4 P6-T01; `docs/PHASE7_RESOLUTION_DECISION.md` ("the
Phase 8 head must beat 0.0972 to justify itself").

### L-04 — Optical-SAR accuracy is carried by common classes; macro-F1 is low (`MEASURED`, ruling `OPEN`)

The fusion head scores accuracy **0.931** but macro-F1 **0.434161** on a held-out test split of
n = 4,000 over 19 classes. **5 of the 19 classes are absent in the scored split** (`classes_absent:
[1, 11, 14, 15, 16]`) and contribute **0.0** to macro-F1 by construction
(`macro_f1_denominator: "all 19 classes (absent classes contribute 0.0)"`). The wide accuracy–macro-F1
gap is the signature of class imbalance. **Never quote accuracy without macro-F1.**

**Evidence:** `artifacts/optical_sar/fusion_head_production_v001/pre_registered_115_metric.json`;
`docs/FINAL_DELIVERY_TODO.md` §1.6.

### L-05 — The optical-SAR ruling is `OPEN` (`OPEN`)

`pre_registered_115_metric.json` states plainly: *"This tool reports ONE head's held-out accuracy and
macro-F1. It selects no head, ranks nothing and compares no arms. Whether this constitutes a Phase 12
pass is the owner's ruling."* Phase 12 is **INCOMPLETE**; the pre-registered metric's gate criterion is
owner-gated (`docs/PHASE12_CURRENCY_CORRECTION.md` §0, §3; `docs/STEP7_BACKEND_CHAIN_REPORT.md` §17).

**Evidence:** `artifacts/optical_sar/fusion_head_production_v001/pre_registered_115_metric.json`
(`is_deciding_statistic: false`); `docs/PHASE12_CURRENCY_CORRECTION.md`.

### L-06 — Change-VQA is weak on rare classes, on two test sets (`MEASURED`, ruling `OPEN`)

Change-VQA scores **accuracy 0.697626 / macro-F1 0.378373** on `Test` (n = 39,686) and
**0.651469 / 0.372309** on `Test2` (n = 31,036). The wide accuracy–macroF1 gap is the signature of
class imbalance. The ruling is **`OPEN`** (`docs/PHASE19_FINAL_HARDENING.md` §4.5: "the R-02
macro-F1/accuracy gap is unruled … not this work order's to rule"). Top-3 accuracy is 0.964698. The
head's metadata records `confidence_method: "uncalibrated"` and `test_splits_used: false` on the
training record itself.

**Evidence:** `artifacts/change_vqa/run/PROMOTION.json` (`test_accuracy`, `test_macro_f1`,
`test2_accuracy`); `artifacts/change_vqa/run/model_metadata.json`; `docs/PHASE19_FINAL_HARDENING.md`
§4.5.

### L-07 — VQA is weak-but-related (`MEASURED`)

The live VQA path answers broadly related content rather than a crisp class. Measured live: the case
A1 query answered **"Grassland"** for a scene where a more specific answer was expected
(`LIVE_VALIDATION_POSTFIX.md`, "Model-quality note"; `release/CURRENT_RELEASE_STATE.md` §6). This is a
model-quality limitation, not a deployment fault — the pipeline dispatches and returns a real answer.

**Evidence:** `.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md`.

### L-08 — Optical-SAR returns a bare class index, not a human label (`MEASURED`)

The live service returns `class_18` rather than a human-readable CLC label. The live answer reads
`[optical_sar] Fused optical-SAR prediction: class_18 (margin 1.000; optical channels 4/12, SAR
channels 2/2)` — the modality accounting confirms the right channels reached the fusion head, but the
answer is not interpretable without a label map.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6;
`.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md`.

### L-09 — Calibration made ECE worse (`MEASURED`)

Temperature scaling moved ECE from **0.013755 → 0.014929** (`ece_improvement: −0.001174` — **worse**)
while improving NLL marginally (0.689741 → 0.689631). It is **retained only because it is part of the
frozen config** — **not** because it helped. The fitted temperature is `0.9772731820958189`, fitted on
the Val split with n = 16,441, `effective: true`, `hit_bound: false`. The path is live
(`core/controller.py` calls `load_calibration(config)` and hands the artifact to `EvidenceEngine`), so
a deployed result carries a calibrated value — but the calibration is **not an improvement** and must
never be described as making confidence "more accurate".

**Evidence:** `artifacts/calibration_v001.json` (`metrics.ece_before`, `metrics.ece_after`,
`fit_diagnostics.temperature`); `docs/STEP7_BACKEND_CHAIN_REPORT.md` §7;
`docs/PHASE19_FINAL_HARDENING.md` §9 (calibration-success correction).

### L-10 — The VLM adapter is `ACCEPTANCE-REJECTED` (`REJECTED`)

The Phase-6 LoRA adapter's metrics are **usable** — test exact-match **0.963**, F1 **0.96432**,
aggregate test delta **+49.5 pp** — and the artifact is `USABLE_VERIFIED`. But its acceptance status is
**`REJECTED`**: v001 rejected it on val, and the independent-test rule v002 rejected it on the test
split (one class, `Mixed forest`, lost 4 questions at z = 2.1335). The closure record keeps the two
questions separate: *"'Verified' answers: is this artifact the one we trained, and does it work?
'Accepted' answers: did it clear the bar predeclared before we looked?"* The deployed caption/VQA path
uses the **unadapted** model by default; the adapter is attached only when `SATQUERY_VLM_ADAPTER` is
set. **USABLE ≠ ACCEPTED.**

**Evidence:** `artifacts/vlm/phase6_closure.json` (`production_adapter.acceptance_status`,
`why_acceptance_rejected`, `what_closure_does_not_claim`);
`docs/PHASE6_RUN1_REJECTION_DIAGNOSIS.md`.

### L-11 — The VLM acceptance-rule history is a post-hoc rule change (`MEASURED`, disclosed)

v001 was pre-registered (`declared_before_training: true`) and rejected the run on a per-class guardrail
whose 1.0 pp threshold sits **below the measurement resolution** of the data (0.20 questions at n = 20;
per-class SE 2.6–10.6 pp). v002 was declared **after** run 1 (`declared_before_training: false`) and is
documented as a **relaxation** of V2, justified measurement-theoretically, not by the outcome. The
record keeps v001 and its `REJECTED` verdict verbatim and states that v002 "is not a numerically
stricter bar" than the contract's ~3 SE figure. A reader must treat the acceptance verdict as resting
on 4 questions in one class of 33 — the "unfloored minimum-size exposure" the closure reports but does
not resolve.

**Evidence:** `docs/PHASE6_RUN1_REJECTION_DIAGNOSIS.md` §4, §7.1, §7.4;
`artifacts/vlm/phase6_closure.json` (`thresholds_used.amendment`, `residual_risk`).

### L-12 — The router number is a validation result, ungated, n = 86 (`MEASURED`, `TEST NOT RUN`)

Router task accuracy is **0.965116** — measured on **validation**, **ungated**, **n = 86**,
**corpus-limited** (`corpus_total: 576`, `corpus_groups: 54`; `corpus_limited: true`). The **test
split was NOT RUN**. The number is indicative only and must never be quoted as a test result.

**Evidence:** `artifacts/router/router_adapter_v001/metadata.json` (`val_task_accuracy`);
`artifacts/router/threshold_sweep_val.json`; `docs/FINAL_DELIVERY_TODO.md` §1.6.

### L-13 — The router's routing is not perfect (known residuals) (`MEASURED`)

See §2. The router is a lexical/embedding classifier over a small corpus; residual misroutes exist and
are documented rather than hidden.

---

## 2. Router residuals (known misroutes)

### L-14 — *"What is the new runway?"* reads `change`, not `vqa` (`OPEN`)

The `new`-as-change heuristic fires on non-`where` questions. This is "strictly better than pre-fix,
where `new` was unconditionally temporal. A lexical router cannot cleanly separate 'the new X' from
'what's new'."

**Evidence:** `.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md` ("Known residuals");
`release/CURRENT_RELEASE_STATE.md` §6.

### L-15 — *"How much built-up area was added?"* reads `vqa` (under-trigger) (`OPEN`)

`built` was dropped from the temporal set during the B-08 fix and `area` no longer matches inside
`areas`, so a change-style quantifier is not caught and the query under-triggers to `vqa`.

**Evidence:** `.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md` ("Known residuals");
`docs/FINAL_DELIVERY_TODO.md` §5 B-08.

### L-16 — The `interpret()` / `chooseTask()` asymmetry is visually surprising (`RESOLVED`, intentional)

For *"What changed between the earlier and later image?"* with **one** asset attached, the console
**reads** `change` while dispatch correctly falls back to **`change_vqa`**. This is **intentional** —
the reading is asset-count-blind (it describes the question's intent), while dispatch is
asset-count-aware (it respects what can actually be computed with the assets present) — but a reader
who sees the reading panel and the answer disagree may mistake it for a defect.

**Evidence:** [`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) §7;
`.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md` ("Discriminator note").

---

## 3. Evaluation gaps

### L-17 — No system-level end-to-end benchmark exists (`NOT RUN`)

**No end-to-end accuracy is claimed anywhere.** `STATUS.md` states there is no system-level E2E
benchmark, and the Benchmark page is required to label it `NOT RUN`.

**Evidence:** `docs/FINAL_DELIVERY_TODO.md` §1.7 item 7, §5 B-04; `docs/FINAL_DELIVERY_REPORT.md` §6.

### L-18 — The router test split was not run (`NOT RUN`)

See L-12. The test split exists but was never scored.

**Evidence:** `docs/FINAL_DELIVERY_TODO.md` §1.6; `docs/FINAL_DELIVERY_REPORT.md` §6.

### L-19 — The benchmark adapters were not run (`NOT RUN`)

No benchmark adapter is registered; the registry is empty by construction
(`docs/PHASE19_FINAL_HARDENING.md` §9, "Benchmark pass — Not claimed").

**Evidence:** `docs/PHASE19_FINAL_HARDENING.md` §9; `docs/FINAL_DELIVERY_REPORT.md` §6.

### L-20 — No end-to-end latency benchmark (`NOT RUN`)

Per-specialist latency is recorded only incidentally (e.g. grounding encoder latency 2.205 ms/image at
224 in the canonical eval, 20.0 ms/image on a T4 per `docs/PHASE7_RESOLUTION_DECISION.md`). There is no
benchmark of the deployed request path across the four tiers.

**Evidence:** `artifacts/grounding/remoteclip_grounding_v001/eval_result_canonical.json`;
`docs/PHASE7_RESOLUTION_DECISION.md`; [`PERFORMANCE.md`](PERFORMANCE.md).

### L-21 — No cross-dataset generalisation (`NOT RUN`)

Each specialist is evaluated only on its own training-family test split (LEVIR-CD for change,
VRSBench for grounding, a BigEarthNet-family split for fusion, CDVQA for change-VQA). Nothing measures
transfer to a different distribution.

**Evidence:** `docs/PHASE7_RESOLUTION_DECISION.md` ("Anything about hidden ISRO/SAC imagery … a
different distribution entirely"); the per-task evaluation sections of [`EVALUATION.md`](EVALUATION.md).

### L-22 — No human evaluation (`NOT RUN`)

No human study of answer quality, usefulness, or failure modes was performed.

**Evidence:** `docs/FINAL_DELIVERY_REPORT.md` §6 (unverified items); this document is the only
catalogue.

### L-23 — No robustness or adversarial evaluation (`NOT RUN`)

No evaluation of behaviour under adversarial, corrupted, or out-of-distribution inputs. The
change specialist carries invalid-data and registration-quality logic
(`docs/ARCHITECTURE_FREEZE.md` §23 false-change handling), but no robustness *evaluation* exists.

**Evidence:** `docs/FINAL_DELIVERY_REPORT.md` §6.

### L-24 — BigEarthNet label semantics make the local metrics non-comparable (`MEASURED`)

The local BigEarthNet subset is **100 % single-label** against the official **1–11 multi-label**
scheme, so metrics computed on it are **not comparable** to published multi-label numbers.

**Evidence:** [`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) §9; `docs/PHASE12_LABEL_POLICY_DECISION.md`.

### L-25 — The reliability diagram shipped is the pre-scaling curve (`MEASURED`)

The shipped reliability curve is the **pre-scaling** curve (labelled as such); the calibrated curve is
not plotted. The caption now reads "Measured" and the bins are transcribed from
`artifacts/calibration_v001.json`, but the remaining section-03 PR curves are still labelled
illustrative.

**Evidence:** `docs/FINAL_DELIVERY_TODO.md` §4 P6-T01 note; `artifacts/calibration_v001.json`.

### L-26 — Statistical significance exists for only one decision (`MEASURED`)

Only the grounding resolution decision (448 vs 224) has a paired test with a confidence interval
(§[`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) §3). Every other per-task number is a point estimate with no
significance test.

**Evidence:** `docs/PHASE7_RESOLUTION_DECISION.md` ("Paired analysis — independent confirmation").

### L-27 — The optical-SAR registry state is `degraded`, and the adapter never advertises `loaded` (`MEASURED`)

The registry resolves `optical_sar` to **`degraded`**, not `available`
(`docs/STEP7_BACKEND_CHAIN_REPORT.md` §17). More generally, the capability adapter derives contract
state from **artifact presence** and therefore **never emits `loaded` or `evicted`** — "a model is
resident" is unknowable without loading one, which the metadata path must not do
(`docs/DEPLOYMENT_ARCHITECTURE.md` §3.3.1). A consumer cannot learn from `/v1/capabilities` whether a
model is actually resident.

**Evidence:** `docs/STEP7_BACKEND_CHAIN_REPORT.md` §17; `docs/DEPLOYMENT_ARCHITECTURE.md` §3.3.1.

### L-28 — The trace's registry block is a snapshot of the *previous* request (`MEASURED`)

`SpecialistRegistry.describe()` is assigned into the trace **immediately after planning** and **before
execution**, so on a cold process the client-visible `built` map is necessarily `{}` — including for
the request that is about to build the specialist. The same query returns two different traces
depending on how many requests the process has already served. The same trace is also internally
inconsistent about which clock it uses (`selected_models` is assigned inside execution, so it *does*
reflect the current request while `built` does not). **Severity: low — observability only.**

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.8 (finding F-19).

### L-29 — The uploaded-asset path surface has historically leaked server-side paths (`RESOLVED`, recorded)

A series of findings (F-13 … F-16) recorded that `trace.inputs`, `trace.steps[PARSE].detail`, and
`evidence[].artifact_ref` / `result.change_map` published server-side filesystem paths to an
unauthenticated client. All were fixed (paths reduced to basenames; refs set to `null` with an explicit
non-retrievable warning; no fabricated `artifact://` URIs). Two consequences remain worth recording:
the contract's §2.4 example once showed a fabricated `artifact://` URI the service cannot emit (now
corrected), and the ruling introduced a **signalling** change (F-16c): on a deployment that configures
`change.artifact_dir`, a no-change run now reports `degraded: true` where it previously reported
`degraded: false`.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.3–§5.6; [`SECURITY.md`](SECURITY.md).

---

## 4. Operational limitations

### L-30 — B-07: transient tunnel gaps (`OPEN`)

A request can hang or return `504` when the tunnel agent is briefly absent. The patch is prepared,
**NOT deployed**.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §8.1; `docs/FINAL_DELIVERY_TODO.md` §5 B-07;
`release/CURRENT_RELEASE_STATE.md` §6.

### L-31 — B-07 root shape: the `auto`-mode fallthrough wastes the wake budget (`MEASURED`)

In `auto` transport mode a tunnel timeout **falls through** to the forward path, which then burns
`wake_timeout_s` (120 s) on a `302` → a worst case of ≈ **249 s** (150 + 120). Measured.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6; [`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) §6;
[`DEPLOYMENT.md`](DEPLOYMENT.md) §8.1.

### L-32 — Cold start is tens of seconds (`MEASURED`)

Render's free tier sleeps when idle, and the Codespace may be stopped (idle timeout 30 min). The first
request after idle waits for a wake. Documented, not hidden.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §8; `docs/DEPLOYMENT_TOPOLOGY.md` §2.

### L-33 — B-02: `codespace_name` trailing newline (`OPEN`, cosmetic)

The `/api/health` payload reports the raw `codespace_name` with a trailing `\n`. Cosmetic; the wake
path strips it.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §8.2; `docs/FINAL_DELIVERY_TODO.md` §4 P2-T03.

### L-34 — No database, auth, or queue (`BY DESIGN`)

The gateway is stateless by design. There is no persistence of runs or users, no auth layer, and no
request queue (plan §73/§74; `docs/DEPLOYMENT_ARCHITECTURE.md` §6).

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §2.2, §6.

### L-35 — The deployment repositories are private (`BY DESIGN`)

The three deploy repositories return `404` for an outside audience.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §11.4; `docs/FINAL_DELIVERY_TODO.md` §4 P9-T01.

### L-36 — `deploy/` in the monorepo is stale and untracked (`OPEN` trap)

Edits there do not deploy; it is not the deployed source.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §1.1; `docs/FINAL_DELIVERY_TODO.md` §1.1.

### L-37 — The rate limiter is a fairness control, not a protection control (`BY DESIGN`)

The per-IP limiter keys on the first hop of the client-supplied `X-Forwarded-For`; a caller that varies
the header is never throttled (measured 0/8 throttled with a fresh value per request, versus 5/8
without). It is explicitly **not** a security boundary.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.2; `docs/BACKEND_DEPLOYMENT_RUNBOOK.md` §4.1.2.

### L-38 — No APM, distributed tracing, or cost accounting (`BY DESIGN`)

Observability is limited to the health payload and per-run traces. There is no APM, no distributed
tracing across the four tiers, and no cost accounting.

**Evidence:** [`architecture/10-observability-and-ops.md`](architecture/10-observability-and-ops.md);
[`OPERATIONS.md`](OPERATIONS.md).

### L-39 — Single-region, no HA (`BY DESIGN`)

One Render service, one Codespace. No redundancy, no failover, no multi-region deployment.

**Evidence:** [`DEPLOYMENT.md`](DEPLOYMENT.md) §13.

### L-40 — A saturated asset store is indistinguishable from a misconfigured one (`OPEN`)

`POST /v1/assets` answers `503` both when the store is unconfigured and when it is full; the response
cannot tell them apart, and the counter that would have separated them was **removed** rather than given
a consumer. Treat the `503` on this route as ambiguous.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.1 (finding F-11).

### L-41 — `change_vqa.artifact_dir` is a configured-but-inert key (`OPEN`, low severity)

`change_vqa.artifact_dir` is advertised in the same `optional_config_keys` table as the two keys that
work, but `specialists/change/vqa_specialist.py` **never reads it** (the attribute occurs exactly once,
as an assignment; the module contains no file-writing code). An operator who sets it receives no
artifacts and **no warning**.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.6 (finding F-17).

### L-42 — The Anatomy page's plate image variant is cosmetic-wrong (`OPEN`, cosmetic)

The Anatomy plate points at the **720×720** variant of an image the recorded run analysed at
**730×730**. The content is identical and the canvas scales it, but the page's "the ACTUAL analysed
image" wording is very slightly loose.

**Evidence:** `.workbuddy-ai/scratch/live_validation/LIVE_VALIDATION_POSTFIX.md` ("Known residuals");
`release/CURRENT_RELEASE_STATE.md` §6.

### L-43 — The `/api/capabilities` deployment block carried stale metadata (`RESOLVED`)

The capabilities `deployment` block once claimed `huggingface-spaces`/`zerogpu`. It was recorded as a
stale-metadata item (`docs/FINAL_DELIVERY_TODO.md` §1.7 item 6) and is reconciled in the shipped
contract; the frozen `configs/deploy.yaml` still describes the superseded target (§5 below).

**Evidence:** `docs/FINAL_DELIVERY_TODO.md` §1.7 item 6; [`DEPLOYMENT.md`](DEPLOYMENT.md) §11.

---

## 5. Packaging and licensing

### L-44 — There is no `LICENSE` file (`OPEN`)

**No `LICENSE` file exists** in the source repository. The README says "add a license file before
public release". A licence must be selected before public release of the code. This is a **release
blocker for the code**, not a model defect.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6 ("**No `LICENSE` file exists** in the monorepo;
README says 'add a license file before public release'"); `release/DOCS_STYLE_GUIDE.md` §3.

### L-45 — Backbones are not redistributed (`BY DESIGN`)

The six trained artifacts are small modules; the backbones (SmolVLM, RemoteCLIP, MiniLM, CROMA,
STANet-style encoder) are fetched from their sources at run time, and their licences are their own.
Nothing here re-licenses a backbone.

**Evidence:** [`MODELS.md`](MODELS.md); `app/serving.py` (`resolve_checkpoint_path`, "offline first");
`docs/ARCHITECTURE_FREEZE.md` §2.

### L-46 — The released weights require their backbones (`MEASURED`)

A consumer of the six artifacts must also fetch the pinned backbones at the exact revisions; an
artifact alone is not runnable. The VLM adapter, for example, requires
`HuggingFaceTB/SmolVLM-500M-Instruct` (revision `a7da5b986cb5`) plus the tokenizer/processor files
listed in `phase6_closure.json`.

**Evidence:** `artifacts/vlm/phase6_closure.json` (`production_adapter.files_required_to_serve_standalone`);
`release/CURRENT_RELEASE_STATE.md` §3.

### L-47 — Artifact-tree bloat (`MEASURED`)

`artifacts/` totals roughly **3.7 GB**, almost all of it caches, duplicates and features rather than
released weights:

| Path | Size | Classification |
|---|---|---|
| `artifacts/grounding/remoteclip_grounding_v001/` | 1.4 GB | ARCHIVED (evidence) |
| `artifacts/grounding/remoteclip_grounding_v001.zip` | 774 MB | **DUPLICATE** of the directory above |
| `artifacts/optical_sar/fusion_head_v001/` | 276 MB | superseded by `fusion_head_production_v001` |
| `artifacts/optical_sar/fusion_features/` | 231 MB | reproducible cache |
| `artifacts/optical_sar/fusion_features_armB/` | 231 MB | reproducible cache |
| `artifacts/change/levir_change_cpu_probe_v001/` | 241 MB | **DUPLICATE** probe of `levir_change_v001` |
| `artifacts/change/levir_change_v001/` | 241 MB | ARCHIVED |
| `artifacts/phase12_selection/*.jsonl` | ~235 MB | data-selection manifests (seeds) |

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §3.

### L-48 — The VLM adapter is not committed and lives under `.scratch/` (`MEASURED`)

The adapter is **not** committed (`.gitignore` excludes `artifacts/`, `checkpoints/` and
`*.safetensors`) and its canonical path is under `.scratch/`, which a future cleanup could remove. The
closure record states that moving it to a non-scratch location is "a reasonable follow-up, not a
closure requirement", and that moving it would make the recorded evidence stale.

**Evidence:** `artifacts/vlm/phase6_closure.json` (`production_adapter.reconstruction.why_not_moved`).

### L-49 — The frozen `configs/deploy.yaml` describes a target that does not exist (`OPEN` paperwork)

`configs/deploy.yaml` still declares `platform: huggingface-spaces`, `sdk: gradio`, `zerogpu: true`,
and the `gpu_duration_*` values. It is inert (`registry: false`), never loaded by `core/config.py`, and
cannot be edited without either failing `scripts/validate_deploy_config.py` or moving `Config.hash`. It
is deliberately left undisturbed, but a reader who finds it will reasonably think the project targets a
Gradio ZeroGPU Space.

**Evidence:** `configs/deploy.yaml`; `docs/DEPLOYMENT_DECISION.md` §4; [`DEPLOYMENT.md`](DEPLOYMENT.md) §11.

---

## 6. Documentation caveats

### L-50 — `docs/FINAL_DELIVERY_REPORT.md` §6 is stale (`SUPERSEDED`)

It still lists the bundled EO change pair as **DEGRADED** (726² vs 736² → shape error) and **B-01** as
**BLOCKED**. Both were resolved on 2026-09-25: the EO pair is now same-shape (both 720×720, new `-720`
URLs) → **RESOLVED**; the Hugging Face link is live on all 11 pages → **B-01 CLOSED**.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6 ("Documentation that this sprint supersedes");
`docs/FINAL_DELIVERY_REPORT.md` §6.

### L-51 — The monorepo `README.md` was materially stale (`SUPERSEDED`)

It described a hermetic frontend, an in-progress Render/Codespace, a `/v1/*` contract, omitted the
tunnel, and pointed at the stale `deploy/`. Superseded by this release's README.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6.

### L-52 — The `hf/` docs were stale (`SUPERSEDED`)

`hf/SETUP.md` and `hf/README.md` asserted the project owns no weights and has no HF credentials. Both
were false at release time.

**Evidence:** `release/CURRENT_RELEASE_STATE.md` §6.

### L-53 — Stale-negative documentation is a structural hazard (`MEASURED`)

Three documents written after the Phase-12 A/B experiment still described it as **un-run**, even though
it had completed 34 hours earlier. The lesson recorded: "a stale negative claim is more dangerous than
a stale positive one … 'This has never been executed' is contradicted by *nothing* — no test fails, no
hash moves, no invariant breaks." The existing conformance tests check that documented things *exist*;
**no test can check that a documented absence is still absent**.

**Evidence:** `docs/PHASE12_CURRENCY_CORRECTION.md` §0, §6.

### L-54 — The original master plan describes a superseded deployment (`SUPERSEDED`)

The master plan specifies a Gradio GUI + HF Space + ZeroGPU + Railway, and a single-image workflow set.
The shipped system is a static frontend + Render + Codespace tunnel, serving JSON, with the change-VQA
and optical-SAR capabilities added later. The plan is a design document, not a description of the
shipped system.

**Evidence:** `docs/MASTER_ARCHITECTURE_PLAN.md`; `docs/DEPLOYMENT_DECISION.md` §4;
[`DEPLOYMENT.md`](DEPLOYMENT.md) §11.

### L-55 — `mask_ref` was wrongly listed as a documented path surface (`CORRECTED`)

An audit note listed `Region.mask_ref` as a deliberate documented path surface; that was wrong —
`core/schemas.py` is a bare `str | None = None` with no description, and `grep -r mask_ref docs/` finds
nothing. Recorded so the correction is not lost.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.5 (note on `mask_ref`).

### L-56 — Documentation-validated-by-execution found nine factual errors (`MEASURED`)

Validating every JSON example against the real Pydantic models and every runbook claim against the
repository caught nine factual errors proof-reading had missed — including `CoordinateSystem`
documented as `normalized`/`geographic` when the real values are `normalized_0_1`/`geo`, and `Box`
documented with nested geometry when the real model is flat. The checks are now permanent tests (48
assertions). This is a caveat about how much confidence a *document* can carry: prose is not validated
by these tests.

**Evidence:** `docs/PHASE19_FINAL_HARDENING.md` §3.6; `docs/STEP8_FINAL_CONFORMANCE_AUDIT.md` §13.

---

## 7. Interface, contract, and data-surface limitations

### L-57 — The contract promises forward-compatible reading; the schema forbids it (`OPEN`, contract contradiction)

`docs/API_CONTRACT.md` §1.1 says a consumer **"MUST tolerate unknown fields on read (forward
compatibility)"**, and §1 says additive changes do not bump the version — which only works if unknown
fields are ignorable. But `ResultEnvelope`, `SpecialistResult` and `ExecutionTrace` are all
`extra="forbid"`, so `model_validate` **rejects** a body carrying an unknown key. Both halves are
load-bearing and cannot both hold. The contract's own authority clause makes the **code** authoritative,
so the document's bullet is the inaccurate half — but the document was **not** corrected (a doc edit is
a reviewable change), so a reader of the contract is still told the wrong thing.

**Evidence:** `docs/STEP7_BACKEND_CHAIN_REPORT.md` §15 (finding C-2);
[`architecture/08-api-contract.md`](architecture/08-api-contract.md).

### L-58 — The capability adapter can never report `loaded` or `evicted` (`MEASURED`)

Because the metadata path must not construct a model, `app/deployment.py` derives contract state from
artifact **presence** and reconstructs the registry's word from that state — the inverse direction. One
observable consequence: **`loaded` and `degraded` are never emitted**, since "a model is resident" is
unknowable without loading one, and `evicted` is a runtime model-cache fact no static inspection can
observe. A consumer therefore cannot learn from `/v1/capabilities` whether a model is actually
resident.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §3.3.1;
`docs/STEP8_FINAL_CONFORMANCE_AUDIT.md` §3 (finding C-4).

### L-59 — Two subsystems use overlapping words with different meanings (`MEASURED`)

To the registry, `unavailable` means "no builder could be constructed"; to the contract it means
"present but broken, and **therefore a defect**". Transcribing one into the other without noticing
"would turn a deployment gap into a reported defect, or vice versa". The registry's `available` is not a
contract state at all, and `degraded` is *both* a whole-service status and a capability state — a reader
cannot tell from the word alone which is meant.

**Evidence:** `docs/STEP7_BACKEND_CHAIN_REPORT.md` §10 (findings H-2, M-2).

### L-60 — The capability source of truth was historically two producers (`RESOLVED`, recorded)

Before the owner ruling, `AnalysisController.health()` enumerated **6** capabilities from the registry
while the served `describe_deployment()` enumerated **2** from two `Path.exists()` calls. The registry
is now authoritative and `describe_deployment()` delegates to the single adapter — but the historical
divergence is recorded because "any table that exists in two places will drift, and this one already
had".

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §3.3.1;
`docs/STEP7_BACKEND_CHAIN_REPORT.md` §10, §16 (finding M-1).

### L-61 — `mask_ref` is an undocumented optional field (`OPEN`, low)

`core/schemas.py` declares `mask_ref` as a bare `str | None = None` with no description, and
`grep -r mask_ref docs/` finds nothing. An earlier audit note wrongly listed it as a deliberate
documented path surface; that was corrected. It remains undocumented.

**Evidence:** `docs/DEPLOYMENT_ARCHITECTURE.md` §5.5 (note on `mask_ref`).

### L-62 — VRSBench box coordinates are normalised to 0–100 (`MEASURED`)

VRSBench's repository notes that provided evaluation box coordinates are normalized to **0–100**, so the
evaluator adapter must explicitly convert between that convention and the project's internal **0–1**
representation rather than quietly treating the numbers as pixels. A consumer that reads a grounding box
without the coordinate-system field will misinterpret it.

**Evidence:** `docs/MASTER_ARCHITECTURE_PLAN.md` §13 (grounding head / coordinate convention);
`docs/STEP7_BACKEND_CHAIN_REPORT.md` §4 (`CoordinateSystem` is exactly `{normalized_0_1, pixel, geo}`).

### L-63 — The gateway's rate-limit and size-limit values are implementation choices, not plan facts (`OPEN`)

The plan specifies none of them. The defaults in `GatewayConfig` are choices the implementation made,
and the maintainer is asked to confirm them, because they bound one client's share of the daily budget.
No rate-limit value is specified by the plan.

**Evidence:** `docs/PHASE19_FINAL_HARDENING.md` §4.4; `docs/BACKEND_DEPLOYMENT_RUNBOOK.md` §4.1.

### L-64 — `POST /v1/assets` was not in the original plan (`RESOLVED`, historically undefined)

The plan fixes three endpoints, yet `AnalysisRequest.assets` is a list of *handles*, which requires a
fourth. `docs/API_CONTRACT.md` §2.5 records the gap; the endpoint is now implemented, but the
fourth-endpoint decision was historically open and the gateway once answered `501` for it.

**Evidence:** `docs/PHASE19_FINAL_HARDENING.md` §4.2;
`docs/STEP7_BACKEND_CHAIN_REPORT.md` §16.

---

## 8. Dataset and corpus limitations

### L-65 — The change model is evaluated only on LEVIR-CD-256 (`MEASURED`)

The change head's headline (pooled IoU 0.8122 / macro IoU 0.8457 / pooled F1 0.8964, n = 2048,
threshold 0.5) is measured on **LEVIR-CD-256** test. Nothing measures transfer to another change
dataset or to a different sensor pair.

**Evidence:** `artifacts/change/eval_test/eval_result.json`; [`EVALUATION.md`](EVALUATION.md).

### L-66 — The change evaluation records a large pixel imbalance (`MEASURED`)

The change test split is heavily imbalanced: pooled counts record `tp = 5,978,997`, `fp = 523,658`,
`fn = 858,407`, `tn = 126,856,666` over `n_pixels = 134,217,728`, with a mean change fraction of
**0.0509** and only **935 of 2,048** images containing change. A pooled IoU on a 5 % positive pixel rate
is not the same statistic as a balanced one, and the macro/pooled split (macro IoU 0.718 vs pooled IoU
0.8122) reflects that.

**Evidence:** `artifacts/change/eval_test/eval_result.json` (`metrics.pooled`, `metrics.macro`,
`mean_change_fraction`, `n_images_with_change`).

### L-67 — The router corpus is small and corpus-limited (`MEASURED`)

The router's training/evaluation corpus is **576** queries in **54** groups (`corpus_total: 576`,
`corpus_groups: 54`), with a by-task distribution of caption 91, change 115, grounding 128, optical_sar
50, unsupported 105, vqa 87. The validation split is **n = 86**. A 0.965116 validation accuracy over 86
examples, drawn from a 576-query corpus, is **indicative only**; it is not a benchmark result.

**Evidence:** `artifacts/router/router_adapter_v001/metadata.json` (`corpus`),
`artifacts/router/threshold_sweep_val.json`.

### L-68 — The change-VQA test and test2 splits share scenes (`MEASURED`)

The change-VQA dataset's integrity block lists `allowed_shared_pairs: [["Test", "Test2"]]` — the two
test splits legitimately share scenes, so they are **not independent draws** of the same population. A
number from one is not a confirmation of the other.

**Evidence:** `artifacts/change_vqa/run/run_record.json` (`dataset.integrity`).

### L-69 — The optical-SAR metric is on a 19-class space with five absent classes (`MEASURED`)

The fusion metric is defined over a **19-class** label space; the scored held-out split contains only 14
present classes (`classes_present: [0,2,3,4,5,6,7,8,9,10,12,13,17,18]`). The absent five contribute 0.0
to macro-F1 by construction, which is why accuracy (0.931) and macro-F1 (0.434161) diverge so sharply.
The metric is a single head's held-out result; it selects no head and compares no arms.

**Evidence:** `artifacts/optical_sar/fusion_head_production_v001/pre_registered_115_metric.json`.

### L-70 — The grounding evaluation is a single dataset and a single expression family (`MEASURED`)

Grounding is measured only on VRSBench referring expressions (n = 16,159). Nothing measures grounding on
a different expression style or a different imagery distribution. The `matched6` protocol (top_k = 6) is
the only protocol variation recorded.

**Evidence:** `artifacts/grounding/remoteclip_grounding_v001/eval_result_canonical.json`,
`eval_result_matched6.json`.

---

## 9. Explicit non-claims

These are things a reader might reasonably assume, which this project does **not** claim:

- **No claim of state-of-the-art performance** on any benchmark.
- **No claim of production readiness for model quality.** The deployment runs; the models carry the
  limitations above.
- **No claim that the trained heads generalise** beyond their training-family test splits.
- **No claim that calibration improves confidence** — it made ECE worse (0.013755 → 0.014929).
- **No claim that the VLM adapter is accepted** for production use — it is `ACCEPTANCE-REJECTED`.
- **No claim of an end-to-end accuracy number** — none exists.
- **No claim that the router is correct on all phrasings** — residuals exist (§2).
- **No claim that the router number is a test result** — it is validation, ungated, n = 86.
- **No claim that the optical-SAR or change-VQA rulings are settled** — both are `OPEN`.
- **No claim of robustness** to adversarial, corrupted, or out-of-distribution inputs.
- **No claim of geolocation accuracy** — grounding boxes are image-relative, not geodetic.
- **No claim that the system is a safety-, legal-, or life-critical tool.**
- **No claim that the code is licensed** — no `LICENSE` file exists.
- **No claim that the release repositories are public** — three of four are private by design.

---

## 10. Where the evidence lives

| Topic | Evidence |
|---|---|
| All measured metrics | `artifacts/**/*.json`, verified by `release/tools/verify_readme_metrics.py` |
| Metric honesty rules | [`BENCHMARKS.md`](BENCHMARKS.md), [`EVALUATION.md`](EVALUATION.md) |
| The grounding resolution rejection | `docs/PHASE7_RESOLUTION_DECISION.md` |
| The VLM rejection | `artifacts/vlm/phase6_closure.json` (`why_acceptance_rejected`), `docs/PHASE6_RUN1_REJECTION_DIAGNOSIS.md` |
| The optical-SAR ruling | `artifacts/optical_sar/fusion_head_production_v001/pre_registered_115_metric.json` |
| The change-VQA ruling | `artifacts/change_vqa/run/PROMOTION.json`, `docs/PHASE19_FINAL_HARDENING.md` §4.5 |
| The calibration result | `artifacts/calibration_v001.json`, `docs/STEP7_BACKEND_CHAIN_REPORT.md` §7 |
| B-07 / B-02 | [`DEPLOYMENT.md`](DEPLOYMENT.md) §8.1, §8.2; `docs/FINAL_DELIVERY_TODO.md` §5 |
| Router residuals | [`architecture/04-router.md`](architecture/04-router.md), `LIVE_VALIDATION_POSTFIX.md` |
| Environment traps | [`REPRODUCIBILITY.md`](REPRODUCIBILITY.md), [`RESEARCH_NOTES.md`](RESEARCH_NOTES.md) §8 |
| Stale documentation | `release/CURRENT_RELEASE_STATE.md` §6, `docs/PHASE12_CURRENCY_CORRECTION.md` |
| The stale-claim class | `docs/PHASE12_CURRENCY_CORRECTION.md` §6 |