Sync beads jsonl after c4c.3 close

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bruno Postle 2026-06-18 06:06:41 +01:00
parent 6ed9e0b4b1
commit bbbbdedde8

View file

@ -1,4 +1,4 @@
{"id":"homemaker-py-c4c.3","title":"Staged per-floor search (curriculum: credible base floor, then upper floors as deltas)","description":"Search the genome in its causal dependency order. The base-floor tree is the master; upper storeys are deltas (Below-inheritance). The programme partitions rooms by required level (harbor: 10 L0, 4 L1, 2 free), so each floor's target room set is known up front. Today the search discovers both floors simultaneously via random typing + the rare/drastic level_add (weighted 0.2) — an uncontrolled, degenerate version of staging.\nStage 1 — base floor: search the single-storey tree over the level-0 room set, dimensionality reduced (one tree, no deltas).\nStage 2 — upper floors as deltas: seed each upper storey with ITS required room set (via the construction op, homemaker-py-c4c.2), search the deltas; keep the base MUTABLE at low probability so it can adapt to upper-floor pressure.\nCRITICAL non-goal: do NOT hard-freeze the base. A base optimised purely as ground floor is a §4.2-style partial objective and can be a bad SUBSTRATE. Stage 1 objective must include (a) a reserved, vertically-alignable circulation core and (b) a substrate-readiness term: enough divisible area/cut structure to host the level-1 room set later.","design":"Premise gated by homemaker-py-c4c.1: only high-value if single-storey construction already reaches low fails. Substrate-readiness proxy candidates: count of base leaves large enough to subdivide for L1 rooms; presence of a core node with vertical continuity. Stage transition: when stage-1 base hits a fails/score threshold or budget fraction, freeze-soft and open the delta genome. Composes with canonical encoding (homemaker-py-9gp) — deltas are where redundancy/coarse moves hurt most.","acceptance_criteria":"Staged search beats single-stage on harbor-house (best fails/score), measured at equal native-fitness budget and recorded in DESIGN.md §11.x + bead notes. Reserved-core + substrate-readiness shown to prevent the bungalow trap (stage-2 does not have to carve a core from scratch — track core-carving moves). No regression on programme-house.","notes":"DONE. Implemented driver.search_staged (Stage 1 single-storey base over level-0 set with substrate-readiness ranking bonus; Stage 2 upper floors lifted as constructed deltas, base mutable at 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}, driver.search rank_bonus_fn/seed_factory/base_p hooks, 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-\u003e18 + edge 12-\u003e8, small access cost +5. Anti-bungalow CONFIRMED: all Stage-2 core_divide/undivide in winning lineage are noops (core inherited, not carved). Regression PASS: programme-house warmstart-2f4 still reaches whole-pop 1-fail. DESIGN.md §11.3 filled. Remaining high-fail plateau is §11.4 (graded objective) territory.","status":"in_progress","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-17T19:01:01Z","created_by":"Bruno Postle","updated_at":"2026-06-18T05:04:32Z","started_at":"2026-06-18T04:25:07Z","dependencies":[{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c","type":"parent-child","created_at":"2026-06-17T20:01:00Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c.1","type":"blocks","created_at":"2026-06-17T20:01:00Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c.2","type":"blocks","created_at":"2026-06-17T20:01:01Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0}
{"id":"homemaker-py-c4c.3","title":"Staged per-floor search (curriculum: credible base floor, then upper floors as deltas)","description":"Search the genome in its causal dependency order. The base-floor tree is the master; upper storeys are deltas (Below-inheritance). The programme partitions rooms by required level (harbor: 10 L0, 4 L1, 2 free), so each floor's target room set is known up front. Today the search discovers both floors simultaneously via random typing + the rare/drastic level_add (weighted 0.2) — an uncontrolled, degenerate version of staging.\nStage 1 — base floor: search the single-storey tree over the level-0 room set, dimensionality reduced (one tree, no deltas).\nStage 2 — upper floors as deltas: seed each upper storey with ITS required room set (via the construction op, homemaker-py-c4c.2), search the deltas; keep the base MUTABLE at low probability so it can adapt to upper-floor pressure.\nCRITICAL non-goal: do NOT hard-freeze the base. A base optimised purely as ground floor is a §4.2-style partial objective and can be a bad SUBSTRATE. Stage 1 objective must include (a) a reserved, vertically-alignable circulation core and (b) a substrate-readiness term: enough divisible area/cut structure to host the level-1 room set later.","design":"Premise gated by homemaker-py-c4c.1: only high-value if single-storey construction already reaches low fails. Substrate-readiness proxy candidates: count of base leaves large enough to subdivide for L1 rooms; presence of a core node with vertical continuity. Stage transition: when stage-1 base hits a fails/score threshold or budget fraction, freeze-soft and open the delta genome. Composes with canonical encoding (homemaker-py-9gp) — deltas are where redundancy/coarse moves hurt most.","acceptance_criteria":"Staged search beats single-stage on harbor-house (best fails/score), measured at equal native-fitness budget and recorded in DESIGN.md §11.x + bead notes. Reserved-core + substrate-readiness shown to prevent the bungalow trap (stage-2 does not have to carve a core from scratch — track core-carving moves). No regression on programme-house.","notes":"DONE. Implemented driver.search_staged (Stage 1 single-storey base over level-0 set with substrate-readiness ranking bonus; Stage 2 upper floors lifted as constructed deltas, base mutable at 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}, driver.search rank_bonus_fn/seed_factory/base_p hooks, 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-\u003e18 + edge 12-\u003e8, small access cost +5. Anti-bungalow CONFIRMED: all Stage-2 core_divide/undivide in winning lineage are noops (core inherited, not carved). Regression PASS: programme-house warmstart-2f4 still reaches whole-pop 1-fail. DESIGN.md §11.3 filled. Remaining high-fail plateau is §11.4 (graded objective) territory.","status":"closed","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-17T19:01:01Z","created_by":"Bruno Postle","updated_at":"2026-06-18T05:04:48Z","started_at":"2026-06-18T04:25:07Z","closed_at":"2026-06-18T05:04:48Z","close_reason":"Closed","dependencies":[{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c","type":"parent-child","created_at":"2026-06-17T20:01:00Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c.1","type":"blocks","created_at":"2026-06-17T20:01:00Z","created_by":"Bruno Postle","metadata":"{}"},{"issue_id":"homemaker-py-c4c.3","depends_on_id":"homemaker-py-c4c.2","type":"blocks","created_at":"2026-06-17T20:01:01Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0}
{"id":"homemaker-py-c4c.2","title":"Programme-aware construction + missing-room repair operator","description":"Highest-leverage fix for the epic's diagnosis. Today mutate_divide (operators.py:71) types new leaves at RANDOM, so required programme spaces go missing -\u003e 'missing' stacking dominates fitness on full programmes (harbor: 6 missing-room records stacking critical+size+width+adjacency+level). Make the required room set a constructive invariant rather than something the search must stumble onto.\nTwo parts:\n1. Constructive seeder: generate initial topologies that instantiate each required space (respecting count/level/type) by construction, instead of random divide+retype chains.\n2. Repair operator mutate_place_missing: detect a required-but-absent space and insert it (divide a compatible leaf, type the new leaf to the missing code, prefer a slot satisfying its adjacency). Complements mutate_level_compound_fix (which repairs level, not presence).\nWire the seeder into driver bootstrap and the repair op into mutate() weights.","design":"Seeder must place generic C (circulation/core) and O (outside) too, not just programme codes. Keep it stochastic (diverse population) but biased to cover the required set + correct levels. Repair op should be lex-safe: prefer insertions that don't create more new fails than the missing-stack it removes (cf. the §4.10 deceptive-valley lesson — a naive insert dumps a room into a bad slot and nets worse).","acceptance_criteria":"On harbor-house, 'missing'-type failures collapse to ~0 across the population (record before/after fail histograms); measured net-fail improvement vs current 74-fail out1.dom baseline, recorded in DESIGN.md §11.x + bead notes. No regression on seeded programme-house (still reaches 1-fail optimum, §4.10).","notes":"DONE 2026-06-17. Implemented constructive_topology seeder + mutate_place_missing repair op (operators.py), wired into driver bootstrap + mutate weights. A/B on harbor (20k evals, seed 0, identical config): old random-bootstrap 133 fails (103 missing, 77%) -\u003e new constructive 105 fails (12 missing, 11%); missing-records 22-\u003e2; -21% total. Seed head-start 163-\u003e139. §4.10 regression PASS: warmstart-2f4 still reaches 1-fail population at 50k. Verdict: construction necessary, reframes bottleneck to quality-fail packing (crinkliness/size/access/edge) of complete dense design -\u003e unblocks §11.3 staging, motivates §11.4 graded objective. Follow-up filed: adjacency-aware seeding. Full numbers in DESIGN.md §11.2. 186 tests pass.","status":"closed","priority":1,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-17T18:51:21Z","created_by":"Bruno Postle","updated_at":"2026-06-17T21:50:34Z","started_at":"2026-06-17T20:19:39Z","closed_at":"2026-06-17T21:50:34Z","close_reason":"Closed","dependencies":[{"issue_id":"homemaker-py-c4c.2","depends_on_id":"homemaker-py-c4c","type":"parent-child","created_at":"2026-06-17T19:51:20Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":0,"dependent_count":3,"comment_count":0}
{"id":"homemaker-py-c4c.1","title":"Experiment: single-storey harbor premise test (per-floor construction vs multi-storey coupling)","description":"De-risk the staged-search and construction work BEFORE building either. Strip harbor-house to its 10 level-0 rooms as a single-storey programme; run the current memetic search from a bare plot; record best fails/score and the fail-type histogram. This isolates the question: is the bottleneck per-floor CONSTRUCTION (placing the right room set on one floor) or the multi-storey COUPLING (deltas, core alignment, level constraints)?\n- If single-storey 10-room reaches near-zero fails: the difficulty is coupling -\u003e staged per-floor search (homemaker-py-\u003cstaging\u003e) is the high-value lever.\n- If it still stalls at many fails (esp. 'missing'): per-floor construction itself is the bottleneck -\u003e programme-aware construction (homemaker-py-\u003cconstruction\u003e) is required first and staging alone won't rescue it.\nRun from blank-slate (init.dom equivalent) AND from a bootstrap population; report both.","design":"Build examples/harbor-house-l0/ from harbor's level-0 spaces only (drop level: keys or set all to 0; keep adjacency among the retained codes). Reuse experiments/run_search_scaled.py harness. Cheap (~minutes at native-fitness throughput).","acceptance_criteria":"Single-storey 10-room harbor variant created and committed under examples/; current search run and best fails/score + fail histogram recorded in DESIGN.md (new §11.x) and bead notes; explicit verdict on construction-vs-coupling.","notes":"VERDICT: per-floor CONSTRUCTION is the bottleneck, not multi-storey coupling.\nBuilt examples/harbor-house-l0/ (10 explicit level:0 codes = 13 room instances, single-storey constraints), seeded from bare init.dom.\nRun: URB_NO_OCCLUSION=1 python3 experiments/run_search_scaled.py examples/harbor-house-l0 20000 0 examples/harbor-house-l0/init.dom examples/harbor-house-l0/generated.dom\nResult: 20000 evals / 250 topologies / 234s. Best 33 fails (fitness 2.25e-12, deep in 0.5^n regime); whole pop stuck 33-35. 40-\u003e33 over full budget. NOT near zero.\nFail histogram: 13 missing (all 3 m meeting rooms never built) + 6 adjacency + 4 access + 4 size + 2 edge-too-long + 2 crinkliness + 1 proportion + 1 too-few-stairs(single-storey artifact). Missing = 39% — matches the 'still stalls esp. missing' branch.\n=\u003e c4c.2 (programme-aware construction + missing-room repair) is the prerequisite; staging (c4c.3) alone won't rescue it. c4c.3 already correctly depends on both. Full writeup in DESIGN.md §11.1.","status":"closed","priority":1,"issue_type":"task","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-17T18:49:43Z","created_by":"Bruno Postle","updated_at":"2026-06-17T20:15:36Z","started_at":"2026-06-17T19:25:49Z","closed_at":"2026-06-17T20:15:36Z","close_reason":"Closed","dependencies":[{"issue_id":"homemaker-py-c4c.1","depends_on_id":"homemaker-py-c4c","type":"parent-child","created_at":"2026-06-17T19:49:43Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":0,"dependent_count":1,"comment_count":0}
{"id":"homemaker-py-c4c","title":"Phase 6: topology-search quality for full/multi-storey programmes","description":"Diagnosis (survey 2026-06-17): the delivered speedups (native fitness ~140x, geometry inner loop ~1.6x) landed in the two layers that were never the bottleneck. The geometry inner loop polishes WITHIN a failure tier (DESIGN.md §4.5/§4.7: 0 fail changes, by design — the 0.5^n cliff protects it). But final design quality is dominated by FAILURE COUNT, which is almost entirely a topology property. Topology search on full programmes is the weakness:\n- blank-slate programme-house (init.dom): memetic stalls at 18 fails vs urb-evolve 6 (§7 Phase 2 verdict);\n- harbor-house (16 rooms): out1.dom=74 fails, generated.dom=130 fails, both at ~machine-epsilon score; fails dominated by 'missing' room stacking (each missing room stacks critical+size+width+adjacency+level, §6).\nSmoking gun: operators.mutate_divide (operators.py:71) assigns each new leaf a RANDOM type from programme-codes+C+O. Nothing guarantees the required programme spaces are instantiated, so on a large programme required rooms go missing -\u003e catastrophic 0.5^n stacking, and the search is a random walk over type assignments with a flat/catastrophic gradient in the high-fail regime.\nThis epic groups the topology-search-quality work: programme-aware construction, staged per-floor search, graded high-fail objective, topology diversity, then the canonical-encoding capstone. Everything experiment-driven; results recorded in DESIGN.md sections + bead notes.","design":"Causal frame: base-floor tree is the master genome; upper storeys are divide/undivide deltas (Below-inheritance); the programme partitions rooms by required level (harbor: 10 on L0, 4 on L1, 2 free). So construction and search should follow the genome's dependency order: credible base floor first, upper floors as deltas, with required-room sets known per floor from the programme. Do NOT hard-freeze the base when adding floors — that recreates the §4.2 partial-objective trap at the topology level (a base optimised purely as ground floor can be a bad SUBSTRATE: vertical core must stay aligned, load-bearing walls must stack). Curriculum, not freeze.","acceptance_criteria":"Memetic search reaches a competitive low-fail design on harbor-house (16 rooms, multi-storey) and on blank-slate programme-house, beating the current 74/18-fail plateaus; each child bead lands its experiment with results recorded in DESIGN.md.","status":"open","priority":1,"issue_type":"epic","owner":"bruno@postle.net","created_at":"2026-06-17T18:45:39Z","created_by":"Bruno Postle","updated_at":"2026-06-17T18:45:39Z","dependency_count":0,"dependent_count":0,"comment_count":0}
@ -38,16 +38,16 @@
{"id":"homemaker-py-can","title":"Programme width defaults: t3 contradiction (impossible width_inside default)","description":"DESIGN.md §8.2, confirmed in source. t3 (3 m2 WC) has no width spec so inherits width_inside [4.0, 1.0] (Fitness/Base.pm:60) — geometrically impossible; designs 'pass' only by failing size instead. Fix AFTER faithful-port validation (port-faithfully-first policy, §8.1): a sane width default scaled to area (e.g. sqrt(area/proportion)) or per-room widths in patterns.config. Applies to native fitness; optionally upstream to Urb.","acceptance_criteria":"No programme space has a default width incompatible with its target area; corpus re-scored and effect documented","status":"closed","priority":3,"issue_type":"bug","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-11T23:39:01Z","created_by":"Bruno Postle","updated_at":"2026-06-13T21:21:37Z","started_at":"2026-06-13T21:16:11Z","closed_at":"2026-06-13T21:21:37Z","close_reason":"Fixed in get_space_params: when a programme space has no explicit 'width', derive target from sqrt(size/proportion) instead of falling back to width_inside [4.0, 1.0]. Re-scored 35-file corpus: 32 files improved (+1-121%), 5 files lost spurious width fails. All 109 tests pass. Upstream Perl fix tracked as homemaker-py-8fe.","dependencies":[{"issue_id":"homemaker-py-can","depends_on_id":"homemaker-py-uxz","type":"blocks","created_at":"2026-06-12T00:39:47Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"id":"homemaker-py-yg5","title":"Penalty reshaping: replace 0.5^n while preserving inner-loop protection","description":"DESIGN.md §4.7, §5.4, §7 Phase 4, §8.5. The 0.5^n cliff gives the outer search no gradient and rewards flag-count over geometry, but it also PROTECTS the inner loop from trading into new failures (§4.5). One fitness shape cannot naively be both soft outside and cliff-protected inside. Candidates: cliff-inside-inner-loop only, lexicographic (failure count first, score second), additive/soft, multi-objective Pareto. Must preserve the missing-space failure hierarchy (worse to drop a room than to have a poor one). Measure landscape + search outcomes; this helps Urb today too.","acceptance_criteria":"Chosen scheme documented with measurements: search improves while inner loop still never trades into new failures","status":"closed","priority":3,"issue_type":"feature","assignee":"Bruno Postle","owner":"bruno@postle.net","created_at":"2026-06-11T23:39:00Z","created_by":"Bruno Postle","updated_at":"2026-06-14T08:16:14Z","started_at":"2026-06-14T07:55:32Z","closed_at":"2026-06-14T08:16:14Z","close_reason":"Implemented lexicographic outer-search comparison (-n_fails, fitness). Inner loop unchanged (0.5^n cliff protection preserved). Experiment penalty_reshape.py confirms 0/9 fail regressions in inner loop and shows lex avoids the 3-fail trap that scalar hits 1/3 of the time. Fixed stale _CHILD_INNER_KW sigmas entry.","dependencies":[{"issue_id":"homemaker-py-yg5","depends_on_id":"homemaker-py-uxz","type":"blocks","created_at":"2026-06-12T00:39:46Z","created_by":"Bruno Postle","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"id":"homemaker-py-2g5","title":"Rebuild occlusion/daylight/sun subsystem in Python (post-Phase-5, after optimisation fully native)","description":"DESIGN.md §6 port scope — a whole subsystem, not a term. quality_daylight (Leaf.pm:281-296) needs Urb::Misc::Sun + Urb::Field::Occlusion (+CIESky); quality_uncrinkliness also takes the occlusion object. Indoor spaces return 1 for daylight; cost is outdoor spaces + crinkliness. Port Sun_horizontal (262980-minute normalisation) and the occlusion wall set from Dom-\u003eWalls.","acceptance_criteria":"Daylight and crinkliness factors match Perl (float tolerance) across the corpus, including multi-storey cases","notes":"Re-scoped 2026-06-12: occlusion disabled in the Urb oracle instead of ported (see homemaker-py-gp2). Native fitness ships with simple crinkliness (illumination factor = 1, in homemaker-py-gnw). This issue is now the eventual Python occlusion rebuild, only after optimisation works entirely in Python. Restores outdoor-daylight and shaded-wall selection pressure.\nReframed 2026-06-17: orthogonal to epic homemaker-py-c4c. This is fitness FIDELITY (restoring daylight + shaded-wall selection pressure to match Perl), not search CAPABILITY — it changes what 'good' means, not the search's ability to find good. It will NOT improve final designs in the sense currently sought. Stays P4, deferred until the topology-search-quality epic lands and optimisation is fully native.","status":"open","priority":4,"issue_type":"feature","owner":"bruno@postle.net","created_at":"2026-06-11T23:38:25Z","created_by":"Bruno Postle","updated_at":"2026-06-17T19:14:48Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"memory","key":"deceptive-valleys-in-topology-search-when-every-single","value":"Deceptive valleys in topology search: when every single-step mutation from a target state passes through a high-fail intermediary (e.g. level_fix displaces a room into 5+ new fails), a compound operator that atomically applies two coordinated changes can escape. Design compound operators to land on the low-fail state directly, bypassing the deceptive gradient. Programme-house example: level_compound_fix atomically moves the level-constrained room AND re-inserts the displaced room adjacent to C in one step (operators.py, 2026-06-14)."}
{"_type":"memory","key":"correction-to-urb-fitness-bug-memory-bruno-2026","value":"CORRECTION to urb-fitness-bug memory (Bruno, 2026-06-12): 'C' is NOT a 'covered' type — Is_Covered is a geometric predicate (indoor space above). Urb's generic types are canonically UPPERCASE: C=circulation, O=outside, S=sahn (get_space_types qw/C O S/; corpus is 100% uppercase, never 'c'/'o' leaves). The mixed-case designs that fired the latent ratio_type first-match bug were created by homemaker's own operator type pool emitting lowercase 'c'/'o' — fixed: driver/operators now emit uppercase generics only, and class checks use t[0].lower() in 'cos'. The Urb class-sum patch stays as defensive hardening (zero impact on canonical designs). Native port (3y7/gnw): treat type classes case-insensitively, generics canonically uppercase."}
{"_type":"memory","key":"homemaker-py-pythonpath-set-pythonpath-home-bruno-src","value":"homemaker-layout PYTHONPATH: package installed as 'homemaker-layout' via pip install -e . so 'import homemaker_layout' works from anywhere without PYTHONPATH. For running tests use 'python -m pytest' from project root /home/bruno/src/homemaker-layout (pyproject.toml adds src/ automatically). Never try pip show homemaker — that's the old homemaker-addon conflict."}
{"_type":"memory","key":"multi-storey-staircase-consistency-when-dividing-or-retyping","value":"Multi-storey staircase consistency: when dividing or retyping a circulation (C) leaf at one level, the same structural change should be propagated to the matching leaf on ALL other storeys so the stair core path is maintained. The optimizer cannot fix staircase disruptions through trial-and-error geometry alone — it requires a synchronized multi-level operator that applies the same topology change to every storey simultaneously."}
{"_type":"memory","key":"warm-x0-initialization-bug-pattern-when-a-topology","value":"warm_x0 initialization bug pattern: when a topology operator explicitly sets division ratios on a newly-created node (e.g. compound_fix sets node.division=[0.25,0.25] for t3), parent.ratios has no entry for that node (it was a leaf). warm_x0 defaults it to 0.5, corrupting the inner loop's starting point and making the operator invisible to lex comparison. Fix: only propagate child ratios for nodes where the parent node was NOT already divided; stale hidden nodes revealed by structural mutations (swap flipping b.below) must NOT contribute their pre-writeback values. See driver.py lines 259-267 (fixed 2026-06-14)."}
{"_type":"memory","key":"urb-oracle-nondeterminism-urb-fitness-pl-output-varies","value":"Urb oracle nondeterminism: urb-fitness.pl output varies run-to-run from Perl hash-order randomisation — .fails line ORDER shuffles (compare sorted, use oracle.Score.fail_lines) and the score float can flip by ~1 ULP (compare with math.isclose rel_tol=1e-12, never ==). Not a batching artifact; affects single runs too. Matters for the Phase 3 native-fitness parity gate (homemaker-py-uxz)."}
{"_type":"memory","key":"adjacency-in-binary-slicing-tree-is-structural-not","value":"Adjacency in binary slicing tree is structural, not geometric: the inner-loop NM cannot fix topological adjacency failures. Two paths exist: (1) tree-sibling adjacency — a node is adjacent to its sibling in the tree; (2) cross-zone geometric adjacency — leaves from different subtrees that happen to share a boundary. Staircase/adjacency fails require a topology mutation that changes which nodes are siblings or which zones touch. This was proved empirically on programme-house: staircase fail from rot=0 layout could not be fixed by NM but was fixed by level_retype creating a two-C topology (2026-06-14/15)."}
{"_type":"memory","key":"cli-tool-style-prefer-python-m-homemaker-module","value":"CLI tool style: prefer python -m homemaker.module --parameters pattern, installable via pip install -e . with pyproject.toml entry_points. Not standalone bin/ scripts."}
{"_type":"memory","key":"urb-fitness-bug-found-fixed-2026-06-12","value":"Urb fitness bug found+fixed 2026-06-12 (patch in /home/bruno/src/urb, uncommitted): ProgrammeDriven.pm ratio_o/ratio_type grepped case-insensitively over the ratios hash and took the FIRST key — nondeterministic (x4.5 score swings) for designs with mixed-case type classes (both 'c' circulation and 'C' covered). Fixed to SUM the class (matches Is_Circulation//Is_Outside semantics); 35/35 corpus scores unchanged. CRITICAL for homemaker-py-3y7/gnw: the native port must implement class-SUM ratios. Building.pm has the same unpatched pattern (site-driven path, not used by our oracle). Also: the memetic search reward-hacked this bug before the fix — search results predating it are noise artifacts."}
{"_type":"memory","key":"user-preference-bruno-this-is-a-fedora-system","value":"User preference (Bruno): this is a Fedora system — NEVER install Python packages via pip without asking first; always ask whether to install the rpm via dnf (e.g. python3-cma) before considering pip. Applies to any dependency additions."}
{"_type":"memory","key":"warm-x0-initialization-bug-pattern-when-a-topology","value":"warm_x0 initialization bug pattern: when a topology operator explicitly sets division ratios on a newly-created node (e.g. compound_fix sets node.division=[0.25,0.25] for t3), parent.ratios has no entry for that node (it was a leaf). warm_x0 defaults it to 0.5, corrupting the inner loop's starting point and making the operator invisible to lex comparison. Fix: only propagate child ratios for nodes where the parent node was NOT already divided; stale hidden nodes revealed by structural mutations (swap flipping b.below) must NOT contribute their pre-writeback values. See driver.py lines 259-267 (fixed 2026-06-14)."}
{"_type":"memory","key":"deceptive-valleys-in-topology-search-when-every-single","value":"Deceptive valleys in topology search: when every single-step mutation from a target state passes through a high-fail intermediary (e.g. level_fix displaces a room into 5+ new fails), a compound operator that atomically applies two coordinated changes can escape. Design compound operators to land on the low-fail state directly, bypassing the deceptive gradient. Programme-house example: level_compound_fix atomically moves the level-constrained room AND re-inserts the displaced room adjacent to C in one step (operators.py, 2026-06-14)."}
{"_type":"memory","key":"never-use-corpus-filenames-candidate-001-dom-candidate","value":"Never use corpus filenames (candidate-001.dom, candidate-002.dom, generated.dom, init.dom, etc.) as --output targets when running experiments. These are test fixtures. Always write experimental outputs to scratch/ or a timestamped path. Lesson from 2026-06-14: warm-start runs overwrote candidate-001/002.dom and broke graph tests."}
{"_type":"memory","key":"strategy-decision-2026-06-12-bruno-occlusion-daylight","value":"Strategy decision 2026-06-12 (Bruno): occlusion/daylight is ORTHOGONAL to building a scalable optimiser. Disable it in Urb (env flag, homemaker-py-gp2) rather than port it; native fitness uses simple crinkliness (illumination factor = 1); rebuild occlusion in Python only after optimisation is fully native (homemaker-py-2g5, now P4). Consequence: all scores change when the flag flips — re-baseline corpus/.score, DESIGN \\$4.5 gains, gate bars at one clean boundary AFTER homemaker-py-1p0 closes; Phase-2 urb-evolve benchmark must run with the same flag."}
{"_type":"memory","key":"programme-house-optimisation-result-2026-06-14-15","value":"Programme-house optimisation result (2026-06-14/15): best achievable is 1 fail (l1 wrong level, score ~0.005). 0 fails is geometrically impossible: l1 (min 27m²) must occupy ll (~23m²) at level 0, which eliminates the t3-adj-C provider; dividing ll into lll(l1)+llr(C) gives llr proportion ~6:1 (fails). Python memetic optimizer achieves 1 fail in 50k evals vs Perl optimiser's 2-3 fails. Winning topology: TWO C nodes at level 0 — ll(C) for t3-adj-C via geometric contact, rl(C) for staircase via tree-sibling adjacency to rrr(O). Best .dom: scratch/from-warmstart-fixed.dom and scratch/from-compound3-fixed.dom."}
{"_type":"memory","key":"user-preference-bruno-this-is-a-fedora-system","value":"User preference (Bruno): this is a Fedora system — NEVER install Python packages via pip without asking first; always ask whether to install the rpm via dnf (e.g. python3-cma) before considering pip. Applies to any dependency additions."}
{"_type":"memory","key":"correction-to-urb-fitness-bug-memory-bruno-2026","value":"CORRECTION to urb-fitness-bug memory (Bruno, 2026-06-12): 'C' is NOT a 'covered' type — Is_Covered is a geometric predicate (indoor space above). Urb's generic types are canonically UPPERCASE: C=circulation, O=outside, S=sahn (get_space_types qw/C O S/; corpus is 100% uppercase, never 'c'/'o' leaves). The mixed-case designs that fired the latent ratio_type first-match bug were created by homemaker's own operator type pool emitting lowercase 'c'/'o' — fixed: driver/operators now emit uppercase generics only, and class checks use t[0].lower() in 'cos'. The Urb class-sum patch stays as defensive hardening (zero impact on canonical designs). Native port (3y7/gnw): treat type classes case-insensitively, generics canonically uppercase."}
{"_type":"memory","key":"homemaker-py-pythonpath-set-pythonpath-home-bruno-src","value":"homemaker-layout PYTHONPATH: package installed as 'homemaker-layout' via pip install -e . so 'import homemaker_layout' works from anywhere without PYTHONPATH. For running tests use 'python -m pytest' from project root /home/bruno/src/homemaker-layout (pyproject.toml adds src/ automatically). Never try pip show homemaker — that's the old homemaker-addon conflict."}
{"_type":"memory","key":"urb-fitness-bug-found-fixed-2026-06-12","value":"Urb fitness bug found+fixed 2026-06-12 (patch in /home/bruno/src/urb, uncommitted): ProgrammeDriven.pm ratio_o/ratio_type grepped case-insensitively over the ratios hash and took the FIRST key — nondeterministic (x4.5 score swings) for designs with mixed-case type classes (both 'c' circulation and 'C' covered). Fixed to SUM the class (matches Is_Circulation//Is_Outside semantics); 35/35 corpus scores unchanged. CRITICAL for homemaker-py-3y7/gnw: the native port must implement class-SUM ratios. Building.pm has the same unpatched pattern (site-driven path, not used by our oracle). Also: the memetic search reward-hacked this bug before the fix — search results predating it are noise artifacts."}
{"_type":"memory","key":"urb-oracle-nondeterminism-urb-fitness-pl-output-varies","value":"Urb oracle nondeterminism: urb-fitness.pl output varies run-to-run from Perl hash-order randomisation — .fails line ORDER shuffles (compare sorted, use oracle.Score.fail_lines) and the score float can flip by ~1 ULP (compare with math.isclose rel_tol=1e-12, never ==). Not a batching artifact; affects single runs too. Matters for the Phase 3 native-fitness parity gate (homemaker-py-uxz)."}