CR-008: boards that feel fresh (Phase 10H) plan

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
fireshaper 2026-10-04 17:56:36 -04:00
parent edbe31593b
commit 394fc1b0db
4 changed files with 71 additions and 0 deletions

View File

@ -910,3 +910,7 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md`
- **A backfill migration instead of a database reset.** The CR allows resetting, but contracts are JSONB, so a custom SQL migration can give old rows the new fields and keep saves. It uses a `pg_temp` helper function (drizzle runs all migrations in one session) and touches only contracts without a `goodId`, so rerunning is a no-op.
- **Summaries carry `goodId`, `massTonnes` and `shipper`** for Step 10G.10's "Delivered 6 t Medical Supplies for Meridian Health to the Moon".
## CR-008 — Boards That Feel Fresh (Phase 10H)
- **User report: "the jobs aren't refreshing".** Investigated before changing anything: the server stores a new board every period (the user's dev database had one per 10-minute period, all different), and a real browser left on the board refetched one second after the timer hit zero and showed the new cards. The new boards just look the same for an early player: Earth → Moon runs of three goods, with identical pay for the same good and mass. The user picked three fixes from four offered: visible refresh, per-job pay rate, more early goods (not more open slots).

View File

@ -0,0 +1,54 @@
# Change Request CR-008 — Boards That Feel Fresh
**Project:** Deadhead: Space Freight Tycoon
**Applies to:** a build with CR-001 to CR-007 complete
**Do this:** as **Phase 10H**, after Phase 10G and before Phase 11
**Related docs:** `CR-006-boards-that-fit.md`, `CR-007-cargo-goods.md`, `DECISIONS.md`
---
## 1. Why
User report: "The jobs aren't refreshing after you wait. You get the same jobs even after the timer hits zero. Leaving the page and coming back still doesn't refresh and neither does refreshing the page manually."
Investigation: the board **does** refresh. The server stores a new board each period (the user's dev database has one per 10-minute period, with different goods, masses and payouts). A browser left on the board refetched one second after the timer hit zero and showed the new cards; a reload showed the same new board. But the new board looks like the old one:
- An early player (one Courier, Earth and the Moon discovered) is offered almost only Earth → Moon runs of three Standard goods (CR-006 fits the board to the fleet; CR-007 has three Standard goods on that route).
- Payout depends only on good, mass and distance, and the Moon's distance barely changes, so the same good and mass pays the identical amount on every board ("Consumer Goods 16 t · 614 cr" recurs).
- Nothing on screen says the board changed.
The user chose three fixes (asked): show the refresh, vary pay per job, and add more early goods.
## 2. Decisions
Record as plan §0.5.60–0.5.62.
- **0.5.60 Market rate.** Each board contract (not tutorial) gets its own pay rate, drawn uniformly within ±`contractPayVariance` (default 15 %) of 1 and multiplied into its payout. The average payout is unchanged.
- **0.5.61 More early goods.** Five Standard goods join the catalog so early routes vary: Earth → Moon gains Water Recyclers, Spare Parts (Priority-eligible) and Lunar Base Supplies; Moon → Earth gains Crew Personal Effects and Recycled Alloys.
- **0.5.62 Visible refresh.** When the board shown for a location changes (the timer rolls over while open, or the player comes back to a newer board), the screen announces "New contracts posted" and tags each contract that wasn't on the last board the player saw there "New". The last seen board is remembered per location in the browser (a convenience; losing it only loses the tags). On a first visit nothing is tagged.
## 3. Steps — Phase 10H
### Step 10H.1 — Content: pay variance and new goods
- Config `contractPayVariance` (0.15, fraction). Goods per decision 0.5.61:
| Id | Name | Mass (t) | Pay × | Priority | Produced at | Demanded at |
|---|---|---|---|---|---|---|
| `water-recyclers` | Water Recyclers | 3–18 | 1.1 | No | Earth | Moon, Mars, Ceres |
| `spare-parts` | Spare Parts | 1–12 | 1.05 | Yes | Earth, Mars | Moon, Ceres, Jupiter |
| `lunar-base-supplies` | Lunar Base Supplies | 2–20 | 1.0 | No | Earth | Moon |
| `crew-effects` | Crew Personal Effects | 0.5–5 | 1.2 | No | Moon, Mars, Ceres | Earth |
| `recycled-alloys` | Recycled Alloys | 5–30 | 0.95 | No | Moon | Earth, Mars |
- **Test:** content tests pass with the new goods; Earth → Moon has at least five Standard goods and Moon → Earth at least four; the variance is a fraction.
### Step 10H.2 — Sim: per-contract pay rate
- Board contracts (fit and normal) draw a rate in [1 − v, 1 + v] after their other choices; `contractPayout` takes an optional market rate (default 1). Tutorial contracts use 1.
- **Test:** payout scales with the rate; over 1,000 boards the rates stay within bounds and average 1 ± 0.01; the same good and mass on two boards can now pay differently; tutorial payouts are unchanged; the CR-007 class-mix test still passes.
### Step 10H.3 — Client: visible refresh
- Per decision 0.5.62: a `role="status"` notice "New contracts posted" and "New" pills on new contracts (which also rise in), remembered per location in `localStorage` (wrapped in try/catch).
- **Test:** with a remembered earlier board, new contracts are tagged and the notice shows; with the same board remembered, nothing is; on a first visit, nothing is.
### Step 10H.4 — Regression
- Plan amendments (Step 3.8 payout, Step 9.4 board), full suite, coverage, lint, build; manual check across a real rollover. Stop for review.

View File

@ -115,6 +115,9 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple
57. **Board mix unchanged** (CR-007). Class selection (by each location's class-level `cargoClassMix`), board size and first-contact chance keep their logic and config.
58. **Shippers** (CR-007). Each contract gets a shipper name from its origin's list. Flavor only.
59. **Tutorial goods** (CR-007). Tutorial contracts use Standard goods produced at the loaner's location and demanded at the other end; never Priority. The scripted "Unmarked crates" contract is unchanged.
60. **Market rate** (CR-008). Each board contract (not tutorial) gets its own pay rate, uniform within ±`contractPayVariance` of 1, multiplied into its payout; the average is unchanged.
61. **More early goods** (CR-008). Water Recyclers, Spare Parts and Lunar Base Supplies (Earth → Moon), Crew Personal Effects and Recycled Alloys (Moon → Earth) join the catalog.
62. **Visible refresh** (CR-008). When a location's board changes, the screen announces "New contracts posted" and tags contracts not on the last board the player saw there "New" (remembered per location in the browser; nothing tagged on a first visit).
---
@ -562,6 +565,12 @@ Steps 10G.1–10G.11 are specified in `memory-bank/change-requests/CR-007-cargo-
---
## Phase 10H — Boards That Feel Fresh (CR-008)
Steps 10H.1–10H.4 are specified in `memory-bank/change-requests/CR-008-fresh-boards.md` §3. Done after Phase 10G and before Phase 11; stop for review at the end.
---
## Phase 11 — PWA
### Step 11.1 — Installable PWA

