Lane B S16: gate 2.3 — separation pins ATTEMPTED and honestly REFUSED, with receipts
Measured post-ruling (garden_probe, funnel ON, 2026-07-20): site_02 x earlybuster: bare 82.6 FULL (hail 10.7 + rain 6.8) · best flown 90.2 · gain +7.6 site_03 x southerly: bare 83.7 FULL (hail 10.7 + rain 5.6) · best flown 89.8 · gain +6.1 Bare WINS both nights by >30 points; 'bareMustLoseBelow' cannot be written honestly at any threshold, so per the gate's own rule this is a FINDING, not a fudged pin. Each yard carries _separation_finding (measured refusal with numbers + the delete-on-pin instruction); scorecard exposes it and SCORE IT's NONE PINNED branch becomes PIN REFUSED (measured). New assert: every shipped yard is separation-JUDGED — pinned XOR refused-with-finding; silence and stale-finding both red. Balance fight filed in THREADS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e5df63128a
commit
458e9a5412
@ -112,6 +112,19 @@ export async function buildGardenflyTests() {
|
|||||||
} catch (err) { sepErr = String((err && err.stack) || err); }
|
} catch (err) { sepErr = String((err && err.stack) || err); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPRINT16 gate 2.3 [B]: every shipped yard has been JUDGED on separation —
|
||||||
|
// either it pins a block (backyard_01) or it records a measured refusal
|
||||||
|
// (_separation_finding). Read all three here so the assert below can hold
|
||||||
|
// the invariant: neither is "unjudged", both at once is a stale finding.
|
||||||
|
let sepStates = null, sepStatesErr = null;
|
||||||
|
try {
|
||||||
|
sepStates = [];
|
||||||
|
for (const name of ['backyard_01', 'site_02_corner_block', 'site_03_swing_lawn']) {
|
||||||
|
const sd = await loadSite(name);
|
||||||
|
sepStates.push({ name, pinned: !!sd.separation, finding: !!sd._separation_finding });
|
||||||
|
}
|
||||||
|
} catch (err) { sepStatesErr = String((err && err.stack) || err); }
|
||||||
|
|
||||||
let venRun = null, venErr = null;
|
let venRun = null, venErr = null;
|
||||||
try {
|
try {
|
||||||
const fly = (venturi) => flyGarden({
|
const fly = (venturi) => flyGarden({
|
||||||
@ -184,6 +197,23 @@ export async function buildGardenflyTests() {
|
|||||||
`the siteDef's venturi is not reaching gardenfly's wind (windForSite must receive the SITE def)`);
|
`the siteDef's venturi is not reaching gardenfly's wind (windForSite must receive the SITE def)`);
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
['gate 2.3: every shipped yard is separation-JUDGED — pinned, or measured-and-refused', () => {
|
||||||
|
// SPRINT16's rule made durable: a yard may pin a separation block or it
|
||||||
|
// may carry a measured refusal (_separation_finding, the honest "this
|
||||||
|
// yard cannot separate at $80 under its storm" verdict with receipts) —
|
||||||
|
// but silence is not an option, and holding both means the finding went
|
||||||
|
// stale the day the pin landed and must be deleted (its own text says so).
|
||||||
|
if (sepStatesErr) throw new Error(`site read died: ${sepStatesErr}`);
|
||||||
|
assert(sepStates.length === 3, `expected 3 shipped yards, read ${sepStates.length}`);
|
||||||
|
for (const s of sepStates) {
|
||||||
|
assert(s.pinned || s.finding,
|
||||||
|
`${s.name} has neither a separation block nor a _separation_finding — the yard is UNJUDGED; ` +
|
||||||
|
'run gardenfly, pin honestly or refuse honestly (SPRINT16 gate 2.3)');
|
||||||
|
assert(!(s.pinned && s.finding),
|
||||||
|
`${s.name} carries BOTH a pin and a refusal finding — the finding is stale, delete it in the pinning commit`);
|
||||||
|
}
|
||||||
|
return sepStates.map((s) => `${s.name}: ${s.pinned ? 'PINNED' : 'refused w/ finding'}`).join(' · ');
|
||||||
|
}],
|
||||||
['gardenfly: default fabric is still the pinned 0.30 cloth, and membrane flies heavier', () => {
|
['gardenfly: default fabric is still the pinned 0.30 cloth, and membrane flies heavier', () => {
|
||||||
if (fabErr) throw new Error(`fabric flight died: ${fabErr}`);
|
if (fabErr) throw new Error(`fabric flight died: ${fabErr}`);
|
||||||
const { byDefault, cloth, membrane } = fabRun;
|
const { byDefault, cloth, membrane } = fabRun;
|
||||||
|
|||||||
@ -243,6 +243,10 @@ export async function scoreSite({ site, stormDef, stormName = null, sepStormDef
|
|||||||
bestGarden: bestGarden ? { ids: bestGarden.key, ...bestGarden.g } : null,
|
bestGarden: bestGarden ? { ids: bestGarden.key, ...bestGarden.g } : null,
|
||||||
bestMarginal: bestMarginal ? { ids: bestMarginal.key, ...bestMarginal.g } : null,
|
bestMarginal: bestMarginal ? { ids: bestMarginal.key, ...bestMarginal.g } : null,
|
||||||
separation, sepStormName, sepUnjudged,
|
separation, sepStormName, sepUnjudged,
|
||||||
|
// SPRINT16 gate 2.3 [B]: a site that ATTEMPTED a pin and honestly refused
|
||||||
|
// one records why in its JSON; the card prints it so NONE PINNED reads as
|
||||||
|
// "measured and refused, here's the fight" rather than "nobody tried".
|
||||||
|
separationFinding: site._separation_finding ?? null,
|
||||||
collateral,
|
collateral,
|
||||||
MARGIN: AUDIT.MARGIN,
|
MARGIN: AUDIT.MARGIN,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,6 +9,21 @@
|
|||||||
|
|
||||||
"gardenBed": { "x": 0, "z": 1, "w": 5, "d": 3.5 },
|
"gardenBed": { "x": 0, "z": 1, "w": 5, "d": 3.5 },
|
||||||
|
|
||||||
|
"_separation_finding": [
|
||||||
|
"SPRINT16 gate 2.3 [B] — a separation pin was ATTEMPTED and honestly REFUSED. Measured",
|
||||||
|
"post-ruling (garden_probe, funnel ON, storm_03b_earlybuster, 2026-07-20): bare bed 82.6",
|
||||||
|
"FULL (hail 10.7 + rain 6.8 HP); best flown line 90.2; best gain +7.6 HP. The block's own",
|
||||||
|
"semantics need 'bare LOSES the night' (bareMustLoseBelow, win line 50) and a bare bed",
|
||||||
|
"WINS this night by 32 points — the early buster's pea hail simply cannot hurt an open bed",
|
||||||
|
"enough. Any pin writable today would be a fudge: either a bareMustLoseBelow above the win",
|
||||||
|
"line (the field name lying) or thresholds tuned until the slogan lands (the S13 fudge the",
|
||||||
|
"gate exists to kill). THE FINDING: this yard cannot separate held from bare at ANY price",
|
||||||
|
"under its shipped storm — that is a balance fact about the NIGHT's hail spectrum, not the",
|
||||||
|
"rig market. The fight is in THREADS [B] 2026-07-20; candidate levers are C's hail",
|
||||||
|
"spectrum, the win threshold, or per-night garden stakes — A rules. When a retune lands,",
|
||||||
|
"re-measure, pin like backyard_01's, and DELETE this block in the same commit."
|
||||||
|
],
|
||||||
|
|
||||||
"_design": [
|
"_design": [
|
||||||
"DESIGN.md wants the corner block anchor-poor — 'nowhere to tie off'. An empty yard is just a",
|
"DESIGN.md wants the corner block anchor-poor — 'nowhere to tie off'. An empty yard is just a",
|
||||||
"smaller yard, so the trap is the interesting build: give it something that LOOKS like four free",
|
"smaller yard, so the trap is the interesting build: give it something that LOOKS like four free",
|
||||||
|
|||||||
@ -48,6 +48,16 @@
|
|||||||
"The bare bed reads 83.7 FULL, which is the bare-beds-win pool item showing up on a",
|
"The bare bed reads 83.7 FULL, which is the bare-beds-win pool item showing up on a",
|
||||||
"third yard - gate-4 material, not this yard's doing and not tuned here."
|
"third yard - gate-4 material, not this yard's doing and not tuned here."
|
||||||
],
|
],
|
||||||
|
"_separation_finding": [
|
||||||
|
"SPRINT16 gate 2.3 [B] — a separation pin was ATTEMPTED and honestly REFUSED, same",
|
||||||
|
"verdict as site_02's. Measured post-ruling (garden_probe, funnel ON,",
|
||||||
|
"storm_03_southerly, 2026-07-20): bare bed 83.7 FULL (hail 10.7 + rain 5.6 HP); best",
|
||||||
|
"flown 89.8; best gain +6.1 HP — D's S14 card numbers reproduced. Bare WINS the",
|
||||||
|
"southerly by 34 points, so 'bareMustLoseBelow' cannot be written honestly at any",
|
||||||
|
"threshold. The pea-hail nights cannot hurt an open bed enough for a sail to be the",
|
||||||
|
"point of the night; that is the NIGHT's balance fact, filed in THREADS [B] 2026-07-20.",
|
||||||
|
"When the balance ruling lands, re-measure, pin like backyard_01's, delete this block."
|
||||||
|
],
|
||||||
"yard": {
|
"yard": {
|
||||||
"width": 24,
|
"width": 24,
|
||||||
"depth": 16
|
"depth": 16
|
||||||
|
|||||||
@ -312,6 +312,12 @@ function render(out, s, ms) {
|
|||||||
} else if (s.sepUnjudged) {
|
} else if (s.sepUnjudged) {
|
||||||
const cs = card(out, 'SEPARATION TARGET — NOT JUDGED', 'ed-warn');
|
const cs = card(out, 'SEPARATION TARGET — NOT JUDGED', 'ed-warn');
|
||||||
cs.append(el('div', 'ed-note', s.sepUnjudged));
|
cs.append(el('div', 'ed-note', s.sepUnjudged));
|
||||||
|
} else if (s.separationFinding) {
|
||||||
|
// SPRINT16 gate 2.3 [B]: measured, and honestly REFUSED — different fact
|
||||||
|
// from "nobody tried", and the card must not flatten the two together.
|
||||||
|
const cs = card(out, 'SEPARATION TARGET — PIN REFUSED (measured)', 'ed-warn');
|
||||||
|
cs.append(el('div', 'ed-note',
|
||||||
|
Array.isArray(s.separationFinding) ? s.separationFinding.join(' ') : String(s.separationFinding)));
|
||||||
} else {
|
} else {
|
||||||
const cs = card(out, 'SEPARATION TARGET — NONE PINNED', 'ed-warn');
|
const cs = card(out, 'SEPARATION TARGET — NONE PINNED', 'ed-warn');
|
||||||
cs.append(el('div', 'ed-note',
|
cs.append(el('div', 'ed-note',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user