Owner's daylight ruling: corridors need it; retract the 61% headline
Ruling: corridors need daylight. Only rooms not occupied from day to day --
a cupboard, a store, a plant room -- do without it.
That overturns the classification 38.8 and 38.9 rested on. Those sections
exempted internal circulation, covered courtyards, WCs, laundries and
reception on my inference rather than any ruling. None are exempt: a
corridor is occupied all day every day, a waiting room likewise, a laundry
is a room people spend time in, a sterilisation room is a workplace.
Re-measured with the classification READ FROM THE CORPUS (a space is exempt
exactly when its own patterns.config declares crinkliness: none) instead of
inferred: 24 of 271 crinkliness fails (9%) were not defects -- not 136
(50%), not 61%. Overstated by about six times.
- uncrinkliness_circulation stays at [5/6, 1.1/3]. 38.10 called its
equality with the habitable target the purest case of an untuned value;
it is not a bug, it is the correct answer reached by default, since
corridors want daylight on the same terms as rooms.
- corpus declarations narrowed 18 -> 14. usage: utility was too coarse and
swept in Laundry Rooms and a Sterilisation Room. What remains is
storage, plant/mechanical, utilities closets and a records room.
- audit_crinkliness_truth.py rebuilt to read the classification from the
configs rather than infer it from usage:, so it cannot drift from the
ruling again.
- 38.8/38.9's inflated figures flagged in place, with 38.11 carrying the
correction.
What survives, none of it dependent on the classification: the 38.6
critique of the three modes; usage_daylight being mis-keyed; the 38.8 A/B
yardstick being wrong; and the per-space crinkliness mechanism itself.
ssz's opening measurement was right but its reading was wrong -- under this
ruling a buried leaf usually IS a defect, so scoring it zero is largely
correct. The narrowed remnant is that the score is FLAT rather than low, so
two equally-buried layouts cannot be ranked. Filed as homemaker-py-9gj; it
is a search-mechanics problem, not a calibration one.
Lint at parity (46); tests 369 passed, 2 pre-existing failures (ut5's stale
baseline and 1ue), both failing identically before this change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJ84Feep79Hhm3E4zZJmnB
This commit is contained in:
parent
31d50ba72b
commit
c9b9eafef6
7 changed files with 127 additions and 35 deletions
File diff suppressed because one or more lines are too long
92
DESIGN.md
92
DESIGN.md
|
|
@ -5156,8 +5156,9 @@ sits in?
|
|||
| maple-court | 46 | 13 (28%) | **33 (72%)** |
|
||||
| health-centre | 18 | 9 (50%) | 9 (50%) |
|
||||
|
||||
**Roughly two thirds of the zero-value leaves are spaces that architecturally
|
||||
do not want a window at all** — a broom cupboard, a WC, a plant room, an
|
||||
**RETRACTED, see §38.11 — the real share is under a tenth.** As written this
|
||||
claimed that roughly two thirds of the zero-value leaves are spaces that
|
||||
architecturally do not want a window at all — a broom cupboard, a WC, a plant room, an
|
||||
internal corridor, a covered courtyard. The objective scores them identically
|
||||
with a windowless bedroom. That is the miscalibration, and it is not a gradient
|
||||
problem to be patched with an epsilon; it is the wrong requirement applied to
|
||||
|
|
@ -5255,8 +5256,14 @@ leaf's declared usage:
|
|||
| maple-court `generated.dom` (evolved) | 67 | 43 (64%) |
|
||||
| **overall** | **271** | **164 (61%)** |
|
||||
|
||||
**61% of the crinkliness failures the objective reports are not defects**, and
|
||||
it holds on evolved artefacts, not just seeds. Under
|
||||
**RETRACTED — the true figure is 9%, see §38.11.** The table above classifies a
|
||||
fail as a non-defect using `usage:`, exempting corridors, WCs, laundries and
|
||||
reception; the owner exempts none of those. Only rooms not occupied from day to
|
||||
day — a cupboard, a store, a plant room — do without daylight. The paragraph as
|
||||
written said:
|
||||
|
||||
> **61% of the crinkliness failures the objective reports are not defects**, and
|
||||
> it holds on evolved artefacts, not just seeds. Under
|
||||
`value *= 0.5 ** len(failures)` every one of them halves the fitness of a design
|
||||
that has done nothing wrong — a design is punished for putting the store in the
|
||||
middle of the plan, which is what a competent architect does. That is a
|
||||
|
|
@ -5334,8 +5341,8 @@ programme-house has no utility spaces).
|
|||
|
||||
| | crinkliness fails | not defects |
|
||||
|---|---|---|
|
||||
| before | 271 | 136 (50%) |
|
||||
| after the utility declarations | **243** | 108 (44%) |
|
||||
| before | 271 | ~~136 (50%)~~ **24 (9%)** — see §38.11 |
|
||||
| after the declarations | **247** | **0** |
|
||||
|
||||
The 28 that went are exactly the utility fails. What remains is two populations
|
||||
the corpus cannot reach, because neither is a `spaces:` entry:
|
||||
|
|
@ -5354,6 +5361,79 @@ settable to `none` like any space (tested), but the default is deliberately
|
|||
on, and this is 63% of the remaining phantom fails, so it is not a call to make
|
||||
by inference.
|
||||
|
||||
### 38.11 Owner's ruling on daylight, and the retraction of §38.8's headline
|
||||
|
||||
**Ruling: corridors need daylight. Only rooms that are not occupied from day to
|
||||
day — a cupboard, a store, a plant room — do without it.**
|
||||
|
||||
That overturns the classification §38.8 and §38.9 were built on, and with it
|
||||
their headline number. Those sections exempted, on my inference rather than any
|
||||
ruling: internal circulation, covered courtyards, WCs and bathrooms, laundries,
|
||||
and reception/waiting/foyer. **None of those are exempt.** A corridor is
|
||||
occupied all day, every day; so is a waiting room; a laundry is a room people
|
||||
spend time in; a sterilisation room is a workplace.
|
||||
|
||||
Re-measured against the ruling, with the classification read from the corpus
|
||||
(a space is exempt exactly when its own `patterns.config` declares
|
||||
`crinkliness: none`) rather than inferred:
|
||||
|
||||
| layout | crinkliness fails | not defects |
|
||||
|---|---|---|
|
||||
| harbor-house, 3 constructed seeds | 67 | 8 (12%) |
|
||||
| maple-court, 3 constructed seeds | 112 | 9 (8%) |
|
||||
| health-centre, 3 constructed seeds | 20 | 2 (10%) |
|
||||
| harbor-house `generated.dom` (evolved) | 5 | 1 (20%) |
|
||||
| maple-court `generated.dom` (evolved) | 67 | 4 (6%) |
|
||||
| **overall** | **271** | **24 (9%)** |
|
||||
|
||||
**9%, not 61%.** The objective's daylight requirement was mildly miscalibrated,
|
||||
not massively so, and I overstated it by a factor of about six by inventing a
|
||||
classification instead of asking for one.
|
||||
|
||||
**`uncrinkliness_circulation` is therefore left at `[5/6, 1.1/3]`.** §38.10
|
||||
called its equality with the habitable target "the purest case of a value never
|
||||
tuned". It is not a bug: corridors want daylight on the same terms as rooms, so
|
||||
the two targets agreeing is the correct answer, arrived at by default. The key
|
||||
stays available for a programme that wants to differ.
|
||||
|
||||
**The corpus declarations are narrowed to match.** `usage: utility` was too
|
||||
coarse a proxy — it swept in Laundry Rooms and a Sterilisation Room, all of
|
||||
which are occupied. 14 spaces now declare `crinkliness: none`, and every one is
|
||||
genuinely unoccupied:
|
||||
|
||||
| programme | declared `crinkliness: none` |
|
||||
|---|---|
|
||||
| harbor-house | Ground/First Floor Storage, Mechanical/Electrical Room, Utilities Closet |
|
||||
| harbor-house-l0 | Ground Floor Storage, Mechanical/Electrical Room |
|
||||
| health-centre | General Storage, Plant / Mechanical Room, Records Room |
|
||||
| maple-court | Ground/First/Second Floor Storage, Mechanical/Electrical Room, Utilities Closet |
|
||||
|
||||
*(Records Room is the one debatable entry — a store you fetch a file from, not a
|
||||
desk. Flip it to a declared target if it is meant to be worked in.)*
|
||||
|
||||
**What survives §38.8/§38.9 unchanged**, because none of it depended on the
|
||||
classification:
|
||||
|
||||
- the §38.6 critique. `floor` returns 0.01 for a buried leaf, `compact_ok`
|
||||
contradicted itself, and `exempt_circulation` reached a third at most. Those
|
||||
are facts about the code, and they are why §38.6 measured a null;
|
||||
- `usage_daylight` was mis-keyed. §38.9's reasoning for that was right even
|
||||
though its numbers were not — `usage:` is an access axis;
|
||||
- the §38.8 A/B's yardstick was wrong: scoring the repair under the objective
|
||||
it repairs penalises it for repairing;
|
||||
- the mechanism. Crinkliness was the only leaf quality factor with no per-space
|
||||
target, and §38.10's fix stands on the owner's design, not on my numbers.
|
||||
|
||||
**What this does to `ssz` as a whole.** The issue opened on "45–56% of interior
|
||||
leaves are zero-exposure and score a hard zero, so the objective assigns no
|
||||
value to any interior room". That measurement was right, but the reading was
|
||||
wrong: under this ruling **a buried leaf usually IS a defect**, corridors and
|
||||
WCs included, so scoring it zero is largely *correct*. What remains of the
|
||||
complaint is narrower and is about search mechanics rather than truth — a hard
|
||||
`0.0` cannot rank two bad layouts against each other, so the objective is
|
||||
flat where it should be merely low. That is worth a separate issue; it is not
|
||||
the calibration fault this section spent its length chasing.
|
||||
|
||||
## 39. Config audit: requirements that actively fight the engine (`homemaker-py-ju3`) — measured 2026-08-25
|
||||
|
||||
The corpus `patterns.config` targets and `costs.config` values were estimated
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ spaces:
|
|||
count: 3
|
||||
|
||||
la1:
|
||||
crinkliness: none # no window needed
|
||||
usage: utility
|
||||
name: Laundry Room
|
||||
size:
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ spaces:
|
|||
count: 6 # 3 ground + 3 first floor
|
||||
|
||||
la1:
|
||||
crinkliness: none # no window needed
|
||||
usage: utility
|
||||
name: Laundry Room
|
||||
size:
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ spaces:
|
|||
- ms1
|
||||
|
||||
zt1:
|
||||
crinkliness: none # no window needed
|
||||
usage: utility
|
||||
name: Sterilisation Room
|
||||
size:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ spaces:
|
|||
- o
|
||||
|
||||
la1:
|
||||
crinkliness: none # no window needed
|
||||
usage: utility
|
||||
name: Laundry Room
|
||||
size:
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
"""Are the crinkliness failures the objective emits real defects? (`homemaker-py-ssz`)
|
||||
|
||||
Not an A/B. This asks a correctness question the search cannot answer: of the
|
||||
`crinkliness` failures the STOCK objective reports, how many are on a space
|
||||
that architecturally wants daylight at all?
|
||||
`crinkliness` failures the GLOBAL-target objective reports -- one daylight
|
||||
requirement for every space, which is what the engine did before §38.10 -- how
|
||||
many are on a space that does not want daylight at all?
|
||||
|
||||
A `crinkliness` fail says "this leaf has too little exposed wall for its area".
|
||||
For a bedroom or a living room that is a real defect. For a broom cupboard, a
|
||||
WC, a plant room, an internal corridor or a covered courtyard it is not -- those
|
||||
are ordinary buried architecture, and the fail is an artefact of applying one
|
||||
daylight requirement to every space regardless of use (DESIGN.md §38.8).
|
||||
For anything occupied day to day that is a real defect. For a cupboard, a store
|
||||
or a plant room it is not.
|
||||
|
||||
Every fail is classified by the leaf's DECLARED `usage:` (§39.7), so nothing
|
||||
here rests on how a code is spelled.
|
||||
**The classification is read from the corpus, not guessed here.** A fail counts
|
||||
as a non-defect exactly when that space declares `crinkliness: none` in its own
|
||||
`patterns.config`. An earlier version of this script inferred it from `usage:`
|
||||
instead and got a much larger, wrong answer -- it exempted corridors, WCs,
|
||||
laundries and reception, none of which the owner exempts (DESIGN.md §38.11).
|
||||
Corridors, courtyards and every occupied room want daylight.
|
||||
|
||||
Usage::
|
||||
|
||||
|
|
@ -36,12 +39,11 @@ from homemaker_layout import operators, programme
|
|||
|
||||
CORPUS = ["examples/harbor-house", "examples/maple-court", "examples/health-centre"]
|
||||
|
||||
# Ruled by the project owner: everything a person occupies wants a window --
|
||||
# WCs and bathrooms included, reception/waiting/foyer included, offices and
|
||||
# consulting rooms included. Only stores, plant, records and laundry do not,
|
||||
# together with the generic structural types (a corridor has its own
|
||||
# `uncrinkliness_circulation` target; a courtyard is not a room).
|
||||
NO_DAYLIGHT = {"utility"}
|
||||
# Ruled by the project owner: only rooms that are not occupied from day to day
|
||||
# -- a cupboard, a store, a plant room -- do without daylight. Corridors need
|
||||
# it. So does everything else: WCs, laundries, reception, waiting rooms,
|
||||
# offices, consulting rooms. Which spaces those are is read from the configs
|
||||
# themselves (a declared `crinkliness: none`), never inferred here.
|
||||
|
||||
|
||||
def stock_fitness(progdir: str) -> fitness.Fitness:
|
||||
|
|
@ -64,7 +66,12 @@ def constructed(progdir: str, s: int) -> dom_mod.Node:
|
|||
|
||||
|
||||
def audit(fit: fitness.Fitness, root: dom_mod.Node) -> collections.Counter:
|
||||
"""usage -> count, over the leaves that emit a stock `crinkliness` fail."""
|
||||
"""label -> count over the leaves that fail under ONE GLOBAL daylight target.
|
||||
|
||||
Each is labelled with the leaf's usage, and marked exempt when that space
|
||||
declares `crinkliness: none` -- i.e. when the failure the old objective
|
||||
emitted was not a defect.
|
||||
"""
|
||||
tree = copy.deepcopy(root)
|
||||
geometry.clear_cache()
|
||||
dom_mod.canonicalize_shares(tree)
|
||||
|
|
@ -79,25 +86,33 @@ def audit(fit: fitness.Fitness, root: dom_mod.Node) -> collections.Counter:
|
|||
for leaf in lvl.leaves():
|
||||
if dom_mod.is_outside(leaf) and not dom_mod.is_covered(leaf):
|
||||
continue
|
||||
if fit.quality_uncrinkliness(leaf, graphs[li], groups) >= fitness.FAIL_THRESHOLD:
|
||||
continue # not a failure
|
||||
out[fit.usage_of(leaf) or f"<generic {leaf.type}>"] += 1
|
||||
# the PRE-§38.10 objective: one global target for every leaf
|
||||
crink = fit.crinkliness(leaf, graphs[li], groups)
|
||||
if crink:
|
||||
distance, sigma = fit.conf("uncrinkliness")
|
||||
q = fitness.gaussian(1 / crink, 1.0, distance, sigma)
|
||||
else:
|
||||
q = 0.0
|
||||
if q >= fitness.FAIL_THRESHOLD:
|
||||
continue # not a failure even then
|
||||
label = fit.usage_of(leaf) or f"<generic {leaf.type}>"
|
||||
if fit.crinkliness_params(leaf) is None:
|
||||
label += " [declares crinkliness: none]"
|
||||
out[label] += 1
|
||||
return out
|
||||
|
||||
|
||||
def report(label: str, tally: collections.Counter) -> tuple[int, int]:
|
||||
total = sum(tally.values())
|
||||
real = sum(n for u, n in tally.items() if u not in NO_DAYLIGHT
|
||||
and not u.startswith("<generic"))
|
||||
real = sum(n for u, n in tally.items() if "crinkliness: none" not in u)
|
||||
print(f"=== {label}: {total} crinkliness fails")
|
||||
if not total:
|
||||
print(" none\n")
|
||||
return 0, 0
|
||||
for usage, n in tally.most_common():
|
||||
exempt = usage in NO_DAYLIGHT or usage.startswith("<generic")
|
||||
verdict = ("not a defect -- no daylight wanted" if exempt
|
||||
else "REAL DEFECT")
|
||||
print(f" {usage:<18}{n:>4} {verdict}")
|
||||
verdict = ("not a defect -- not occupied day to day"
|
||||
if "crinkliness: none" in usage else "REAL DEFECT")
|
||||
print(f" {usage:<44}{n:>4} {verdict}")
|
||||
print(f" -> {total - real}/{total} ({100 * (total - real) / total:.0f}%) "
|
||||
f"are reported against spaces that do not want daylight\n")
|
||||
return real, total
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue