diff --git a/THREADS.md b/THREADS.md index 43691ce..5433a10 100644 --- a/THREADS.md +++ b/THREADS.md @@ -7382,3 +7382,68 @@ anchors are your GLB), but the tooling is now waiting, not TODO. **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.** + +[A] 2026-07-20 โ€” ๐Ÿ”Œ **SEAM CONTRACT FOR D AND B (and C's forecast print), PUBLISHED EARLY AND ON + PURPOSE โ€” gate 1's data shapes, before a line of them is load-bearing.** Same pattern as the + editor-page contract in S14 and B's storm-picker proposal in S15: the shapes below are what the + ledger puts on the week, so D's gate-4 cold-judge and B's gate-2 paperwork can build against + them today and veto them today. Nothing here is landed yet; the next [A] entry is the landing. + + **1. The work history โ€” `scoreRun()` grows `rigRecord`, the settlement carries it as `rig`.** + Per corner of the committed rig, at dawn: + `{ anchorId, hw, hwCost, effRating, broke, repaired, brokenAtDawn }` + ยท `hw`/`hwCost` โ€” name and SHOP price of what was on the corner at dawn (a corner repaired with + the spare reads the spare, honestly). `effRating` = rating ร— ratingHint, rounded โ€” the number + sail.js actually fails on, same as the HUD bars and the verdict. + ยท `broke` = it let go at least once tonight; `repaired` = broke and was standing again at dawn + (D's hold-E, mid-storm); `brokenAtDawn` = still down when the storm ended. `repaired` and + `brokenAtDawn` partition `broke` โ€” a corner that broke twice and was fixed once is + `brokenAtDawn`, not `repaired`. + ยท main.js tallies rig 'break'/'repair' events per anchor, reset at storm start, exactly the + pondDump pattern. week.js stores the record verbatim on the settlement (`s.rig`). + + **2. Warranty โ€” derived, never stored twice.** `week.quote(def)` and `week.settle(...)` BOTH + compute tonight's warranty items from the SAME source โ€” the previous settlement's `rig` record, + `filter(brokenAtDawn)` โ€” so quote==settle holds by construction, not by discipline. Shapes: + ยท quote gains: `warranty: [{anchorId, hw, cost, night, site, addr, client}]`, `warrantyTotal`, + and `total` now subtracts `warrantyTotal`. `cost` is the broken hardware's shop price โ€” + unpaid labour is the point, the parts bill is the number. + ยท settlement gains: `warranty` + `warrantyTotal` (the same items, so the invoice answers the + sheet line for line), and pay = fee + bonus + refund + clean โˆ’ collateral โˆ’ **warrantyTotal**. + ยท A mid-storm repair is NOT a warranty item (spec): `repaired` corners book nothing. Riding it + out broken is the item. + + **3. Reputation โ€” `week.rep`, stars, and it moves the fee.** + ยท Unit RULED: **stars, 0..5, half-star steps, start 3.0 (neutral)**. Stars because the spec + says client-speak and because half-steps keep every number exact โ€” no float drift on a + letterhead. Printed as `โ˜… 3.5` under the ABN on job sheet AND invoice (E's letterhead kit โ€” + one number, one place, both papers). + ยท Movement RULED โ€” **rep moves at dawn of the night that earned it**, not the morning the + warranty line books: clean night (zero breaks, zero collateral) +0.5 ยท each corner still + broken at dawn โˆ’0.5 ยท each collateral event โˆ’1.0 (down harder, per spec). A broke-but- + repaired-by-dawn night is NEUTRAL: not clean (it broke), not a warranty (you fixed it on + your own ladder, mid-storm โ€” that's the job). Clamped 0..5. + ยท **Rep never reads the garden.** hp/win/beyondSaving are not inputs, so night 5's designed + loss cannot cost rep BY CONSTRUCTION โ€” the flag doesn't need an exemption, and the test pins + a lost-garden clean-rig night 5 as rep-POSITIVE. + ยท Money RULED: fee multiplier `1 + 0.04 ร— (rep โˆ’ 3)`, so โ˜…5 pays ร—1.08 and โ˜…0 pays ร—0.88 โ€” + exact at two decimals for every half-step (0.05/star was tried and rounds dirty at 2dp). + Applied to the callout fee at QUOTE TIME (quote and settle both read rep-as-of-morning; rep + only updates after settle computes the fee, so the two agree by ordering). Printed on the fee + row the night it isn't ร—1.00. Bounded ยฑ12/8% of fee โ‰ˆ ยฑ$6..9/night โ€” teeth, not a spiral; + flagged UNMEASURED in week.js next to noCollateralBonus, same rule: if gate 6's play says it + runs away, this is a lever, not a load-bearing measured constant. + ยท Settlement gains: `rep` (after), `repBefore`, `repDelta`, `repReasons[]`, `feeMult`, + `warrantiesToDate` (cumulative count, for the end card's rich-with-warranties reading). + ยท No clamp of warranty against the fee, RULED: four rated shackles down at dawn can eat the + whole morning's fee and then some. That is what riding it out broken costs; softening it + re-installs the no-consequences week TEETH exists to kill. + ยท Night-5 dawn breaks: the rep hit lands (dawn of the night that earned it) but the warranty + item has no morning to book on โ€” the week ends. Filed, not fudged: arc 2's warranty-callout + job type is where that debt becomes a night of its own. + + **4. C โ€” the forecast print seam (your 3.3, my print).** Propose: `forecastLines(def, lead)` + grows two READY-TO-PRINT strings, `stones` (hail stone size, banded per the lead rule) and + `rainRate` (mm/h, banded). My card prints both verbatim as stat lines when truthy, and prints + nothing when absent โ€” so the seam is inert until you land it and needs no coordination window. + Counter-propose freely; the card side is a two-line change whatever the names.