View File

@ -213,3 +213,7 @@ Spec: `memory-bank/change-requests/CR-007-cargo-goods.md` (supplied as "CR-005 /
- [x] **Step 10G.9 — Client: Priority in the dispatch sheet.** `explainProblems` adds "Too slow — 7h vs 5h window" (sim `contractTripGameHours` vs the window) so a slow pair is disabled with the numbers; `PairOption.priority` carries each pair's trip and the window, and eligible pairs show "Priority: 2.1h trip, 1.4h to spare in the 3.5h window". The sheet's job details now start with the good and shipper ("Mail & Parcels for Pacific Orbital Logistics · Standard · 6 t …") and Priority jobs show the window chip. Test: `dispatch-priority.test.tsx` (Courier enabled with its margin, Bulk Hauler disabled with "Too slow — …", numbers from the sim).
- [x] **Step 10G.10 — Client: goods in summaries.** Each delivery in "While you were away" says "Delivered 6 t Medical Supplies for Meridian Health to the Moon" (from the summary's `goodId`, `massTonnes`, `shipper`; new `toLocation` gives "to the Moon" / "to Mars"); deadheads keep their fuel line. Test: `away-summary.test.tsx` (the seeded delivery line; a deadhead shows no "Delivered").
- [x] **Step 10G.11 — Plan amendments and regression.** CR-007 §7 amendments added to plan §0.5.6 and §0.5.17 and steps 2.2, 2.4, 3.8, 3.9, 3.12, 9.4, 9.5 and 12.1, and to CR-001 Step 10A.3. Typecheck, lint, full suite with coverage (108 files, 753 tests; sim lines 100 %) and the web build are green. **Manual check:** a fresh owner after the deal with one Courier at Earth: every contract names a good and an Earth shipper (Mail & Parcels, Consumer Goods, Packaged Food; bulk Packaged Food lots flagged Too heavy), and a Priority job appeared on the first board (Mail & Parcels, 7.7 t, window 4.3 h; the Courier makes it in 2.3 h with 2.1 h to spare). The Priority chip keeps its unit in normal case ("within 4.3h"). Screenshots: `docs/screenshots/10g11-goods-contracts-solo-{desktop,phone}.png`, `10g11-priority-dispatch-solo-{desktop,phone}.png`. **Balance notes for Phase 12:** with "the band wins", bulk lots make Packaged Food and Electronics the usual big-band goods; shippers are random per origin, so e.g. Hollis & Crane Consumer can ship Mail. **Phase 10G complete — stopped for review.**
## Phase 10H — Boards That Feel Fresh (CR-008)
Spec: `memory-bank/change-requests/CR-008-fresh-boards.md`. New decisions recorded as plan §0.5.60–0.5.62.