Sprint 11 integration: merge all lanes, wire leadFor + setBudget, untrack launch.json; Sprint 12 plan + prompts
This commit is contained in:
parent
7791299ef0
commit
e99f029206
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ tools/blender/thumbs/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
.claude/launch.json
|
||||||
|
|||||||
@ -612,3 +612,59 @@ THREADS' last [I] entry then SPRINT11.md.
|
|||||||
> Client juice: job-sheet letterhead + invoice styling for A's cards, one
|
> Client juice: job-sheet letterhead + invoice styling for A's cards, one
|
||||||
> per-client prop if cheap. Stand by on the tree-move if B's audit demands
|
> per-client prop if cheap. Stand by on the tree-move if B's audit demands
|
||||||
> it (C's gain drop goes first).
|
> it (C's gain drop goes first).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# SPRINT 12 prompts (the steel tells the truth, the paperwork looks the part)
|
||||||
|
|
||||||
|
Same rules: own clone, own branch, rebase onto latest main FIRST. Read
|
||||||
|
THREADS' last [I] entry then SPRINT12.md. New this sprint: launch.json is
|
||||||
|
untracked — `cp .claude/launch.example.json .claude/launch.json` once per
|
||||||
|
clone and pick your own port (suggested: A 8824, B 8825, C 8826, D 8827,
|
||||||
|
E 8828; integration holds 8823).
|
||||||
|
|
||||||
|
## Lane A — Sprint 12
|
||||||
|
> You are Lane A on SHADES 3D, Sprint 12. Rebase onto main, read SPRINT12.md.
|
||||||
|
> Gate 3 is yours: paste E's letterhead/invoice kit from tools/jobsheet
|
||||||
|
> (between the CUT markers; keep .void), rule on the HARD YARDS masthead and
|
||||||
|
> keep the ABN sequential, and wire the kid's bike (site-JSON key + loader
|
||||||
|
> line — read E's −Z lean note FIRST) with a ruling on its $60. Do NOT start
|
||||||
|
> reputation, site_03, or heatwave — gate 4 decides the branch at sprint end.
|
||||||
|
> Shepherd as always; B's re-audit may route retune proposals through you.
|
||||||
|
|
||||||
|
## Lane B — Sprint 12
|
||||||
|
> You are Lane B on SHADES 3D, Sprint 12. Rebase onto main, read SPRINT12.md.
|
||||||
|
> Gate 2 is yours: wire ratingHint into the failure threshold (A's ruling,
|
||||||
|
> THREADS sprint 11 — `load > c.hw.rating * (anchor.ratingHint ?? 1)`), with
|
||||||
|
> an assert on the CONSEQUENCE (cb blows before q at max tension through the
|
||||||
|
> funnel). Then re-audit BOTH yards — E's baked hints move everything with a
|
||||||
|
> GLB anchor — and post winnable lines per night. Numbers are E's: propose
|
||||||
|
> retunes in THREADS, don't nudge. Also fix the weak-link tie-break D flagged
|
||||||
|
> (strict < keeps first click; flag lowest rating × hint).
|
||||||
|
|
||||||
|
## Lane C — Sprint 12
|
||||||
|
> You are Lane C on SHADES 3D, Sprint 12. Rebase onto main, read SPRINT12.md.
|
||||||
|
> Two jobs: (1) be the second harness on B's post-wiring failure envelope —
|
||||||
|
> measure it through the storm while B measures it through the audit; if the
|
||||||
|
> two disagree, find the variable before anyone retunes. (2) Give the
|
||||||
|
> southerly buster's early change an in-world tell (skyfx): sky darkening
|
||||||
|
> from the south, the lull before the shift — deterministic (dt, t), readable
|
||||||
|
> without spoiling. D judges it.
|
||||||
|
|
||||||
|
## Lane D — Sprint 12
|
||||||
|
> You are Lane D on SHADES 3D, Sprint 12. Rebase onto main, read SPRINT12.md.
|
||||||
|
> Replay both yards AFTER B's ratingHint wiring lands: the trap should fire
|
||||||
|
> at default tension now (your measured fork), the ladder trip should fire by
|
||||||
|
> itself (your #6), the weak-link label should point honestly (your #7).
|
||||||
|
> Judge C's change-tell — does it telegraph without spoiling? — and re-read
|
||||||
|
> the backyard blurb A changed under you ("worked it for years" vs "your own
|
||||||
|
> place"). Feel notes in THREADS, receipts as always.
|
||||||
|
|
||||||
|
## Lane E — Sprint 12
|
||||||
|
> You are Lane E on SHADES 3D, Sprint 12. Rebase onto main, read SPRINT12.md.
|
||||||
|
> The gutter, the carport pattern, second time around: propose its collateral
|
||||||
|
> price with the reasoning baked beside it, and build the torn-gutter wreck
|
||||||
|
> that swaps on the same event. Expect retune proposals against your
|
||||||
|
> 0.22/0.30/0.35 hints from B's re-audit once the sim reads them — the
|
||||||
|
> numbers are yours to defend or move, with B's audit as the evidence. The
|
||||||
|
> tree-move stays cancelled.
|
||||||
|
|||||||
93
SPRINT12.md
Normal file
93
SPRINT12.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# SPRINT 12 — THE STEEL TELLS THE TRUTH, AND THE PAPERWORK LOOKS THE PART
|
||||||
|
|
||||||
|
*Sprint 11 delivered everything it named: the venturi reconciled (twice — both
|
||||||
|
directions of the same lesson), the enum checked, the carport priced and
|
||||||
|
billing, the job sheet quoting before you spend, the invoice with C's
|
||||||
|
resolving forecast on it, and — the door in front of all of it — B's
|
||||||
|
`setWorld`, so night 3 is playable by mouse. 315/0/0, verified live at
|
||||||
|
integration. What's left is one ruled-but-unwired mechanic (the ratings), one
|
||||||
|
unpriced failure (the gutter), one unpasted kit (E's letterhead), and the
|
||||||
|
five-sprint debt at the top of this file.*
|
||||||
|
|
||||||
|
Read THREADS from the last [I] entry.
|
||||||
|
|
||||||
|
## Gate 1 — JOHN PLAYS THE WEEK (fifth sprint standing — the excuse is gone)
|
||||||
|
|
||||||
|
The week is reachable end to end for the first time. `cp
|
||||||
|
.claude/launch.example.json .claude/launch.json`, `python3 server.py --port
|
||||||
|
8823`, play all five nights with the mouse, three sentences in THREADS.
|
||||||
|
- Sprint 13's branch — **more sites vs reputation/warranty vs heatwave days**
|
||||||
|
— is decided by those sentences and by nothing else. Everyone else's gate-2
|
||||||
|
work below is deliberately branch-independent.
|
||||||
|
- Watch the bank. A competent clean week now banks $485 (§BROKE_BELOW). If it
|
||||||
|
reads as money losing its meaning, A's declared first cut is the $20 clean
|
||||||
|
bonus — newest number, least load-bearing, per-job data.
|
||||||
|
|
||||||
|
## Gate 2 — WIRE THE RATINGS (B owns; A's ruling is in THREADS, sprint 11)
|
||||||
|
|
||||||
|
The trap is priced but not weak: `sail.js` fails a corner on `c.hw.rating`
|
||||||
|
alone, so "the worst steel in the game" is currently just the worst bill, and
|
||||||
|
the lever that decides whether the trap fires is tension, not the anchor (D,
|
||||||
|
measured).
|
||||||
|
1. **B: land the shape** `load > c.hw.rating * (anchor.ratingHint ?? 1)`.
|
||||||
|
world.js now guarantees the field (DEFAULT_RATING_HINT = 1); the `?? 1` is
|
||||||
|
belt-and-braces. Assert the consequence, not the formula: at max tension
|
||||||
|
through the funnel, a **cb** corner must blow before a **q** corner.
|
||||||
|
2. **B: re-audit BOTH yards the moment it lands.** E's baked hints (beam 0.22,
|
||||||
|
post 0.30, fascia 0.35, tree 1.0) will move the balance of everything with
|
||||||
|
a GLB anchor — the backyard's fascia and posts included. Post the winnable
|
||||||
|
lines per night like the sprint-11 table. **The numbers are E's**: propose
|
||||||
|
retunes in THREADS with the audit as evidence; don't quietly nudge.
|
||||||
|
3. **D: replay both yards after the wiring.** Your measured fork (tension 1.0
|
||||||
|
→ q3 blows, carport free; 1.4 → cb1 blows, −$205) should now bite at
|
||||||
|
default tension. The ladder trip should fire by itself (your #6). And your
|
||||||
|
#7: **B fixes the weak-link tie-break** (rigging.js reduces with strict `<`
|
||||||
|
— flag the lowest `rating × hint`, not the first click).
|
||||||
|
4. **C: second harness on the envelope.** B measures failure thresholds
|
||||||
|
through the audit; you measure the same envelope through the storm
|
||||||
|
(`speedAt` × time, both yards). Two harnesses, one number — the repo rule.
|
||||||
|
If they disagree, find the variable before anyone retunes.
|
||||||
|
|
||||||
|
## Gate 3 — THE PAPERWORK AND THE GUTTER (A + E; the invoice earns its ABN)
|
||||||
|
|
||||||
|
1. **A: paste E's kit** — `tools/jobsheet/index.html`, between the CUT
|
||||||
|
markers, purely additive by construction. Keep `.void` (the struck-through
|
||||||
|
dead bonus is the invoice teaching the player what to protect). Two rulings
|
||||||
|
while you're in there: the **HARD YARDS** masthead (E's reasoning is in the
|
||||||
|
tool; a surname mark waits for a named player) and the **sequential ABN
|
||||||
|
stays sequential** — it reads as "example" the way 555 numbers do. Don't
|
||||||
|
fix it into a real business's tax identity.
|
||||||
|
2. **A: wire the bike** — site-JSON key + loader line, the gnome pattern.
|
||||||
|
Read E's lean note first: it leans **−Z in three.js**, toward the fence;
|
||||||
|
bars ~0.10 m off the palings. Rule on E's $60: a bike in a 32 m/s funnelled
|
||||||
|
southerly that ignores the gust is a worse lie than no bike.
|
||||||
|
3. **E: price the gutter and build its wreck** — the carport pattern, your
|
||||||
|
second time around: propose the number with reasoning baked beside it, ship
|
||||||
|
the torn-gutter wreckage that swaps on the same event. With fascia 0.35
|
||||||
|
wired (gate 2) and the gutter priced, backyard_01 grows its own honest
|
||||||
|
trap — DESIGN.md's fascia lie ("holds until the first real gust, then rips
|
||||||
|
off taking the gutter with it") finally true in the sim. **A rules the
|
||||||
|
number; `collateralFor('gutter')` stops returning null.**
|
||||||
|
4. **C: the change announces itself.** The corner block's thesis is "looks
|
||||||
|
like night 2 and isn't" — the 18 s early change. Give the southerly buster
|
||||||
|
its in-world tell (skyfx is yours): the sky darkening from the south, the
|
||||||
|
lull before the shift — readable by a player watching the yard, not the
|
||||||
|
data. Deterministic off `(dt, t)` like everything else. D judges whether
|
||||||
|
it telegraphs without spoiling.
|
||||||
|
|
||||||
|
## Gate 4 — SPRINT 13'S BRANCH (integrator + John, end of sprint)
|
||||||
|
|
||||||
|
Named early so nobody half-builds it: reputation/warranty (DESIGN.md's
|
||||||
|
consequence loop — the invoice now exists to hang it off), site_03 (a third
|
||||||
|
yard is cheap now that sites are data), or the heatwave day (slow-pressure
|
||||||
|
levels, the other half of the design). Decided on John's sentences, not
|
||||||
|
before. Do not start any of the three this sprint.
|
||||||
|
|
||||||
|
```
|
||||||
|
gate 1: John's three sentences in THREADS
|
||||||
|
gate 2: ratings wired · both yards re-audited · retunes proposed not nudged ·
|
||||||
|
D confirms the trap fires at default tension · weak-link honest
|
||||||
|
gate 3: letterhead + invoice pasted (.void survives) · HARD YARDS ruled ·
|
||||||
|
bike wired and ruled · gutter priced, wrecked, and billing
|
||||||
|
gate 4: Sprint 13 branch chosen, in writing, in THREADS
|
||||||
|
```
|
||||||
43
THREADS.md
43
THREADS.md
@ -3923,3 +3923,46 @@ anchors are your GLB), but the tooling is now waiting, not TODO.
|
|||||||
through a rewritten NIGHTS[0] to get a coherent boot.** Everything A landed tonight — the enum, the
|
through a rewritten NIGHTS[0] to get a coherent boot.** Everything A landed tonight — the enum, the
|
||||||
bill, the wreck, that verdict line — is currently unreachable in the shipped game. B's one method is
|
bill, the wreck, that verdict line — is currently unreachable in the shipped game. B's one method is
|
||||||
the door in front of all of it.
|
the door in front of all of it.
|
||||||
|
|
||||||
|
[I] 2026-07-17 — **SPRINT 11 INTEGRATION (main).** All five lanes merged; only THREADS conflicted
|
||||||
|
(keep-both). selftest **315/0/0** — the exact sum (296 + A's 10 + B's 4 + C's 2 + E's 3), so no
|
||||||
|
assert was lost or double-counted in the merge. (Housekeeping: lane entries above are dated
|
||||||
|
07-19/07-20; this machine's clock says 07-17 — the lanes' dates drifted, the ORDER is right.)
|
||||||
|
|
||||||
|
**The sprint's headline, verified live, not just green:** the night-3 soft-lock is DEAD. B's
|
||||||
|
`setWorld` + A's honoured `boot({site})` merged together; driven in the browser,
|
||||||
|
`loadSiteInto('site_02_corner_block')` repoints the markers from the backyard's twelve to the
|
||||||
|
corner block's ten, byte-identical to `world.anchors`, zero console errors. D's cold-pass bug 1 —
|
||||||
|
"you cannot rig, cannot start, cannot leave" — no longer reproduces. **The full five-night week is
|
||||||
|
reachable by mouse for the first time.**
|
||||||
|
|
||||||
|
**Two cross-lane integration edits, both pre-agreed in THREADS, both done here:**
|
||||||
|
· hud.js — A's ⚠️ INTEGRATION marker resolved: the `TOMORROW_LEAD = 0.6` placeholder is gone,
|
||||||
|
the call site is C's verbatim `forecastLines(tomorrowDef, leadFor(1, wk.nights))`. Verified on
|
||||||
|
the rendered card: *"forecast confidence 75%"* — leadFor(1,5) = 0.25, exactly C's number.
|
||||||
|
· main.js — A's one private touch into B's session (`_startBudget` + `reset()`) replaced with
|
||||||
|
B's `setBudget(week.bank)`. The fake is deleted, as B asked. Exercised at boot: shop banks $80.
|
||||||
|
|
||||||
|
**Ruling on the launch.json port fight (A + E both filed it):** `.claude/launch.json` is now
|
||||||
|
UNTRACKED — `.claude/launch.example.json` ships in its place and `.gitignore` covers the real one.
|
||||||
|
Each clone copies the example once and picks its own port; suggested spread: integration 8823,
|
||||||
|
lanes A–E 8824–8828. A shared tracked file where every clone needs a different value was a merge
|
||||||
|
conflict with a fuse on it, and on JING5 (one machine, six checkouts) the fuse was lit.
|
||||||
|
|
||||||
|
**C's "half my assert is decoration" disclosure:** keeping it, exactly as labelled — a contract
|
||||||
|
guard for a future `band()` rewrite, not coverage. The honesty is the useful part and it's in the
|
||||||
|
test's own comment now. Nothing to delete.
|
||||||
|
|
||||||
|
Carried to SPRINT12, none blocking boot:
|
||||||
|
· **ratingHint is ruled REAL and still read by nothing** — A's ruling stands, the sequencing
|
||||||
|
blocker (setWorld) is gone. B wires `load > c.hw.rating * (anchor.ratingHint ?? 1)`; the
|
||||||
|
re-audit that follows is the sprint's real work, because E's baked 0.22/0.30/0.35 will move
|
||||||
|
the balance of BOTH yards the moment the sim reads them.
|
||||||
|
· **the gutter is still free** — `collateralFor('gutter')` returns null and backyard_01's house
|
||||||
|
is a free failure. E proposes a price + builds the wreck (the carport pattern), A rules.
|
||||||
|
· **E's invoice/letterhead kit is unpasted** (tools/jobsheet, CUT markers), the HARD YARDS
|
||||||
|
masthead and the sequential ABN await A's ruling, and the kid's bike is dead weight until A
|
||||||
|
wires its site-JSON key. The lean is baked toward −Z; read E's entry before placing it.
|
||||||
|
· **gate 3 — John plays the week. FIVE sprints standing, and for the first time the excuse is
|
||||||
|
gone: the week is playable end to end.** §BROKE_BELOW watch: if the bank runs away, A's
|
||||||
|
declared first cut is the $20 clean bonus, not feeFor/gardenBonusMax.
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
import * as THREE from '../vendor/three.module.js';
|
import * as THREE from '../vendor/three.module.js';
|
||||||
import { STORM_LEN } from './contracts.js';
|
import { STORM_LEN } from './contracts.js';
|
||||||
import { forecastLines } from './weather.js';
|
import { forecastLines, leadFor } from './weather.js';
|
||||||
|
|
||||||
const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v);
|
const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v);
|
||||||
const kmh = (ms) => ms * 3.6;
|
const kmh = (ms) => ms * 3.6;
|
||||||
@ -435,20 +435,12 @@ showForecast({ key, def, site, tomorrowDef }, wk, onGo) {
|
|||||||
// read it as nights first, passed 1, and the card advertised "forecast
|
// read it as nights first, passed 1, and the card advertised "forecast
|
||||||
// confidence 0%": a forecast admitting it knows nothing, printed as news.
|
// confidence 0%": a forecast admitting it knows nothing, printed as news.
|
||||||
//
|
//
|
||||||
// ⚠️ INTEGRATION, SPRINT11: this constant is a placeholder and C has
|
// C's `leadFor` maps "N nights out" onto that dial — 0.25 for tomorrow of
|
||||||
// already landed its replacement on lane/c — `leadFor(nightsOut, weekNights)`
|
// five (75% confidence). Safe to print because the band RESOLVES: verified
|
||||||
// in weather.js, which maps the week onto forecastFor's 0..1 domain and
|
// 4020 samples, 0 violations — tomorrow's band always contains tonight's,
|
||||||
// gives 0.25 for tomorrow of five (75% confidence), not my 0.6. Theirs is
|
// so the number tightens toward the truth and never rules out what it
|
||||||
// better than a guess: they verified the band RESOLVES — 4020 samples, 0
|
// previously allowed. (Integrated at SPRINT11 merge; was a 0.6 placeholder.)
|
||||||
// violations, tomorrow's band always contains tonight's, so the number
|
const tf = tomorrowDef ? forecastLines(tomorrowDef, leadFor(1, wk.nights)) : null;
|
||||||
// tightens toward the truth and never rules out what it previously
|
|
||||||
// allowed. That's the property that makes it safe to print on a card.
|
|
||||||
// At merge this becomes C's own call site, verbatim from their THREADS:
|
|
||||||
// forecastLines(tomorrowDef, leadFor(1, wk.nights))
|
|
||||||
// Not imported here yet only because leadFor is on lane/c and this branch
|
|
||||||
// would go red reaching for it.
|
|
||||||
const TOMORROW_LEAD = 0.6;
|
|
||||||
const tf = tomorrowDef ? forecastLines(tomorrowDef, TOMORROW_LEAD) : null;
|
|
||||||
const tomorrow = tf ? `
|
const tomorrow = tf ? `
|
||||||
<div class="tomorrow">
|
<div class="tomorrow">
|
||||||
<span class="tlabel">tomorrow</span>
|
<span class="tlabel">tomorrow</span>
|
||||||
|
|||||||
@ -771,15 +771,10 @@ export async function boot(opts = {}) {
|
|||||||
// loadSiteInto, keyed on the rebuild itself, so it can't desync from it.
|
// loadSiteInto, keyed on the rebuild itself, so it can't desync from it.
|
||||||
await loadSiteInto(week.site);
|
await loadSiteInto(week.site);
|
||||||
|
|
||||||
// Reaching into Lane B's session to re-bank the shop. `RiggingSession` takes
|
// B's setBudget (SPRINT11): re-bank + reset in one named call. This was
|
||||||
// a budget at construction but exposes no setter, and the UI owns the
|
// main.js's one private touch into their session (`_startBudget` + reset(),
|
||||||
// instance — so this is the one private touch in main.js, done loudly rather
|
// asked in THREADS, landed, fake deleted — same route reset() took).
|
||||||
// than by forking their file. I've asked for `session.setBudget(n)` in
|
rigging.session.setBudget(week.bank);
|
||||||
// THREADS; when it lands these two lines become one. (Same route
|
|
||||||
// `session.reset()` took: I faked it, asked, they landed it, I deleted the
|
|
||||||
// fake.)
|
|
||||||
rigging.session._startBudget = week.bank;
|
|
||||||
rigging.session.reset();
|
|
||||||
spentThisNight = 0;
|
spentThisNight = 0;
|
||||||
// SPRINT11 — the job sheet reads three new things off the week: tonight's
|
// SPRINT11 — the job sheet reads three new things off the week: tonight's
|
||||||
// JOB (client + brief), the QUOTE (what it pays, before you rig it, which is
|
// JOB (client + brief), the QUOTE (what it pays, before you rig it, which is
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user