feat(simulation): architecture-flavor pipeline (T-992/994/995/1003) #173

Closed
jpmschweitzer wants to merge 0 commits from architecture-flavor-pipeline into main
Owner

Summary

The D-232 architecture-flavor mechanism — the last blocker on T-959 (Layer 5 tile fill) and behind it T-962 (Phase 5 gate).

  • T-994 — three-phase trait draw: body K-draw (SeedChain::for_body, coverage-aware over a new body-level district-mix aggregate), district-dominant pick keyed by the D-243 2048m District cell, resolved at L3→L4 dispatch (FillChunk stays pure). Replaces the flat splitmix64 flavor pick. New trait_catalog_reader + trait_draw modules.
  • T-1003 — deviation/swerve system: ArchitectureFlavorRef = InVocabulary(u8) | Swerve(tag); rare per-building wildcard with foreign-import/heritage-callback pools + driver-scaled integer-bps rates (placeholder constants pending calibration); sparsity escape hatch at the phase-2 pick.
  • T-995 — ObjectTag registry ratified (shipped 28-tag palette canonical): wiki/economics/object_tag_vocabulary.toml + importer validation V-TT-03/V-TT-04 (tag existence, axis match, acyclic fallback graph). Resolves Q-049. systems.db regenerated + stamped.
  • T-992 — Gemma architecture-flavor methodology doc (text-fields-only corpus distillation, human-gated).

Governance: D-232 amended (2048m district pin — capture gap from D-222/D-243; swerve driver mappings), D-229 flavor_ref enum, D-235 vocabulary ratification, Q-049 resolved.

Also: chore(engine) crossbeam-epoch 0.9.20 (RUSTSEC-2026-0204, caught by the gate).

Gates: full cargo test (1630 green incl. golden harnesses), clippy -D warnings, ruff, test-tooling, cargo deny, fresh systems.db stamp.

🤖 Generated with Claude Code

