Per-leaf breakdown of maple-court constructive seeds (6 seeds) overturns the
earlier 'shape-aware placement' handoff guess: shape fails are UNIFORM
(~68/73 leaves fail) at only 0.44 plot utilisation, dominated by crinkliness
(perimeter/area) then size (undersize). So the residual is neither a room->leaf
placement mismatch (no well-shaped leaves to place into) nor density-bound — it
is over-granular construction (73 small leaves for 52 rooms). Corrected the
§12.3 verdict accordingly and filed homemaker-py-c3g (construction granularity /
leaf-shape lever) as an unproven, must-be-A/B'd hypothesis.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
24-run sweep (maple-court + harbor, seeds 0/1/2, 20000 evals): M3 reassociate
and the shape-feasibility filter are both neutral-to-slightly-worse vs the
§12.2 baseline (maple 136.0 -> 139-140, harbor 74.0 -> 77-78). Baseline controls
reproduce §12.2 exactly, so the negative is real.
Verdict: the Phase-7 residual is the geometry/shape floor of the constructed
slicing layouts, not reachability/feasibility-bound — third independent negative
on search machinery (§11.4/§11.5/§12.3) vs four construction/seed wins
(§11.2/§11.6/§11.7/§12.2). A full canonical Polish rewrite is not justified: its
one testable promise (associativity reachability) was tested and did not pay.
Both operators kept default-OFF.
Closes 9gp.1, 9gp.2, 9gp; epic leu (Phase 7) auto-closed (3/3). Adds the
reproducible sweep harness experiments/run_9gp_ab.sh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Land the two evidence-supported parts of the re-scoped 9gp capstone as
operators on the existing decoded Node tree (no Polish-expression rewrite),
each default-OFF and measured against the §12.2 leu.2 baseline.
9gp.1 shape-feasibility pre-filter: operators.predicted_shape_fails lays a
topology out at its proportion-aware target geometry and counts shape fails
(size/width/proportion/crinkliness); driver._evaluate prunes clearly-infeasible
topologies before the inner loop (1 eval vs ~80), guarded so nothing that could
beat the incumbent is discarded. search/search_staged feasibility_filter,
feasibility_max_shape_fails (env FEAS/MAXSHAPE), default OFF.
9gp.2 M3 Wong-Liu reassociate: operators.mutate_reassociate adds associativity
(a|b)|c <-> a|(b|c) on same-orientation live cuts — the canonical-slicing move
missing from swap(M1)/rotate(M2), attacking the §11.4/§11.5 reachability
bottleneck. enable_reassociate (env REASSOC), default OFF (weight 0 -> baseline
byte-identical).
Unit tests (operators + driver) green, full suite 211 passed; maple-court smoke
run clean under native fitness. A/B sweep handed off per the plan; DESIGN.md
§12.3 documents the design and the pending measurement.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Size each constructive-seed cut from leaf TARGET areas (division=[f,f] gives
left area-fraction f) and pick each cut's rotation for child squareness — both
derived from target dims, topology/type assignment untouched. Area-only
regressed (slivers); rotation choice is what makes it pay.
End-to-end (20000 evals, 3 seeds, staged): harbor 85.3->74.0 (-13%, best 69),
maple-court 151.7->136.0 (-10%, best 126). PROP=0 reproduces the §11.7/§12.1
baselines exactly. programme-house regresses at fixed budget (deeper local
optimum walls off the undivide restructuring path) but a budget sweep shows
it's convergence speed, not a worse asymptote (PROP=1 reaches 1 fail at 150k).
Default-on (seed_proportion_aware=True, env PROP=1).
cq1: n_storeys now honours storey_minimum, not just level: keys — programme-house
(storey_minimum:2, all rooms level:0) was seeded one storey short and fell
through to plain search. New programme.storey_minimum()/n_storeys_for();
driver.search passes min_storeys to the seeder; search_staged routes on the max.
No-op for harbor/maple; programme-house single-stage 8.0->5.0.
New maple-court best (126) saved as generated.dom. 204 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_assign_adjacency_aware gains fixed_circ (seed the connected-dominating-set from
given circulation leaves) and secondary-adjacency-aware room placement: codes
with the most non-c adjacency requirements are placed first, each onto the open
slot satisfying the most of its requirements against already-typed neighbours
(clustering k1<->da1, da1<->o). lift_base_to_storeys(reqs, adjacency_aware=True)
grows the upper-floor circulation spine off the inherited vertical core and
assigns rooms around it; threaded through driver.search_staged
(seed_adjacency_aware) and run_staged_search.py (ADJ env).
End-to-end staged harbor, 20000 evals, mean total fails over 3 seeds:
ADJ=0 99.0 (reproduces the §11.4 staged lex baseline exactly), ADJ=1 85.3
(-13.7, -14%; best 78). New best harbor configuration overall: staged baseline
99.0 -> single-stage adjacency-aware (§11.6) 90.7 -> staged + adjacency-aware
lift 85.3. Staging and adjacency-aware seeding compose.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
operators._assign_adjacency_aware spends ~one extra leaf per three rooms on a
greedy connected-dominating-set of circulation leaves (read from the geometric
leaf_graph, type-independent), so every room borders a connected circulation
spine and adjacency-to-c + access are satisfied by construction. Default-on via
constructive_topology(adjacency_aware=True), threaded through
driver.search(seed_adjacency_aware) and run_search_scaled.py (ADJ env).
End-to-end single-stage, 20000 evals, mean total fails over 3 seeds:
harbor 110.0 -> 90.7 (-17.5%; ADJ=0 reproduces the §11.2 105 baseline exactly),
programme-house 12.3 -> 9.3 (-24%). Adjacency-aware single-stage harbor (mean
90.7, best 85) beats the §11.3 staged best of 95 — the first Phase-6 fail-count
reduction from seeding. Follow-ups (lift_base_to_storeys, secondary adjacencies)
filed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
genome.signature: ratio-invariant structural topology hash (per-storey tree
shape + cut orientation + leaf types), the cheap stand-in for the 9gp canonical
encoding. driver gains niche_by_signature (one individual per topology, replaces
the fitness-scalar dedup) and restart_patience (soft restart: keep elites,
refill with fresh seeds); SearchResult gains n_distinct_signatures /
diversity_history / n_restarts.
Diversity criterion MET (final-pop distinct ~5/16 -> 16/16). Gate NOT met:
blank-slate programme-house mean fails 12.3(legacy)/12.7(niche)/13.0(restart)
over 3 seeds at 20000 evals; harbor staged 95/94/108. Niching is a tie within
seed noise, restarts strictly worse — falsifies the premise that the
fitness-scalar dedup causes premature convergence. Both flags default-off,
kept for reuse. Epic c4c complete.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implement a graded proximity comparator key (-n_fails, grade, fitness) behind
a default-off use_grade flag: fitness._leaf_grade / score_with_grade sum
f/FAIL_THRESHOLD over failing per-leaf quality factors; scalar fitness and fail
count stay untouched so the inner-loop 0.5^n cliff (§5.4) is unaffected (0/9
regression check: PASS). Read once per child in driver._evaluate off the
already-optimised tree; threaded through search_staged (Stage 2 only).
Harbor staged A/B (20000 evals, seeds 0/1/2): lex 95/96/106 (mean 99.0) vs
lex+grade 99/98/102 (mean 99.7) — grade wins 1/3, no plateau escape. Premise
falsified: within a fixed fail-tier 0.5^n is constant so fitness still spans
~6 orders of magnitude; grade above fitness displaces that working signal.
Verdict: reject; lexicographic (-n_fails, fitness) stands. Flag kept default-off
for reproducibility / possible reuse as a §11.5 diversity signal.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Search the genome in causal dependency order. Stage 1 evolves a single-storey
base over the level-0 room set (programme auto-derived to a tempdir), ranked
with a substrate-readiness bonus (reserved core × divisible capacity) so the
base is selected as a good substrate, not just a good ground floor (anti-§4.2).
Stage 2 lifts the best base into a full multi-storey design — preserving the
inherited core, instantiating each upper storey's required set by construction —
and searches the deltas with the base mutable at low probability (base_p=0.15).
New: programme.{n_storeys_required,partition_rooms_by_storey,write_stage1_programme},
graph.substrate_readiness, operators.{lift_base_to_storeys,_pick_weighted_by_storey},
base_p threading, driver.search rank_bonus_fn/seed_factory/base_p hooks +
search_staged orchestrator, experiments/run_staged_search.py, tests/test_staging.py.
Result (harbor, 20000 evals, seed 0): staged 95 fails vs single-stage 105
(-10, -9.5%), gain in crinkliness 27->18 + edge 12->8. Anti-bungalow confirmed
(Stage-2 core moves all noop — core inherited, not carved). Programme-house
regression PASS (warmstart-2f4 still reaches whole-pop 1-fail).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the required programme room set a constructive invariant instead of
something the topology search must stumble onto by random divide+retype.
- operators.constructive_topology: bootstrap seeder that sizes each storey to
its required rooms (partitioned by level; level-free rooms distributed),
+1 core C and +1 O per storey, then assigns types. Stochastic for population
diversity. Wired into driver bootstrap when the programme has required spaces.
- operators.mutate_place_missing: repair op that inserts a missing required
space by dividing a host leaf into [room | remainder]. Lex-safe host ranking
(generic O first, never displace a required room); honours required level.
Weight 2.0 in the mutation mix; noops cheaply once the set is complete.
A/B on harbor-house (20k evals, seed 0, identical config):
old random-bootstrap 133 fails (103 missing, 77%)
new constructive 105 fails ( 12 missing, 11%) -21% total, missing-stack
collapsed; seed head-start 163->139.
§4.10 regression PASS: warmstart-2f4 still reaches a 1-fail population at 50k.
Verdict (DESIGN.md §11.2): construction is necessary and reframes the
bottleneck to quality-fail packing of a complete dense design (crinkliness/
size/access/edge) -> unblocks §11.3 staging, motivates §11.4 graded objective.
Follow-up filed (homemaker-py-s44): adjacency-aware seeding.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Built examples/harbor-house-l0/ (10 explicit level:0 codes, 13 instances,
single-storey constraints) and ran the memetic search from a bare plot. Best
33 fails at 20000 evals; whole population stuck 33–35, deep in the 0.5^n
high-fail regime. Fail histogram is dominated by 'missing' (13/33 = 39%): the
counted space m×3 is never constructed, with adjacency/access/size fails
downstream of the unbuilt room set.
Verdict: per-floor CONSTRUCTION is the bottleneck, not multi-storey coupling —
c4c.2 (programme-aware construction + missing-room repair) is the prerequisite
and staging (c4c.3) alone won't rescue it. Closes homemaker-py-c4c.1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Records the diagnosis (§11.0) and stubs the experiment subsections (§11.1-11.5)
for epic homemaker-py-c4c children, to be filled in by the sessions that run
each experiment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Records: the level-fix deceptive valley, compound operator design,
warm_x0 initialization bug and fix, two-C topology breakthrough,
0-fails geometric impossibility proof, and final 1-fail results
beating the Perl optimiser.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Outer search now ranks individuals by (-n_fails, fitness) instead of raw
fitness scalar. This prevents high-score 3-fail designs from displacing
2-fail designs in tournament selection and population replacement — the
root cause of the §4.8 pathology where flag count dominates geometry.
Inner loop is unchanged: it still optimises against the raw 0.5^n fitness
scalar, so the cliff that prevents trading into new failures remains intact
(0/9 regressions in experiments/penalty_reshape.py).
Also removes stale _CHILD_INNER_KW = {"sigmas": (0.05,)}: this was left
over from the CMA-ES era; the NM inner loop default (homemaker-py-d6d)
does not accept a sigmas parameter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
programme-house budget=20000: 1.04e-02 (2 fails), 1.36× over Phase-2
oracle run and 2.60× over urb-evolve p128. Winning topology found via
rotate at eval 10357, unreachable within Phase-2 budget. 71.8 evals/s
(~140× faster than batched oracle).
harbor-house (16 rooms): 3.73e-18 (49 fails) at budget 10000 in 633s.
This programme is beyond the oracle's capability; native fitness makes
it feasible. 638 topologies explored.
Adds experiments/run_search_scaled.py (native-only search runner, no
oracle dependency). DESIGN.md records Phase 3 gate result.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
benchmark_vs_urbevolve.py results (2026-06-13, budget=2000, URB_NO_OCCLUSION=1):
- Seeded designs: memetic beats urb-evolve 1.91× (c964435) and 1.63× (2f45907)
- Blank slate init.dom: memetic at 18 fails vs urb-evolve at 6 fails (topology
diversity gap from single-seed mutation chain vs random-population init)
Bug fixed: run_search.py was calling oracle.score on out.parent without
patterns.config present — causing the re-score to return near-zero instead of
the correct tracked fitness. Added shutil.copy to propagate patterns.config
alongside the output .dom before the standalone re-score.
Gate recorded in DESIGN.md §7. Closes homemaker-py-way.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4-way comparison (NM / CMA-ES / compass / compass-ms) over 3 corpus files ×
3 seeds at budget 200, cold-start, URB_NO_OCCLUSION=1. CMA-ES wins on
batch-efficiency (18 oracle calls vs 200 for NM, 12x speedup on Perl startup
amortisation per §4.6) with acceptable quality (x1.41 @200 vs NM's x1.56).
Compass stalls on narrow-valley landscapes and introduces fail regressions.
NM flagged as Phase 3+ candidate once native fitness removes oracle call overhead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Corpus: all 35 scores shift (x1.0-1.24, daylight pinned), one expected
failure-set change (458aa8b8 +2 crinkliness), oracle ~8% faster batched.
New deterministic-seed reference gains become the accept_innerloop bars:
x1.63 / x1.70 / x1.68 at budget 400, ~35 oracle calls per topology.
urb-evolve respects the flag by construction (in-process fitness reads
ENV at call time). Old flag-off numbers kept in DESIGN as historical.
Closes homemaker-py-gp2 (Urb-side patch lives in /home/bruno/src/urb,
uncommitted there pending review).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Strategy decision (Bruno): occlusion is orthogonal to building a scalable
optimiser. Instead of porting Sun/Occlusion/CIESky, disable it in Urb
behind an env flag (daylight -> 1, illumination factor -> 1 so crinkliness
is unweighted external wall area / floor area). Python occlusion rebuild
deferred until optimisation is fully native.
Tracker: new homemaker-py-gp2 (flag + re-baseline) gates gnw/way/uxz;
homemaker-py-2g5 re-scoped to the post-Phase-5 Python rebuild (P4).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Self-contained design + plan structured for breaking into bd (beads) tasks:
domain constraints that fix the slicing representation; what was built;
full empirical record (geometry port validated 35/35; area-proxy solver
falsified; perpendicular artifact resolved via equal-offset cuts; full-fitness
frozen-topology optimisation validated with 24-67% headroom; 0.5^n cliff);
validated memetic architecture; component plan; phased roadmap; risks/open
questions; repro steps; gotchas.
Oracle throughput measured: ~0.99s/dom batched vs 1.65s single (assessment-
dominated). urb-fitness.pl batches many doms per call, so native fitness is a
later speed/scale optimisation, not a gate; favour population/batch optimisers
and prototype the search on the batched oracle first.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>