Commit graph

108 commits

Author SHA1 Message Date
13f73be771 Topology genome: base tree + per-storey deltas + type assignment
genome.py (homemaker-py-k2g): Genome = base-floor GNode tree + per-storey
StoreyDelta (undivides, divide subtrees, leaf retypes, height) + base
metadata. encode/decode round-trips dom.py Node trees.

Key empirical finding baked into the design: upper-storey nodes carry
heavily drifted DEAD fields (97 inherited-cut divisions, 187 rotations
differ from the owning node below across the corpus) — dead because
geometry delegates to below before reading them. decode canonicalises
them; encode stores only owned state, so genomes from drifted sources
compare equal (fixed-point test).

Acceptance: 35/35 corpus files fitness-identical after round-trip through
the oracle (experiments/genome_parity.py, URB_NO_OCCLUSION=1); owned-cut
projection + genome fixed-point + storey counts in tests/test_genome.py
(16 tests pass).

Closes homemaker-py-k2g.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 13:52:32 +01:00
5f0c159112 Re-baseline under URB_NO_OCCLUSION: new reference gains, DESIGN §4.7
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>
2026-06-12 10:31:38 +01:00
1cc86c8a7e Warm-vs-cold experiment: topology mutations + Lamarckian ratio inheritance
experiments/warm_vs_cold.py (homemaker-py-8cs): top-storey divide/undivide
mutations on corpus designs, path-keyed inheritance of the parent's
optimised ratios (surviving cuts keep values, new cuts 0.5), per-evaluation
convergence traces; reports oracle evals to 95% of best final, warm vs
cold. Machinery validated oracle-free (cut survival counts) and one
mutated child scored through the oracle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 10:00:51 +01:00
511c86c4dc Fix cma convergence test: assert basin convergence, not final-digit polish
The sigma-ladder default splits the budget into restart phases, so a
400-eval run reaches ~0.996 on the smooth test objective rather than
0.999+. Test now matches the component's contract. (Previous commit
landed with this failing because piping pytest to tail masked its exit
code.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:46:13 +01:00
0dcdf1f29f Geometry inner loop: batched full-objective ratio optimiser (CMA-ES)
innerloop.py: optimise(root, programme_dir, x0=None, budget, method) ->
Result, optimising equal-offset free-branch ratios (midpoint projection of
legacy unequal cuts) against full oracle fitness. OracleEvaluator scores
each population in one batched perl call. Methods: cma (default) — multi-
start sigma ladder (0.05 local, 0.15 exploratory) with IPOP-style popsize
doubling and deterministic seeding (pycma treats seed 0 as clock!) — and
compass with Hooke-Jeeves pattern moves, kept for the d0s bake-off.

Acceptance (experiments/accept_innerloop.py, §4.5 bars vs unprojected
originals, within-noise tolerance 1%): x1.65 / x1.66 / x1.58 against bars
x1.24 / x1.67 / x1.59, no new failures, 46 oracle calls vs Nelder-Mead's
200. The two near-bar results are statistically indistinguishable from the
single-NM-draw bars (measured draw spread brackets them); decision approved
by Bruno 2026-06-12.

Also: tests/ scaffold (12 oracle-free unit tests, pytest pythonpath=src),
rebaseline_no_occlusion.py for homemaker-py-gp2, cma>=3.0 dependency
(installed via dnf), dead-variable cleanup in solver.py.

Closes homemaker-py-1p0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:42:24 +01:00
d4266f46dc Descope occlusion/daylight: disable in Urb, port simple crinkliness only
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>
2026-06-12 08:31:20 +01:00
2ef2b15fe3 Batched oracle: score many .dom files per perl invocation
oracle.score_batch() writes/cleans N outputs and runs urb-fitness.pl once
with all file names; oracle.score() is now a thin wrapper. Adds
Score.fail_lines (sorted) because Perl hash-order randomisation shuffles
.fails line order between runs, and documents Urb's ~1-ULP score
nondeterminism (compare with rel tolerance, never ==).

experiments/bench_batch_oracle.py validates batch-vs-single parity on the
35-file corpus and benchmarks: 0.98 s/dom batched vs 1.27 s/dom single
(x1.30), all files identical (fitness to 1e-12 rel, exact failure sets).

Closes homemaker-py-av5.
2026-06-12 01:13:55 +01:00
16f1704bdc Add beads issues for DESIGN.md phases 1-5 with dependency graph 2026-06-12 00:40:28 +01:00