diff --git a/docs/progress.json b/docs/progress.json
index d8f7ddc6f9..44fefa948e 100644
--- a/docs/progress.json
+++ b/docs/progress.json
@@ -66,7 +66,7 @@
},
"types": {
"date": "2026-10-03",
- "head": "3a9377c926",
+ "head": "20faec8d40",
"snapshot": "P39",
"census": ".run/P39/census/type_census.json",
"what": "the structs phases' counters: raw pointer-cast dereferences in four forms (P *(T*)(\u2026), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD), struct definitions and their duplicate classes, lying call declarations, and the struct map's types",
diff --git a/docs/progress.md b/docs/progress.md
index e7c849de74..93b3230068 100644
--- a/docs/progress.md
+++ b/docs/progress.md
@@ -18,5 +18,3 @@ REAL matches: CdQueueBusy CdReadRequest CdReadSectorReadyCB CdReadStateMachine D
NON_MATCHING:
build SHA1: 143dbb89f34491258bbc27810d0a12ec8b43a8dd (byte-identical)
-
-empties audit: 43/43 genuine jr;nop (all clean)
diff --git a/docs/readability-progress.tsv b/docs/readability-progress.tsv
index 709ee995a4..1555704ebc 100644
--- a/docs/readability-progress.tsv
+++ b/docs/readability-progress.tsv
@@ -12,3 +12,4 @@ date label commit definitions narrow_decls callees kr_empty narrow pinned_rows p
2026-10-02 P3.39 T7.1: GTE to one spelling (direct GTE 492 -> 0, per-TU gte defs 150 -> 0) 72e4c48c8928a952e3c0021620ee2cdc85dbc169 16094 11 3 2 9 0 0 260306 320402 336219 257469 49831 13790 15129 18889 173103 1650 1021 600 523 53 496 17878 98.8 5293 200 418 96
2026-10-02 P3.39 T8: lever residue TSV (2433 rows, reading A) 21f3aee1b2cbbca84ab26fbd5a49c869ce5db7f8 16094 11 3 2 9 0 0 260312 320402 336225 257475 49831 13790 15129 18889 173103 1650 1021 600 523 53 496 17677 98.8 5293 200 418 96
2026-10-02 P3.39 close: cast campaign, reading A 3a9377c926d83ba643f29f28186a3e810e15736d 16094 11 3 2 9 0 0 260312 320402 336225 257475 49831 13790 15129 18889 173103 1650 1021 600 523 53 496 17968 98.8 5293 200 418 96
+2026-10-02 P3.39 T12: phase-close docs 20faec8d40b1aa3bfe30398ba250c9dc4b571df9 16094 11 3 2 9 0 0 260312 320402 336225 257475 49831 13790 15129 18889 173103 1650 1021 600 523 53 496 17968 98.8 5293 200 418 96
diff --git a/docs/readability.md b/docs/readability.md
index 368b0303c8..e30d76ed09 100644
--- a/docs/readability.md
+++ b/docs/readability.md
@@ -21,6 +21,7 @@
| 2026-10-02 | P3.39 T7.1: GTE to one spelling (direct GTE 492 -> 0, per-TU gte defs 150 -> 0) | `72e4c48c8` | 11 | 2 | 9 | 0 | 260306 | 320402 | **336219** | 173103 | 1650 (1021 / 600) | 523 | 53 / 496 | 17878 (98.8 %) | 5293 | 418 |
| 2026-10-02 | P3.39 T8: lever residue TSV (2433 rows, reading A) | `21f3aee1b` | 11 | 2 | 9 | 0 | 260312 | 320402 | **336225** | 173103 | 1650 (1021 / 600) | 523 | 53 / 496 | 17677 (98.8 %) | 5293 | 418 |
| 2026-10-02 | P3.39 close: cast campaign, reading A | `3a9377c92` | 11 | 2 | 9 | 0 | 260312 | 320402 | **336225** | 173103 | 1650 (1021 / 600) | 523 | 53 / 496 | 17968 (98.8 %) | 5293 | 418 |
+| 2026-10-02 | P3.39 T12: phase-close docs | `20faec8d4` | 11 | 2 | 9 | 0 | 260312 | 320402 | **336225** | 173103 | 1650 (1021 / 600) | 523 | 53 / 496 | 17968 (98.8 %) | 5293 | 418 |
**How to read it.** A *lying declaration* is a call site whose in-scope declaration names fewer parameters
than the callee's own definition. It is not a style problem: on this processor an argument travels in a
diff --git a/docs/story-timeline.md b/docs/story-timeline.md
index 30455f6d2d..324bd3bff7 100644
--- a/docs/story-timeline.md
+++ b/docs/story-timeline.md
@@ -103,6 +103,6 @@
| 2026-09-29 | 40 | P37 (v2.3.0) | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | 789 / 2091 | 3,730 | — | — |
| 2026-09-30 | 93 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — | — | 502,983 | 1,650 |
| 2026-10-01 | 73 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — | — | — | — |
-| 2026-10-02 | 141 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | 789 / 2091 | 3,364 | 336,225 | 1,650 |
+| 2026-10-02 | 145 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | 789 / 2091 | 3,364 | 336,225 | 1,650 |
82 dated rows · phase ticks from the 38 PhaseEnds · the chart: `docs/story-timeline.svg`.
diff --git a/docs/story-timeline.svg b/docs/story-timeline.svg
index 344565bcb0..794883863c 100644
--- a/docs/story-timeline.svg
+++ b/docs/story-timeline.svg
@@ -87,7 +87,7 @@
register pins + asm statements (the lever series, 99 increments): 53,221 → 3,364
raw pointer-cast dereferences — the one-form regex count (until the census, 2026-09-12): 414,148 → 411,850
-
+
raw pointer-cast dereferences — the four-form census (2026-09-12 →; a new instrument, its own 100 %): 503,016 → 336,225
generated by tools/timeline.py — keyed by date
diff --git a/docs/struct-map.md b/docs/struct-map.md
index d26152853f..f43334e75a 100644
--- a/docs/struct-map.md
+++ b/docs/struct-map.md
@@ -1,6 +1,6 @@
# The struct map — the types the fleet's cast sites need (Phase 37 T1)
-> **Generated by `tools/type_census.py` at `3a9377c926` (2026-10-03T04:25:25Z); never typed (R75).** Every raw pointer-cast dereference in `src/` was assigned to a base (a parameter, a local, a global by value or by address, an absolute address) and the bases were clustered by EVIDENCE only — the same global symbol, an argument passed to a callee's parameter, an assignment or return, a pointer field read, a shared body's fleet-wide identity — never by a similar offset signature. Each cluster is one type the tree needs. Names are placeholders (`Unkstruct_`: the lowest global instance's address, else the lowest member function's); fields are placeholders (`unk`) until Phase 38 cites evidence.
+> **Generated by `tools/type_census.py` at `20faec8d40` (2026-10-03T04:56:30Z); never typed (R75).** Every raw pointer-cast dereference in `src/` was assigned to a base (a parameter, a local, a global by value or by address, an absolute address) and the bases were clustered by EVIDENCE only — the same global symbol, an argument passed to a callee's parameter, an assignment or return, a pointer field read, a shared body's fleet-wide identity — never by a similar offset signature. Each cluster is one type the tree needs. Names are placeholders (`Unkstruct_`: the lowest global instance's address, else the lowest member function's); fields are placeholders (`unk`) until Phase 38 cites evidence.
**17968 types explain 332313 of 336225 dereference sites (98.8 %); 3912 sites have a base the census could not classify; 813 types carry a width conflict.** Merges by evidence: param 39300, assign 19424, arg 10513, field 6557, ret-of 6015, return 1537, assign& 1401, arg& 253, nested 9.