docs: handoff, session log and pointers to the contract

docs/HANDOFF.md is the starting point for the next maintainer;
docs/superpowers/notes/2026-11-11-session-log.md records the day.
AGENTS.md, CLAUDE.md and README now point maintainers to the handoff
and to docs/contract.md.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Fable 5.2 committed 2026-11-11 12:06:48 +01:00
1 parent c67d81b288
commit 2277f4beb6
6 files changed
+165 -3

No files matched your search

@@ -79,7 +79,7 @@ Owner request: audit the course, fact-check, add sources, knowledge and exercise
- Not done: a human playing the games; the tab-switch fix is covered by stream tests only.
## Open follow-ups (added)
- Changes are uncommitted in the working tree.
- (Committed later the same day; see the end of this file.)
- `Check.fs` is not in `fsharp/web/Web.fsproj` (not needed in the browser).
- A turn queue (honouring Up-then-Left within one step) is still only a question in Module 3.
- Resolved from the earlier list: backwards `Time` is now harmless behind `clampTime`.
@@ -123,7 +123,7 @@ Owner approved eleven extensions; spec: `docs/superpowers/specs/2026-11-11-cours
- VS Code's own display of the JS type errors was not checked, only `tsc`.
- TypeScript version is not pinned (`TS_PACKAGE` can pin it).
- Scala lacks the JS test "play without a best answers LoadBest with 0".
- Everything is uncommitted in the working tree.
- (Committed later the same day; see the end of this file.)
## Playwright end-to-end suite (2026-11-11, owner's suggestion; spec Item 12)
- `e2e/` (own `package.json`, `@playwright/test` 1.65.0 pinned) and `scripts/e2e.sh`; `scripts/play.mjs` deleted, `smoke.mjs` kept. The course tracks stay dependency-free.
@@ -131,3 +131,9 @@ Owner approved eleven extensions; spec: `docs/superpowers/specs/2026-11-11-cours
- Result: 176 tests pass in about 20 s. No frame of any track differs from the model.
- Found and fixed: the three tracks read an unusual stored best differently (`"1e2"`, `"7.0"`, `"2147483648"`). Ruling: only plain decimal digits with a value of at most 2147483647 count; anything else reads as 0. Applied to `js/solutions/browser.js`, `scala/web/BrowserPlatform.scala`, `fsharp/web/BrowserPlatform.fs`.
- Still not covered: real animation timing and real hidden-tab throttling (the clamp is tested with a fake 10 s frame), rendered pixels and fonts, zoom, touch, key auto-repeat, Firefox (no build installed), and a person playing.
## Wrap-up (2026-11-11)
- `docs/contract.md` is now the canonical contract; the "contract" section of the 2026-10-28 plan is superseded.
- Specs: `specs/2026-11-11-audit-pass.md` (written after the fact) and `specs/2026-11-11-course-extensions.md` (twelve items, marked as built).
- Committed on branch `audit-and-extensions` (`edd57f0`), merged into `main` (`c67d81b`) and pushed to origin on the owner's instruction.
- `docs/HANDOFF.md` is the starting point for the next maintainer; `notes/2026-11-11-session-log.md` records the day.
@@ -0,0 +1,53 @@
# Session log — 2026-11-11
What was asked and done on this day, in order. Decisions and results are in the build log (`2026-10-29-build-log.md`, sections "Audit and extension pass", "Extension pass", "Playwright end-to-end suite"); the rules as they now stand are in `docs/contract.md`.
## 1. Audit ("take a look through this course … skip the questions")
The main session read the whole course and the JS solutions, then ran a hand-rolled mutation analysis of the solutions against the tests.
- Found three behaviour bugs: uneven steps at every speed-up, a hidden browser tab killing the snake, Pong restart clearing held keys. Fixed in JS first, then ported to Scala and F# by two subagents working from the JS diff.
- Fact-checked the text; measured mulberry32's output coverage by running its full 2^32 period (44 % of values appear).
- Wrote bonus Module 12 (property-based testing built on the student's own `Random`), with tests that run the library against deliberately broken games.
- Added fixture cases for the six test gaps the mutation run showed, challenge questions and primary sources.
- Spec written afterwards: `docs/superpowers/specs/2026-11-11-audit-pass.md`.
## 2. Ideas ("are there any ideas … to improve and extend the course?")
Eleven ideas were proposed, grouped as: close gaps the course already points at; deepen the theory; take testing further; reach and polish. The owner answered: do all eleven; the main session writes the specs and Opus 5.5 does the coding.
## 3. The eleven extensions
Spec: `docs/superpowers/specs/2026-11-11-course-extensions.md`. Builders were Opus subagents, dispatched in waves so that no two worked on the same files:
| Wave | Builder | Items |
|---|---|---|
| 1 | A (JS, fixtures, text) | 1 turn queue, 7 state generator and model-based test |
| 1 | B | 6 `State`, 8 mutation script |
| 1 | C | 4 stack-safe IO (Module 7b) |
| 2 | D | 2 persisted high score, 5 `play` |
| ports | Scala, F# | items 1, 7, 6, 4 — then 2, 5 |
| 3 | E | 3 replay viewer, 10 Life capstone with `Click` |
| ports | Scala, F# | items 3, 10 |
| 4 | F | 9 JS type checking, 11 play script, clean-ups |
The main session verified each wave before starting the next, kept tar snapshots of the working tree between waves, and ran the complete verification at the end.
## 4. Playwright ("you could consider doing the test with playwright")
Item 12 was added to the spec and built by one more Opus builder. The suite fixes the seed, fakes the clock and records canvas draw calls, then compares every frame each page draws with the pure JS model. It replaced `scripts/play.mjs`. It found one real difference between tracks (how an unusual stored best score is read); the main session ruled on one rule for all three and applied it.
## 5. Wrap-up
Contract (`docs/contract.md`), the after-the-fact audit spec, this log and `docs/HANDOFF.md` were written; everything was committed on branch `audit-and-extensions`, merged into `main` and pushed.
## What was learned about working this way
- **Write the contract into the stub doc comments and the course text first.** Porters then implemented exactly what the text says, and mismatches surfaced as questions instead of silent divergence.
- **Pin seeds, run counts and expected counterexamples.** Three independent implementations reproducing the same shrunk counterexample is strong evidence that draw orders agree.
- **Tell builders their file scope and who else is in the tree.** Shared files (README, `reference.md`, the check scripts) were edited with small replacements after re-reading; there were no lost edits.
- **Ports can run in parallel with the next JS wave** as long as that wave adds fixtures and does not change existing ones.
- **`check-progression.sh` is not enough for cross-cutting features.** Builders hand-made a temp copy of "a student who has not built this yet" each time a dormant field or platform method was added.
- **Ask builders to prove a check can fail.** Each end-to-end check was shown to go red against a deliberately broken copy.
- **Things that went slightly wrong:** one builder ran `git checkout` on a file its script had reformatted (harmless, but against the rules); two builders shared a scratch directory name and a port, and one left a server running; the first draft of the spec had three details that the build corrected (recording delivery, clicks while running, the `tsc` command).
- **A differential test against a pure model is worth more than pixel checks.** The first play script guessed from pixels and could not see text, timing or the speed-up; the Playwright suite compares draw calls frame by frame and covers all of them.