# PhaseEnd — Phase 35: Gen3 opens — the dedup phase, "one source per unique function" **Date:** 2026-09-08 · **Project Version:** 2.1.0 · **Phase Status:** Complete (milestone: see §Milestone — every item with its literal output; gate 2 = Drew's close commit) · **Generation:** Gen3 (the first phase; Drew's Gen3 order: dedup → pins → structs → names, one phase each, planned one at a time) > Chartered at gate 1 (S94, 2026-09-08, plan mode, Max) from `docs/gen3-handoff.md` + `docs/gen3-standards.md`, on evidence read from > sotn-decomp's tree that reversed the 2026-09-02 "leave the dedup backlog" decision. Ran **three sessions (S94–S96, all 2026-09-08)** and > **48 commits** (`48170fd7f..HEAD`, plus this close). The granular trail — every task's verify lines, the S94 death and the S95 > recovery, every tool defect with its cause — is at **`phase-ends/logs/Phase35.md`** (R19, on demand). Owner decisions (Drew): gate 1's > four (twins → one source directory; cross-address classes censused and deferred; macro-era tools frozen with a loud refusal; R96–R99 > ratified); no "trivial" exception; the tooling must know there is one source per unique function (→ the S1 gate); the recovery session's > scope ("capture only"); the effort levels per step (Max for two decisions delegated to Claude, high/xHigh otherwise); T9 run in the same > session at xHigh. ## Build Log **The phase in one line:** every shared function body became one plain-C header included at each member's site (sotn's shape), the five identical-payload overlay twins build from one source directory, the 4,755 already-matched duplicate copies of 1,099 same-address classes were shared down to 160 copies in 51 ledgered classes, 38 functions whose bytes vary per overlay share one text through a new registry tier, the invariant "one source per unique function" is a `tools-health` gate with a second, disagreeing oracle, the macro-era tools are frozen or retired behind a guard, the published numbers were corrected where the old counting was blind — and every step was proven by the 218 hashes from a clean rebuild. **Files created/changed and complete — do not recreate** (category summaries; the per-commit list is `git log 48170fd7f..HEAD` and the archived log): - **The shape (T3, T4, T5, T5b).** `src/shared/engine_prelude.h` (what every overlay/module TU includes at line 2), `src/shared/{ov,main, slot_800CAE08,slot_801E25E8,slot_801EF468}/func_[__|__t].h` — **3,175 headers**, one per shared body (2,215 converted from the macro header at T4, 914 + 1 + 38 written by the share tool); `src/shared/engine_core.h`, `ov_setters.h`, `clearTbl40.h` deleted; the whale `func_80144B9C.h` moved under `ov/`; **3,173 registry groups** in `config/dedup.us.yaml` (2,220 at the open; 38 of them `tier: h_text` in the verbose member form with per-member `h_exact`); `config/dedup_exceptions.tsv` (the S1 ledger: 51 rows, each with the compiler's diagnostic and a reason code); `config/overlays.mk` `_TWIN_OF/_SRC_DIR` for SC01_006, SC03_119, SC02_003, SC04_019, SC03_015 (their `src/` directories deleted, 166 files; the twins' yamls = the primaries' carves with `create_c_files: False`, their `JTBL_PADS` lines regenerated); the Makefile's twin block. - **The tools (T1, T2, T4, T5, T5b, T6, T7).** `tools/share_census.py` (the S1 census + gate: every sig instance resolves to one source form; verdicts A/B/C/D/M, flags E/F/TWIN/PINS/ALIAS; `--selftest` fixture; `--check --strict-macros --strict-text`; `text_classes`; the second, sig-blind oracle keyed by (text, address)), `tools/macro_to_header.py` (the T4 converter, kept as `share_body`'s library), **`tools/ share_body.py`** (the permanent share tool: `--plan / --apply --bucket extend|new|text / --reexemplar / --repair-registry`, the per-binary gate with object comparison and a snapshot-based bisect, the ledger, `--batches 1`), `tools/share_body_cycle.sh` (the unattended batch cycle: batch → exit code → phase-log entry → commit → periodic clean fleet run), `tools/frozen.py` (the one refusal 14 FROZEN tools print from `main()`), `tool_census.py` (status FROZEN; the `ast` macro-form guard with `--guard-root` for the negative control), `dedup_integrate.py` (C2c/C2d; the `h_text` tier with C1 per member), `progress.py` (the include form as a definition, the source-dir oracle, the empty-shared fold, `unique_function_bodies`, `duplicate_source_copies/_classes`, `text_tier_*`, `deferred_same_address_*`, a dated `corrections` list, the README sentence), `corpus.py` (`src_dir/twin_of`, the one source-dir oracle), 16 health-chain tools taught the include + twin forms (T2), 12 tools' dead macro branches dropped (T6); `tools/sunset/`: `dedup_propagate`, `dedup_extend` (their library surface moved verbatim into `share_body`), `macro_draft`, `test_reconcile_ledger`; the Makefile's `tools-health` gained `share_census --selftest` and the strict check before `report`. - **The record (T8).** `docs/wiki/The-dedup-engine.md` rewritten for the shared-source model; `Repository-layout.md`, `Where-the-project-goes-next.md`, `Verification-and-progress.md`, how-to ch.10, README prose and the generated block (with the "One source per unique function" sentence), `docs/gen3-standards.md` (§4 row struck, the DoD's "0 macro bodies" met), `docs/gen3- handoff.md` (dated snapshots), cookbook **§453** + a retirement banner on §14, `docs/decision-log.md` P35 (R31), `docs/accelerators.md` P35 (five), DIGEST §0/§2/§3/§4, `docs/SETUP.md` P35 sections (T1, T3–T5, T6, T7/T5b, the context guard), `docs/tool-index.md` and the kit corpus regenerated, the memory `dedup-backlog-leave-it` rewritten as REVERSED. - **Evidence (`.run/P35/`, allowlisted text):** `baseline/` (every R22 and tools-health log, the kit-corpus logs), `census/` (the census json/txt, `check_t5.txt`), `share/` (every batch record `batch_