## Summary The D-232 architecture-flavor mechanism — the last blocker on T-959 (Layer 5 tile fill) and behind it T-962 (Phase 5 gate). - **T-994** — three-phase trait draw: body K-draw (SeedChain::for_body, coverage-aware over a new body-level district-mix aggregate), district-dominant pick keyed by the D-243 2048m District cell, resolved at L3→L4 dispatch (FillChunk stays pure). Replaces the flat splitmix64 flavor pick. New trait_catalog_reader + trait_draw modules. - **T-1003** — deviation/swerve system: ArchitectureFlavorRef = InVocabulary(u8) | Swerve(tag); rare per-building wildcard with foreign-import/heritage-callback pools + driver-scaled integer-bps rates (placeholder constants pending calibration); sparsity escape hatch at the phase-2 pick. - **T-995** — ObjectTag registry ratified (shipped 28-tag palette canonical): wiki/economics/object_tag_vocabulary.toml + importer validation V-TT-03/V-TT-04 (tag existence, axis match, acyclic fallback graph). Resolves Q-049. systems.db regenerated + stamped. - **T-992** — Gemma architecture-flavor methodology doc (text-fields-only corpus distillation, human-gated). Governance: D-232 amended (2048m district pin — capture gap from D-222/D-243; swerve driver mappings), D-229 flavor_ref enum, D-235 vocabulary ratification, Q-049 resolved. Also: chore(engine) crossbeam-epoch 0.9.20 (RUSTSEC-2026-0204, caught by the gate). Gates: full cargo test (1630 green incl. golden harnesses), clippy -D warnings, ruff, test-tooling, cargo deny, fresh systems.db stamp. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jpmschweitzer added 5 commits 2026-07-08 10:01:03 +02:00
Si refinement round resolved 7 decisions: district-dominant = D-243 2048m tier
(build in T-994), draw at GenerateSkeleton, body-level coverage aggregate,
ratify shipped 28-tag palette (amend D-235), Gemma proposes text fields only,
swerve driver mappings pinned, T-1004 render mechanism deferred to Phase 5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage-1 register selection over the current wiki tree (Q-107 assumption
stated), stage-2 TEXT-FIELDS-ONLY structured proposals (tag, label,
cultural_description, candidate allow/block tags) — humans own all numeric
eligibility/weights (catalog-wide CI guardrails can't be satisfied
per-template); Araminta owns visual_bundle. No era-bands (Q-106 dissolved);
trauma_decay_rate stale-schema note. Mirrors docs/gemma-naming-methodology.md
incl. the sr-voice-tooling serving pattern. Worked example: GJ-4053 granite
dry-stack accept; GJ-1248/GJ-285/GJ-588 as correct stage-1 rejections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The shipped 28-tag catalog palette is canonical (user ratification,
/whats-next refinement 2026-07-07). New machine-readable registry
wiki/economics/object_tag_vocabulary.toml (wall/roof/facade/street axes +
4 generic fallback terminals, Miri/Araminta co-owned header). Importer
validation in economy_import/traits.py: V-TT-03 (every catalog
allow/block/visual_bundle tag exists in the registry, axis-checked) and
V-TT-04 (fallback graph: non-generics declare a parent, chains acyclic,
resolve to a generic — absorbs T-1004's Phase-4 slice). Registry added to
generator_sources (stamp coverage); systems.db regenerated + stamped.
Q-049 marked Resolved — divergence is now a loud build failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
T-994 — three-phase draw replacing the flat splitmix64 flavor pick:
- Phase 1 body K-draw (trait_draw.rs): hard gates -> soft weights (two-part
  geographic_sector join, PR #148) -> SeedChain::for_body-seeded weighted
  draw of K (5/3/1/0 by ComplexityTier), pins count toward K, coverage-aware
  over a new body-level district-type-mix aggregate threaded into
  CityGenerationContext at L3->L4 dispatch.
- Phase 2 district-dominant pick keyed by the D-243 2048m District cell —
  settlements sharing a cell independently derive the identical template.
  Resolved at dispatch, never in FillChunk (T-987 stays pure).
- trait_catalog_reader.rs: systems.db reader for trait_templates +
  atlas_body_trait_bias (D-225 resource pattern), registered in main.rs
  with graceful degradation.
- BlockSkeleton carries district_type; assign_block_tags is a pure lookup.

T-1003 — deviation/swerve system (trait_swerve.rs):
- ArchitectureFlavorRef is now InVocabulary(u8) | Swerve(tag).
- Rare per-building wildcard: foreign-import pool (other corridors +
  cross_corridor) driven by Epicenter/Passage tier, mixed faction,
  road-graph degree; heritage-callback pool (own-corridor heritage) driven
  by isolation, remote tier, founding_age_years. Integer bps, base 100,
  cap 300 per driver — placeholder constants pending calibration.
- Sparsity escape hatch = same mechanism, necessity-triggered at the
  phase-2 pick (deterministic max-weight over the hard-gate-eligible pool).
- New SeedDomains: TraitVocabulary(13) / TraitDistrict(14) / TraitSwerve(15).

Governance: D-232 amended (district pinned to the D-243 2048m tier — the
D-222/D-243 redefinition was never captured; swerve driver mappings +
placeholder rates recorded), D-229 flavor_ref field updated to the enum
shape, D-235 amended (T-995 vocabulary ratification note; rides here due
to single-file entanglement).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Invalid pointer dereference in fmt::Pointer for Atomic/Shared null
pointers; flagged by cargo deny in the pre-push gate. Transitive via
rayon; lockfile-only change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

Review: architecture-flavor-pipeline → main (type: code)

Reviewers: Hoshe (code quality), Tyre (architecture) — both read from the branch worktree at 034791602.

Hoshe (Code Quality): REQUEST_CHANGES

The three-phase trait-draw mechanism is well-designed and thoroughly unit-tested at the pure-function level — determinism, hard gates, coverage repair, swerve rarity, and the sparsity escape hatch all have solid tests mapping cleanly to D-232. Findings target the untested integration seam and robustness gaps.

# File Issue
H1 server/src/atlas/plugin.rs ~118–256 T-994 body-level aggregation (coverage set, max-K/prosperity aggregation, BodyVocabularyContext threading) is untested — existing tests bypass the whole branch. Add a test wiring the readers with 2+ placements asserting identical trait_selection on both dispatched contexts
H2 tooling/economy-db/economy_import/traits.py 31–124 V-TT-03/04 graph validation has no failure-branch tests (cycle, duplicate tag, axis mismatch, missing registry, generic-with-fallback). Pure dict-in/errors-out logic — add test_traits.py
H3 server/src/atlas/trait_catalog_reader.rs 284–314 parse_bulk_class_gate/parse_production_ubiquity_gate swallow malformed JSON via unwrap_or_default() with no logging — silently widening hard-gate eligibility. Sibling map-parsers tracing::warn! on the identical failure; match them
H4 server/src/atlas/trait_draw.rs 223–235, 296–309 No guard/warn when pins exceed K — silently breaks "K is not a range" (D-232); the over-K branch is untested. Warn in draw_body_vocabulary + bound pins in an importer guardrail
H5 plugin.rs ~198 / trait_catalog_reader.rs The immutable catalog is re-queried + re-parsed from SQLite on every body dispatch (~300 identical reads per run). Cache/memoize the parsed Vec<TraitTemplate>

Tyre (Architecture): REQUEST_CHANGES

Dispatch-time vs Rayon/FillChunk split correct (T-987 held), D-243 district-cell keying verified to make co-district settlements agree, all-integer/BTreeMap (D-010 clean), one-DB-round-trip-per-settlement aggregation is elegant. Two design-fidelity gaps in the phase-1 draw, two precision nits.

# File Issue
T1 trait_draw.rs 175–191, 237–288 corridor_pool == "heritage" templates enter the ordinary K-draw lottery ungated. D-232's two-part corridor pool reserves heritage for the remoteness dial ("tagged so the remoteness dial draws specifically from it") — with real catalog weights (7000–8000 bps) a deep-history callback becomes an everyday vocabulary member anywhere. Exclude heritage from the ordinary weighted pool + coverage repair; pins, phase-2 necessity_swerve, and the T-1003 swerve pools keep reading the full eligible set
T2 trait_draw.rs 296–309 Coverage repair pushes past K when every slot is pinned — but D-232's sparsity escape hatch is phase 2's necessity_swerve (out-of-vocabulary, never grows trait_selection), and "K is not a range." Leave the type uncovered here and let phase 2 handle it
T3 seed.rs 128–133 vs trait_draw.rs 384–388 SeedDomain::TraitDistrict doc says "packed (DistrictPos, DistrictType) id"; implementation chains two .derive() calls under one domain. Deterministic and safe, but doc and code disagree on a pinned D-224 contract — align one to the other
T4 trait_catalog_reader.rs 1–14 Module doc cites D-225 (the client-facing layer-stream proxy) for a pattern this reader doesn't follow. Cite the CityContextReader precedent (the pattern actually copied) instead

Verdict: CHANGES REQUESTED

Process notes:

  • Runtime verification performed: full cargo test (1630 incl. golden harnesses), clippy -D warnings, ruff, make test-tooling, cargo deny, fresh systems.db stamp — all in the pre-push gate.
  • Zero warnings introduced. No client merge-path touched (the one main.rs change is server startup resource registration with graceful degradation).
  • T2 + H4 converge on the same pins/K seam — one fix closes both.
## Review: architecture-flavor-pipeline → main (type: code) Reviewers: Hoshe (code quality), Tyre (architecture) — both read from the branch worktree at `034791602`. ### Hoshe (Code Quality): REQUEST_CHANGES The three-phase trait-draw mechanism is well-designed and thoroughly unit-tested at the pure-function level — determinism, hard gates, coverage repair, swerve rarity, and the sparsity escape hatch all have solid tests mapping cleanly to D-232. Findings target the untested integration seam and robustness gaps. | # | File | Issue | |---|------|-------| | H1 | `server/src/atlas/plugin.rs` ~118–256 | T-994 body-level aggregation (coverage set, max-K/prosperity aggregation, `BodyVocabularyContext` threading) is untested — existing tests bypass the whole branch. Add a test wiring the readers with 2+ placements asserting identical `trait_selection` on both dispatched contexts | | H2 | `tooling/economy-db/economy_import/traits.py` 31–124 | V-TT-03/04 graph validation has no failure-branch tests (cycle, duplicate tag, axis mismatch, missing registry, generic-with-fallback). Pure dict-in/errors-out logic — add `test_traits.py` | | H3 | `server/src/atlas/trait_catalog_reader.rs` 284–314 | `parse_bulk_class_gate`/`parse_production_ubiquity_gate` swallow malformed JSON via `unwrap_or_default()` with no logging — silently **widening** hard-gate eligibility. Sibling map-parsers `tracing::warn!` on the identical failure; match them | | H4 | `server/src/atlas/trait_draw.rs` 223–235, 296–309 | No guard/warn when pins exceed K — silently breaks "K is not a range" (D-232); the over-K branch is untested. Warn in `draw_body_vocabulary` + bound pins in an importer guardrail | | H5 | `plugin.rs` ~198 / `trait_catalog_reader.rs` | The immutable catalog is re-queried + re-parsed from SQLite on every body dispatch (~300 identical reads per run). Cache/memoize the parsed `Vec<TraitTemplate>` | ### Tyre (Architecture): REQUEST_CHANGES Dispatch-time vs Rayon/FillChunk split correct (T-987 held), D-243 district-cell keying verified to make co-district settlements agree, all-integer/BTreeMap (D-010 clean), one-DB-round-trip-per-settlement aggregation is elegant. Two design-fidelity gaps in the phase-1 draw, two precision nits. | # | File | Issue | |---|------|-------| | T1 | `trait_draw.rs` 175–191, 237–288 | `corridor_pool == "heritage"` templates enter the *ordinary* K-draw lottery ungated. D-232's two-part corridor pool reserves heritage for the remoteness dial ("tagged so the remoteness dial draws specifically from it") — with real catalog weights (7000–8000 bps) a deep-history callback becomes an everyday vocabulary member anywhere. Exclude heritage from the ordinary weighted pool + coverage repair; pins, phase-2 `necessity_swerve`, and the T-1003 swerve pools keep reading the full eligible set | | T2 | `trait_draw.rs` 296–309 | Coverage repair `push`es past K when every slot is pinned — but D-232's sparsity escape hatch is phase 2's `necessity_swerve` (out-of-vocabulary, never grows `trait_selection`), and "K is not a range." Leave the type uncovered here and let phase 2 handle it | | T3 | `seed.rs` 128–133 vs `trait_draw.rs` 384–388 | `SeedDomain::TraitDistrict` doc says "packed `(DistrictPos, DistrictType)` id"; implementation chains two `.derive()` calls under one domain. Deterministic and safe, but doc and code disagree on a pinned D-224 contract — align one to the other | | T4 | `trait_catalog_reader.rs` 1–14 | Module doc cites D-225 (the client-facing layer-stream proxy) for a pattern this reader doesn't follow. Cite the `CityContextReader` precedent (the pattern actually copied) instead | ### Verdict: CHANGES REQUESTED Process notes: - Runtime verification performed: full `cargo test` (1630 incl. golden harnesses), clippy `-D warnings`, ruff, `make test-tooling`, `cargo deny`, fresh systems.db stamp — all in the pre-push gate. - Zero warnings introduced. No client merge-path touched (the one `main.rs` change is server startup resource registration with graceful degradation). - T2 + H4 converge on the same pins/K seam — one fix closes both.
jpmschweitzer added 1 commit 2026-07-08 12:19:46 +02:00
T1: heritage corridor_pool excluded from the ordinary phase-1 lottery and
coverage repair (D-232 reserves the heritage sub-pool for the remoteness
dial); reachable via hero pin, necessity swerve, and the T-1003 heritage
pool only. 3 new tests.
T2+H4: coverage repair no longer grows trait_selection past K when all
slots are pinned (phase-2 necessity swerve serves the type instead);
runtime warn when authored pins exceed K; V-TT-05 importer guardrail
bounds pins per body at 5 (max ComplexityTier K). 2 new tests + 2 python
tests.
H1: body-level dispatch aggregation extracted to pure
aggregate_body_dispatch_inputs + tested directly (union mix, MAX
prosperity/K); threading test asserts identical vocabulary/pools across
co-body settlements with per-settlement swerve rates. 2 new tests.
H2: tooling/economy-db/test_traits.py — 14 stdlib unittest cases over
V-TT-03/04/05 failure branches, wired into make test-tooling.
H3: hard-gate JSON parsers now tracing::warn on malformed blobs (silent
gate-widening) matching the sibling map parsers.
H5: catalog read memoized (OnceLock) — SQL+parse once per server run,
bias stays per-body. 1 new test.
T3: TraitDistrict seed-domain doc aligned with the two-level derive chain.
T4: D-225 misattribution dropped from the reader module doc.

systems.db regenerated + stamped (traits.py is a stamped source).
Gates: full cargo test 1638 green (goldens intact), clippy -D warnings,
ruff, make test-tooling (now incl. the traits units).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
Owner

Review response — all 9 findings fixed in ebe874246

No pushbacks; every finding was verified against the branch and addressed.

# Resolution
T1 corridor_pool == "heritage" now excluded from the ordinary phase-1 lottery and coverage repair. A heritage template reaches a body only via an authored hero pin, the phase-2 necessity swerve, or the T-1003 heritage-callback pool (all read the full eligible set). 3 regression tests, incl. a 50-body sweep proving a 100× overweighted heritage template never wins the lottery.
T2 Coverage repair no longer pushes past K when every slot is pinned — the type is left to the phase-2 necessity_swerve (the actual D-232 sparsity escape hatch), with a debug log. "K is not a range" holds. Test: K=1 pinned body stays at exactly 1 template.
H4 Same seam: runtime tracing::warn! when authored pins exceed K (authored intent kept, loudly), plus a new V-TT-05 importer guardrail — >5 pins on one body (max ComplexityTier K) aborts the import. Tests on both sides.
H1 The body-level aggregation is extracted into pure aggregate_body_dispatch_inputs and tested directly (union district mix vs per-placement recompute, MAX prosperity, MAX K incl. the ghost-stub K=0 case). A second test drives build_skeleton_work_item for two co-body settlements and asserts identical trait_selection/mix/pools with per-settlement swerve rates (exact bps values locked: connected-young (120,150) vs isolated-old (100,300) capped).
H2 New tooling/economy-db/test_traits.py — 14 stdlib unittest cases covering every V-TT-03/04 failure branch (missing registry, unknown axis, duplicate tag, missing description, generic-with-fallback, orphan non-generic, unknown-fallback, cycle, wrong generic set) plus the catalog cross-checks (asserting the specific V-TT-03 line in captured output, since tiny catalogs also trip V-TT-01) and V-TT-05. Wired into make test-tooling as its own step.
H3 Both hard-gate parsers now tracing::warn! on malformed JSON ("gate widens to all classes/values") instead of silently unwrap_or_default() — matching the map-parser siblings.
H5 read_catalog() memoized via OnceLock — SQL + JSON parse once per server run, clones after; errors are not cached (transient failures retry). Per-body bias intentionally uncached. Test proves post-first-read DB writes are invisible.
T3 SeedDomain::TraitDistrict doc rewritten to describe the actual two-level derive chain (pos id, then type ordinal) — code unchanged, so no derivation churn.
T4 D-225 citation dropped from the reader module doc; the CityContextReader precedent (already cited) is the pattern actually followed.

Gates re-run after the fixes: full cargo test 1638 green (goldens intact — the heritage exclusion did not shift any golden output), clippy -D warnings, ruff, make test-tooling (now including the new traits units), systems.db regenerated + freshly stamped (traits.py is a stamped generator source).

## Review response — all 9 findings fixed in `ebe874246` No pushbacks; every finding was verified against the branch and addressed. | # | Resolution | |---|-----------| | T1 | `corridor_pool == "heritage"` now excluded from the ordinary phase-1 lottery **and** coverage repair. A heritage template reaches a body only via an authored hero pin, the phase-2 necessity swerve, or the T-1003 heritage-callback pool (all read the full eligible set). 3 regression tests, incl. a 50-body sweep proving a 100× overweighted heritage template never wins the lottery. | | T2 | Coverage repair no longer pushes past K when every slot is pinned — the type is left to the phase-2 `necessity_swerve` (the actual D-232 sparsity escape hatch), with a debug log. "K is not a range" holds. Test: K=1 pinned body stays at exactly 1 template. | | H4 | Same seam: runtime `tracing::warn!` when authored pins exceed K (authored intent kept, loudly), plus a new **V-TT-05** importer guardrail — >5 pins on one body (max ComplexityTier K) aborts the import. Tests on both sides. | | H1 | The body-level aggregation is extracted into pure `aggregate_body_dispatch_inputs` and tested directly (union district mix vs per-placement recompute, MAX prosperity, MAX K incl. the ghost-stub K=0 case). A second test drives `build_skeleton_work_item` for two co-body settlements and asserts identical `trait_selection`/mix/pools with per-settlement swerve rates (exact bps values locked: connected-young `(120,150)` vs isolated-old `(100,300)` capped). | | H2 | New `tooling/economy-db/test_traits.py` — 14 stdlib unittest cases covering every V-TT-03/04 failure branch (missing registry, unknown axis, duplicate tag, missing description, generic-with-fallback, orphan non-generic, unknown-fallback, cycle, wrong generic set) plus the catalog cross-checks (asserting the specific V-TT-03 line in captured output, since tiny catalogs also trip V-TT-01) and V-TT-05. Wired into `make test-tooling` as its own step. | | H3 | Both hard-gate parsers now `tracing::warn!` on malformed JSON ("gate widens to all classes/values") instead of silently `unwrap_or_default()` — matching the map-parser siblings. | | H5 | `read_catalog()` memoized via `OnceLock` — SQL + JSON parse once per server run, clones after; errors are not cached (transient failures retry). Per-body bias intentionally uncached. Test proves post-first-read DB writes are invisible. | | T3 | `SeedDomain::TraitDistrict` doc rewritten to describe the actual two-level derive chain (pos id, then type ordinal) — code unchanged, so no derivation churn. | | T4 | D-225 citation dropped from the reader module doc; the `CityContextReader` precedent (already cited) is the pattern actually followed. | Gates re-run after the fixes: full `cargo test` **1638 green** (goldens intact — the heritage exclusion did not shift any golden output), clippy `-D warnings`, ruff, `make test-tooling` (now including the new traits units), systems.db regenerated + freshly stamped (`traits.py` is a stamped generator source).
Author
Owner

Re-review (round 2): APPROVED

Both reviewers verified every fix in ebe874246 against the branch worktree — not just presence, but correctness.

Hoshe (Code Quality): APPROVE

All H1–H5 VERIFIED-FIXED. Hand-verified the threading test's swerve-rate constants (120/150 vs 100/300) against compute_swerve_rates arithmetic; confirmed OnceLock error-path semantics (failures retry, successes cache); ran all 14 test_traits.py cases and the 438 atlas:: Rust tests locally — green. The python3 (vs $(VENV_PY)) Makefile invocation is correct: the module is stdlib-only, matching the dry-run step's convention. No new issues.

Tyre (Architecture): APPROVE

All T1–T4 VERIFIED-FIXED. Traced T1's heritage exclusion at both fork points (lottery + coverage repair) and confirmed every escape hatch — hero pin, build_swerve_pools, phase-2 necessity_swerve — still reads the unfiltered eligible set, so a body whose only zone-covering template is heritage is still served (deterministically, as a Swerve ref). Traced T2's deferred DistrictType end-to-end into phase-2 necessity. Confirmed the H1 aggregation extraction is a pure refactor (identical BTreeSet→Vec ordering, D-010 clean). V-TT-05's bound of 5 matches complexity_k(Full) exactly. Independently re-ran full cargo test, test_traits.py, targeted clippy, and the stamp check — all clean. No new issues.

Verdict: APPROVED — proceeding to merge.

## Re-review (round 2): APPROVED Both reviewers verified every fix in `ebe874246` against the branch worktree — not just presence, but correctness. ### Hoshe (Code Quality): APPROVE All H1–H5 VERIFIED-FIXED. Hand-verified the threading test's swerve-rate constants (120/150 vs 100/300) against `compute_swerve_rates` arithmetic; confirmed OnceLock error-path semantics (failures retry, successes cache); ran all 14 `test_traits.py` cases and the 438 `atlas::` Rust tests locally — green. The `python3` (vs `$(VENV_PY)`) Makefile invocation is correct: the module is stdlib-only, matching the dry-run step's convention. No new issues. ### Tyre (Architecture): APPROVE All T1–T4 VERIFIED-FIXED. Traced T1's heritage exclusion at both fork points (lottery + coverage repair) and confirmed every escape hatch — hero pin, `build_swerve_pools`, phase-2 `necessity_swerve` — still reads the unfiltered eligible set, so a body whose only zone-covering template is heritage is still served (deterministically, as a `Swerve` ref). Traced T2's deferred DistrictType end-to-end into phase-2 necessity. Confirmed the H1 aggregation extraction is a pure refactor (identical BTreeSet→Vec ordering, D-010 clean). V-TT-05's bound of 5 matches `complexity_k(Full)` exactly. Independently re-ran full `cargo test`, `test_traits.py`, targeted clippy, and the stamp check — all clean. No new issues. ### Verdict: APPROVED — proceeding to merge.
jpmschweitzer closed this pull request 2026-07-08 17:11:31 +02:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jpmschweitzer/settled-reach#173