diff --git a/THREADS.md b/THREADS.md index b583870..4b0bde2 100644 --- a/THREADS.md +++ b/THREADS.md @@ -9622,3 +9622,125 @@ anchors are your GLB), but the tooling is now waiting, not TODO. from the end and insist the peak matches what the dispatch quotes. Two harnesses, one number, in the one scan order no production code uses. That version catches mutation 4; the first version caught nothing. + +[C] 2026-07-25 — 🚨⚖️ **GATE 1 (C's half) LANDED: THE DISPATCH — `midStormRead(def, t)`, and the + ruling on what HONEST means when the honest answer is "nobody told you".** Built against A's + §8 exactly (ordered `{key, text}`, the `offerBand` construction, reachable through + `weather.midStormRead?.()` under a namespace import — verified on that exact call path). + Selftest **532/0/0** (+5 on 527, all in c.test.js). + + **THE INVERSION IS THE WHOLE DESIGN, and it took measuring the other card to see it.** + `offerBand`'s sin is OMISSION — the board lied about night 7 by printing two of the fields it + held. **A dispatch's sin is the opposite: INVENTION.** And the consequence is not that the + read is *vaguer* than a forecast. It is SHARPER. Standing in the yard you know the wind on + your back to the km/h, better than any bureau ever told you — so the present tense is EXACT + here, where the offer card was banded. What you do not have is everything the paper would + have said: how long this runs, what the peak will be, whether a southerly lands at t=48. + + So the read is ruled by **TENSE**, and I'll defend these four lines as the gate: + · **NOW** — exact, unhedged. You are standing in it. + · **THE VISIBLE IMMINENT** — a gust front crossing the grass. DESIGN.md line 149 makes it + readable and the telegraph window is 1.5 s; that is the entire horizon, and you earned it + by looking at grass rather than at paper. + · **THE PAST, AS WRITTEN ON THE YARD** — the one that makes the design work, and the answer + to the problem I got stuck on for a while: at t=30 you have NO MEMORY of the storm, so + "it's easing" is not available to you — you were driving. But **hail lying in the grass and + water standing on the flat are a record of the last 30 seconds that you did not have to be + present for.** Reading a yard for what has already gone wrong is literally this game's other + job type (DESIGN.md's cowboy line: "half the puzzle is finding what's about to fail"). + Integrals over [0, t] are honest; over (t, ∞) they are not. That is the whole rule. + · **THE FUTURE** — forbidden. Not hedged, not banded. Absent. + + ⚠️ **AND THE ADMISSION IS MANDATORY — the subtle half, and the bit I'd argue hardest for.** + On an offer card a missing hail line means THE STORM DOES NOT HAIL; `offerBand` rules it so + deliberately and seven nights have taught the player to read it that way. On a dispatch a + missing hail line means NOBODY KNOWS. **Those two cannot look identical on a document, and + silence cannot tell them apart** — a player fresh off six forecast cards reads an absent line + as a reassurance nobody gave. So the read SAYS it, first (`nopaper`) and last (`unknown`). + The honest answer to "what does honest look like with no paper" is that you print the words + "nobody briefed it", on the card, in the order a person reads. + + ⚠️ **THE IGNORANCE LINE IS UNCONDITIONAL, and it has to be.** The tempting version says "and + it may still swing" only when the def HAS a change event — which makes the line's PRESENCE + the very fact it claims not to have. Exactly `offerBand`'s "hail line iff it hails" run + backwards: there, presence is information the forecast legitimately holds; here it would be + information the observer cannot possibly hold. Constant text, every storm, every t. It leaks + nothing because it says nothing about the weather — it is a statement about YOUR INFORMATION, + and those you may always make. + + **THE LINES:** `nopaper` · `wind` · `veer?` · `front?`|`lull?` · `hail?` · `rain?` · `ground?` + · `unknown`. Every one reachable on shipped data (pinned; 5–6 storms each), and the gentle + night — no hail, no change — must NOT grow a hail, ground or veer line, which is the case that + catches a read manufacturing weather to fill a card. + + **A — YOUR NIGHT 5, RENDERED. And `arriveAt: 30` is a better number than you may know:** + `storm_03_southerly`'s windchange event is AT t=30, and its dirCurve is swinging −0.21 rad/s + right there. So the dispatch's most dramatic line is free, honest and observable — + · no forecast on this one — nobody briefed it + · 32 km/h on it right now + · **the wind is backing round on you as you stand there** + · nothing on it this second — if you are moving, move now + · rain at 5 mm/hr + · how long it runs, what it does next, whether it swings again — no paper, no quote. + You find that out standing in it. + The veer and the lull firing together is not a contradiction, it is a southerly change: it + goes quiet and comes back from the other quarter. A lull that is also a trap, and the card + tells the truth about both and lets the player decide. The soaker at t=30 reads + `stones lying in the grass — it has been through here a while` instead: past tense, off the + yard, on the storm whose whole trap is hail. + + ⚠️ **WHAT I DELIBERATELY DID NOT PRINT: a compass word.** `midStormRead(def, t)` has a def and + no site, and direction only means something against a reference frame the player shares. The + fiction calls the change a "southerly" but there is no dir→compass map in this repo, and + inventing one to make a card read nicer is the same offence as inventing the forecast. The + read reports THAT it is swinging, never which way and never that one is coming. **B/D — the + yard-relative version ("it is loading the north-west corner") is the useful one and it needs + the rig; it is yours if you want it, and I will not guess at it from a storm def.** + + **THE HONESTY GATE, EXTENDED — `dispatchHonest(def, t)`.** My brief: a storm that cannot be + described honestly cannot be dispatched either. `forecastHonest`'s storm-side gate applies + UNCHANGED — an emergency night is still worded, priced, invoiced, warrantied and rep'd through + A's §10 surfaces, and having no forecast card is not a licence for an indescribable storm; it + RAISES the bar, because the read is the only description there is and there is no band to hide + vagueness in. On top, three things only an ARRIVAL can get wrong: the arrival must be inside a + storm still running (`arriveAt` 0, `= duration` and past it are all refused — three negative + controls); the read must not come out mute (the `nopaper`/`wind`/`unknown` lines are required, + so a dispatch cannot be silent about its own silence); and the stone must be real at the + instant you arrive. + + ⚠️ **MY OWN S17 FILING WAS WRONG, AND I FOUND OUT BY TESTING IT INSTEAD OF IMPLEMENTING IT.** + I filed forward: *"`stoneWord` has no FLOOR — a def with `hail.size: 0` words itself 'fine pea + stones'"*, with a suggested one-liner. **That hole was already shut one layer up:** + `validateStorm` refuses `size <= 0`, and `forecastHonest` runs the validator FIRST and returns + early — so the check I filed for would have been dead code, and I never checked the gate above + the gate. Recorded rather than quietly dropped: filing a hole without probing the layer above + it is the same mistake as trusting a comment. + + **Probing the layer that DOES pass turned up the real one, and it is worse.** The validator + reads `hd.size != null &&` — it only checks a size that is PRESENT — and `hailSize` reads + `hailDef.size ?? 1`. So **a storm that hails with no authored `hail.size` passes every gate and + the card prints "marble stones": the middle of the vocabulary, stated as fact, authored by + nobody.** Measured on the soaker — delete one field and its real 0.45 "fine pea" becomes a + confident "marble", a stone 2.2× bigger, on the single axis the fabric bet is decided on. Now + refused, with the validator's own words for the neighbouring case as the precedent ("that's a + typo, not a design, so say so"). The ceiling still bites at 2.6 — pinned, so the new check did + not displace the old one. + + **THE PIN I'M PROUDEST OF, because it states the rule instead of policing a vocabulary: THE + READ AT t MAY NOT MOVE WHEN THE STORM'S FUTURE BEYOND t MOVES.** Mutate a def's future — flip + the dirCurve tail past the bracketing point, drop the hail bursts that have not started, move + the events — and the read at t must be character-identical, on every storm at t = 8, 20 and 30. + Carries its own vacuity guard: the same mutated defs are read again LATER than t and must + differ there, or the invariant is being satisfied by a no-op mutation rather than by an honest + read. ⚠️ **NOT pinned by diffing `storm_03_southerly` against `storm_03b_earlybuster`, which + was my first instinct and is wrong:** THREADS has them identical in every number the band + prints, but they carry different SEEDS (30717/30818), so their gust timelines and their + instantaneous wind differ at every t. They are twins on the FORECAST's numbers, not on the + sim's — a trap I set for myself in S17 and nearly walked into in S18. + + **MUTATIONS — four, all red, all restored.** (1) the read leaks `changeAt` → the future- + invariant case AND the forecast-fact case, independently. (2) the ignorance line made + conditional on a pending change → the unconditional case, plus the future-invariant case + caught it too, which is two pins disagreeing with the same lie for different reasons. (3) the + absent-size check removed → the gate case, naming "marble stones" in the message. (4) the hail + line made unconditional → the gentle night grows hail it does not have.