Sprint 15 integration: merge all lanes (418/0/0), apply E's world.js manifest patch, [I] entry

This commit is contained in:
type-two 2026-07-20 19:38:11 +10:00
parent e727e49325
commit ed62c7d4be
2 changed files with 43 additions and 0 deletions

View File

@ -7349,3 +7349,36 @@ anchors are your GLB), but the tooling is now waiting, not TODO.
bolted-to-deck option would turn "fascia or nothing" into a real spend-vs-risk decision — bolted-to-deck option would turn "fascia or nothing" into a real spend-vs-risk decision —
the number argues its own case and I'll build against it gladly when SPRINT16 wires the the number argues its own case and I'll build against it gladly when SPRINT16 wires the
swing lawn. swing lawn.
[I] 2026-07-19 — **SPRINT 15 INTEGRATION (main).** All four lanes merged; E's world.js patch applied
verbatim at merge exactly as filed (four hunks, the leadFor precedent — comment in world.js says
so); selftest **418/0/0** on the merged tree, the exact sum D predicted on their scratch (410 +
B 3 + C 3 + E 2), verified in the browser. Game boots clean; posts adopt at ratingHint 1.00
through E's manifest, live in the real chain (D measured p1 committing at eff 3,200 in play —
a 0.90 world would have read 2,880).
**The sprint closed every gate it opened:**
· Gate 1 — ruled 1.00 (shipped value canon), re-baked, mechanism landed (factory manifest →
runtime, ambiguous types refuse to guess, unrated-undenied nodes fail the BUILD), pinned
against the manifest never a literal, and verified zero-delta from THREE directions (B cloth,
C storm, D played). The expensive-sounding gate became cheap because the ruling came first —
sequencing is a tool.
· Gate 2 — the score is iterative and moved nothing (every card byte-identical; MessageChannel
not setTimeout, or Chrome's throttling clamps an occluded run to one flight per minute); ONE
storm picker via a shared store B proposed and C landed converged; D's acceptance verdict is
the receipt: a three-position bed study with predictions before each card, one prediction
wrong IN A RUN instead of in a shipped yard. C's worst-second button predicted the second h3
actually broke in play. "Batch, not iterative" is dead.
· Gate 3 — landed last integration (honest edges), stands.
· Gate 4 — branch RULED by John (all three, sequenced: teeth → sites/clients → heatwaves;
ROADMAP.md is the growth canon). The play half stands open as ever.
Carried forward: B declined the coarse-rank cull as a design change needing a ruling (correct —
it changes card numbers by construction); E's pergola_01 proposal has D's playtester endorsement
("the ladder jumps 0.45-on-grass straight to 1.00-in-concrete; a 0.65 bolted-to-deck mid-rung
turns fascia-or-nothing into a real decision") — TEETH's palette call. D filed their own
harness's fake-Enter artifact so nobody blames A's gate-3.1 work.
**SPRINT16 — TEETH — FIRES NOW: its own header's condition ("fires when 15 integrates") is met,
its pins stand on post-ruling numbers as designed, and the swing lawn is waiting to become a
real night.**

View File

@ -13,6 +13,13 @@
import * as THREE from '../vendor/three.module.js'; import * as THREE from '../vendor/three.module.js';
import { ANCHOR_TYPE, createStubWind } from './contracts.js'; import { ANCHOR_TYPE, createStubWind } from './contracts.js';
// SPRINT15 gate 1.2 — E's patch, applied verbatim by the integrator at merge
// (the leadFor precedent): a node-less anchor takes the factory's word at
// construction, because dress() will never reach it. Object.assign ignores
// null, so each hunk is inert exactly where adoptAnchor already owns the job.
// At the ruled 1.00 this changes ZERO shipped numbers; it exists for the NEXT
// asset. E's e.test pins runtime === manifest so divergence can't be silent.
import { factoryExtras } from './ratings.js';
import { validateSiteWind } from './weather.core.js'; import { validateSiteWind } from './weather.core.js';
/** /**
@ -350,6 +357,7 @@ export function createWorld(scene, opts = {}) {
anchors.push(Object.assign( anchors.push(Object.assign(
makeStaticAnchor(a.id, a.type ?? 'house', new THREE.Vector3(-5 + i * 5, 2.6, -9.9)), makeStaticAnchor(a.id, a.type ?? 'house', new THREE.Vector3(-5 + i * 5, 2.6, -9.9)),
{ work: a.work }, { work: a.work },
a.node ? null : factoryExtras(a.type ?? 'house'),
)); ));
} }
@ -464,6 +472,7 @@ export function createWorld(scene, opts = {}) {
anchors.push(Object.assign( anchors.push(Object.assign(
makeStaticAnchor(spec.id, spec.type ?? 'post', top), makeStaticAnchor(spec.id, spec.type ?? 'post', top),
{ work: spec.work }, { work: spec.work },
spec.node ? null : factoryExtras(spec.type ?? 'post'),
)); ));
} }
@ -532,6 +541,7 @@ export function createWorld(scene, opts = {}) {
anchors.push(Object.assign( anchors.push(Object.assign(
makeStaticAnchor(a.id, a.type ?? 'post', new THREE.Vector3(st.x, heightAt(st.x, st.z) + 2.4, st.z)), makeStaticAnchor(a.id, a.type ?? 'post', new THREE.Vector3(st.x, heightAt(st.x, st.z) + 2.4, st.z)),
{ work: a.work }, { work: a.work },
a.node ? null : factoryExtras(a.type ?? 'post'),
)); ));
} }
} }