AI Initiative logoAI Initiative
Reading room / Game Creation Studio

Learn from play: design v2.4 (current policy)

Separates question-quality advice, shadow difficulty selection, opponent models and factory hints. Defines data handling, model-versus-code authority, frozen comparators, promotion tests and rollback.

Shadow-learning design and pilot-status record
This is the retained source text, not a new validation of its claims. Numerical results and comparative claims require the accompanying source review before public reuse.

Read the connected case study or article →

Not stated in document opening · 2026-10-19

Provenance, authorship and editorial notes

Learn from play: design v2.4 (current policy)

Id

game-platform-proposals-learn-from-play

Project

game-platform

Source path

game-platform/proposals/learn-from-play.md

Source sha256

c71834f94120a2ba83d797c5c7feefcfcb1f0a850d5b06d65f95e5d4f3271499

Repo head

adfb7831984715cb220e4c3c8ba55a66fc7c54fa

Date

2026-10-19

Date provenance

First date near document opening; not independent publication date

Git last change
Not recorded
Author

Not stated in document opening

Document status

Shadow-learning design and pilot-status record

Summary

Separates question-quality advice, shadow difficulty selection, opponent models and factory hints. Defines data handling, model-versus-code authority, frozen comparators, promotion tests and rollback.

Topics
  • AI learning
  • games
  • ANN
  • evaluation
Related ids
  • game-platform-docs-02-architecture
  • game-platform-docs-11-game-factory
  • game-platform-docs-09-multi-agent-workflow
  • game-platform-docs-04-quality-gates
  • modular-ann-docs-head-only-training
Evidence concerns
  • Phase2 not exited; child-visible adaptation not authorized by this record. Test-contract drift, G-L1 admission-cap gap and same-origin switch forgery remain explicitly documented.
Word count

7246

Headings
  • Learn from play: design v2.4 (current policy)
  • 0. Status (as of 2026-10-19)
  • 1. Goal
  • 2. Ground rules
  • 2.1 The model suggests; trusted code decides
  • 2.2 Where data lives (D48, D52)
  • 2.3 Authority and wipe (D49)
  • 2.4 Fail safe
  • 2.5 Saves
  • 2.6 Measured against a frozen comparator
  • 3. What is recorded
  • 4. Learners (separate objectives, separate promotion tests)
  • L2. Bad-question spotter: builder-only, advisory (Phase 1, built)
  • L1. Right-level question picker: SHADOW (Phase 2, wired in Whetstone)
  • Cumulative anti-gaming floor
  • L3. Judge "not sure": DEFERRED (Phase 4)
  • L4. Opponents: two separate objects (D51, D54)
  • L5. Factory risk hints: CI only
  • 5. Relation to the modular ANN research
  • 6. Evaluation design
  • 6.1 Evaluation protocol: required before Phase 3 data
  • 7. Architecture
  • 8. Release gates (executable, evidence retained, rollback = fixed default)
  • 9. Rollout (simplest first)
  • 10. Decisions
  • Appendix A. Revision history
Publication status

Publication or peer-reviewed acceptance not established by discovery

Format

md

Private review scan
Known secret pattern hits

0

Customer or player record sets

None identified in selected narrative/design documents; no gameplay records, account databases or hand datasets copied.

Scope

Pattern scan plus document review; not a formal exhaustive privacy audit.

Learn from play: design v2.4 (current policy)

This is the single current policy for learning from play. It replaces v2, the v2.1 working copy, v2.2 and v2.3. Older text and review provenance are in Appendix A ("Revision history"); they are history, not policy.

Requested by the operator on 2026-10-19 ("how can we use ANN to learn from the output of these games and be smarter over time"). Binding operator decisions: D48–D52 and D54 (maneet-games/master-mind/review-2026-10-15-platform/FINAL-PLATFORM-AND-IMPROVEMENTS.md, rows 48–52 and 54). Where this file and a decision row disagree, the decision row wins and this file is wrong.

0. Status (as of 2026-10-19)

Approved: Phases 1–2, shadow only (D50). Not approved: anything child-visible. Going live (Phase 3) needs a new operator decision plus the §6.1 evaluation protocol.

Built in the pilot (per the pilot report; in maneet-games/master-mind):

Known gaps (open; none is hidden by this document):
1. The switch cannot be enabled from a child's own claude.ai account. That needs a hub-side or db-backed operator grant, which is a future decision (§10).
2. Storage-integrity limitation of Phase 2 shadow capture (§2.3, D49, D52). The privileged APIs (operatorEnable, operatorWipe) do check the hub owner. But routine start() trusts the mm-learn-op localStorage record once it is present, and any same-origin script can forge that record. A forged switch can start bounded shadow recording, and the recorded learn key then syncs to the hub cloud copy (§2.2). There is no child-visible effect. Resolving this is an operator choice (§2.3, §10).
3. Wipe is implemented for Whetstone only. Per the pilot report, Whetstone is also the only game wired to learn.js, so no other game holds learning state yet; this has not been independently re-verified. §2.3 makes it a precondition: no further game records until its namespace is in the wipe scope and passes G-L5.
4. Whetstone's pre-existing save caps (its own migrate caps: 200 skills, 400 facts, 200 pb) can produce a progress + .bak payload over 100,000 bytes. That is not caused by learning: such a save already falls back to device-only today. It does mean the v2.4 G-L1 gate, measured at the admitted caps, can fail for Whetstone until those caps are lowered or the claim is narrowed (§8).
5. The §4 mastery history, G-L7b and the §6.1 protocol do not exist yet. All three are Phase 3 entry conditions.
6. The built claims above come from the pilot report. The ANN reviews (seq 8495, 8504) did not audit code or run tests, and neither did this revision.
7. Test-contract drift. ci/learn-gates-test.mjs still identifies its contract as design v2.1, and it implements G-L1..G-L8 only. G-L7b is not counted as implemented until a test exists. The decision row D50 says "G-L1..G-L8 before any live step". This design adds G-L7b as a further condition and does not edit the D50 row.
8. Code TODO (not edited here): the operatorWipe comment in games/_factory/learn.js (:307) cites "§2.3 wipe" from v2.1. It should cite design v2.4 §2.3.

1. Goal

Each game should get better the more children play. The goal is not "more data"; it is three measurable things:

2. Ground rules

2.1 The model suggests; trusted code decides

2.2 Where data lives (D48, D52)

WhereWhatWho can read itState
Devicelearning summaries under a dedicated learn keyany first-party game script on the hub origin (same-origin, see below)ON only while the operator switch is on for that player
Hub cloud copythe same learn key, synced by MM.store → MM.data to data/users/<uid>/sdk~<game>~<pid>the signed-in account; artifact owner per db rulesON together with the device copy when the child is signed in (D48). The SDK has no local-only option, so this is stated, not hidden
oldisgold / any aggregateno child data. oldisgold holds bot-vs-bot self-play only (L4a, D51)—child-data export OFF (D48). §7.3 lists what an export would need

2.3 Authority and wipe (D49)

2.4 Fail safe

Missing, corrupt or newer state, a new game, too little data, or learning switched off all give exactly today's behaviour: the fixed ladder and the default bot.

2.5 Saves

2.6 Measured against a frozen comparator

Nothing reaches children until it is authorised by a new operator decision (D50), and general release needs G-L9 (§8). Otherwise it stays off.

3. What is recorded

Prefer compact sufficient statistics over raw events. For example, keep per-skill counts and a rating plus per-item counts, not an event log. Per learner:

LearnerState keptBounded
L1per skill: rating, attempts, correct; plus the §4 mastery history (a monotone deque of per-session mastery maxima stored as session ages, and per-level last-four outcomes for the current skill-session). No absolute session counter is stored, and no timestamps≤ 60 skills, and the whole learn key + .bak ≤ 8,000 bytes (worst case in §4)
L2per item/template: attempts, wrong, "marked-wrong-but-looked-right" count, distractor counts, response-time bucket histogrambuilder-only report, offline; never in child saves
L3per judge bucket: confident verdicts, overrules (noisy signal)≤ 50 buckets
L4a bot balancenothing per child. Balance and fixed level tables are game code, built offline from bot-vs-bot playnot in saves
L4b per-child controller (proposal only, §4)would store, per child, one Elo per game modetiny

Only IDs and enums cross the learner boundary. Display text is always resolved from trusted templates and passes through the D45 ingest and the D40 fail-closed display sink at final render.

Size. The 100,000-byte cloud cap covers the game's whole payload. The learning namespace gets a measured budget of at most 8,000 bytes, including its .bak copy, JSON/key overhead and per-key timestamps (the built learn.js measures it as stored), with:

No "N events" promise stands in for a byte guarantee.

Multiple devices. Sync is newest write per key wins, with no merge, so two devices can overwrite each other's learning state. This is an accepted risk, not a recoverability guarantee: the local .bak restores only the last good state on that device, and there is no cross-device restore contract. A stale device's write can erase another device's mastery history, so the §4 floor is a per-device continuity guarantee (G-L7b scope). A merge protocol would be a separate design with its own tests.

4. Learners (separate objectives, separate promotion tests)

Player mastery, the opponent policy and any shared representation are different learned objects. Each gets its own labels, objective and promotion gate.

L2. Bad-question spotter: builder-only, advisory (Phase 1, built)

L1. Right-level question picker: SHADOW (Phase 2, wired in Whetstone)

Cumulative anti-gaming floor

The per-session bound alone lets repeated failures ratchet difficulty down one step per session. So, for each skill:

Mastery history (state per skill). One stored maximum cannot work. Example (levels illustrative, W = 10): history A = [(level 10, session 1), (level 7, session 2)] and history B = [(level 10, session 1), (level 9, session 2)] both have current maximum (10, 1). When session 1 expires, the correct M is 7 for A and 9 for B, which a single maximum cannot tell apart. So each skill keeps:

FieldMeaningBound
mhmonotone deque of (age, level) per-session mastery maxima. age is the number of skill-sessions since the mastery was shown (0 = the current skill-session). Ages strictly decrease and levels strictly decrease from front to back. An entry that a newer, equal-or-higher entry dominates can never be the maximum again, so it is droppedat most min(W, number of ladder levels) entries; 7 for Whetstone's levels 1–7. Every age is in 0 … W − 1
roper level, the outcomes of the last four attempts in the current skill-session, with a count 0–4one value per ladder level; reset at each new skill-session

A skill-session is a game session in which the skill was played at least once.

No absolute session counter is stored (bounded rebasing). v2.3 stored an absolute per-skill counter s in two base-36 characters, which covers only 0–1,295 and would wrap or overflow at 1,296. v2.4 stores ages relative to the current skill-session instead. Each new skill-session rebases all retained entries together: every age goes up by 1, and entries reaching W are dropped. Ages, window membership and order are all preserved, and every stored value is bounded by W − 1 however long a child plays. Constraint: W ≤ 36, so an age fits one base-36 character. A W above 36 needs a new encoding and a migration. There is no silent wrap: a stored age outside 0 … W − 1 fails validation (below). An implementation may keep an absolute counter in memory only; if one is ever persisted, it must use variable-width encoding with a measured worst-case cap inside the budget.

Mastery criterion: at least 3 correct of the last 4 attempts at a level, within one skill-session. Fewer than 4 attempts at a level never counts as mastery. Because ro resets each skill-session, old outcomes cannot combine with a single new attempt to credit mastery.

Expiry boundary. The window is the current skill-session and the W − 1 before it, i.e. ages 0 … W − 1. Mastery shown at skill-session s0 has age W − 1 at s0 + W − 1 (still in the window) and age W at s0 + W (expired).

Update order (per attempt at skill k, level ℓ):
1. If this is the first attempt at k in this game session: add 1 to every deque age; drop entries whose age is now ≥ W; reset ro.
2. M = the level at the deque front, or none if the deque is empty.
3. Floor = max(ladder floor, M − K) if M exists, else the fixed ladder's own placement. The suggestion (logged only, in shadow) is computed now, so expiry happens before the suggestion.
4. Record the outcome in ro[ℓ].
5. If ro[ℓ] has 4 outcomes and at least 3 are correct, credit mastery (age 0, ℓ):
- if the deque tail is (0, ℓ') with ℓ' ≥ ℓ, do nothing;
- otherwise pop tail entries whose level is ≤ ℓ (equal levels: the newer entry wins, since it expires later), then append (0, ℓ).
6. Persist, subject to the budget. Mastery credited mid-session raises the floor for later attempts at once; it never lowers it.

Validation on load (untrusted input, §2.1): ages are integers in 0 … W − 1 and strictly decrease from front to back; levels strictly decrease and lie in the ladder range; the deque is no longer than its bound; ro counts are 0–4. If any check fails, that skill's mastery history is dropped and the floor falls back to the fixed ladder's placement (§2.4); it never falls below it.

Multi-device scope: per-device continuity (recommended for Phases 2–3). Sync is whole-key newest write wins (§3). A stale device that reconnects and writes can overwrite a newer mastery history and erase its high-water mark, and the overwriting record may be internally valid. So the guarantee is scoped:

Serialised size. Proposed compact encoding per skill: each deque entry as 2 base-36 characters (1 for the age, 1 for the level); each level's ro as 1 base-36 character (count plus outcome bits form 31 states). No session counter is stored. For Whetstone (7 levels) the worst case is about 14 + 7 characters plus separators and quoting, so ≈ 26 bytes per skill per copy. At 60 skills, with the .bak, that adds about 3.1 KB to the existing per-skill state. This is an estimate, not a measurement. G-L1 must re-measure the worst case of the whole learn key + .bak as stored, with the mastery history included, against the same 8,000 bytes. If it does not fit, the number of skills that carry a mastery history is lowered (skills without one fall back to the ladder placement). The budget is not raised.

L3. Judge "not sure": DEFERRED (Phase 4)

L4. Opponents: two separate objects (D51, D54)

L4a. Bot balance (approved, D51)L4b. Per-child difficulty controller (proposal only)
What it isoffline self-play balance tables and fixed bot level tables for Anime Punch and Fish Ita local controller that adapts one child's bot level from that child's own results
Consumesbot-vs-bot self-play only. No child datathat child's own match outcomes (win/loss per match, per game mode) and their chosen start level (D54). No timing, no free text
Runs whereoldisgoldin the browser, on the child's device
Storesbalance and level tables as game code, shipped through normal releasesone Elo per game mode in the dedicated learn key: device + hub cloud copy (D48), inside the 8 KB budget
Exportstables only; they hold no child datano additional aggregate or export beyond its declared hub sync: the learn key syncs to the child's hub cloud copy (D48) like all learning state, and nothing goes to oldisgold, aggregates or server-side training
Success measurebalanced bot-vs-bot outcomes; fixed level tables can be assessed on their ownthe child's win rate settles at 50–60%. This is difficulty adaptation, not evidence of learning
Statusruns in parallel (D51); child-visible changes ship only through normal releasesnot authorised. D51 covers bot-only data. D50 approved only the L1 Whetstone shadow pilot. D54 fixes the start level if the adaptive bot is switched on, but it does not decide whether child outcomes may be used. Whether L4b may consume child outcomes is an open decision (§10). If approved: behind the operator switch, shadow first, bot outputs clamped

L5. Factory risk hints: CI only

5. Relation to the modular ANN research

R1/R2 (the selective-training study) is proposed future research under review. Its results do not automatically qualify game transfer or child personalisation.

A shared trunk with per-game heads is an experimental arm against the simple per-game baseline, not the target architecture. Log-loss is lower-is-better, and the two quantities are defined with that direction:

Adoption rule (predeclared, Phase 5):

τ, the confidence level and the other exact numbers are fixed in the Phase 5 plan before any data is looked at.

6. Evaluation design

6.1 Evaluation protocol: required before Phase 3 data

Phase 3 collects no data until a written evaluation protocol exists. It must be:

It must state, at minimum:

ItemRequired content
PurposePhase 3 produces feasibility, calibration, safety and exploratory within-child evidence. It is not general-release evidence and cannot meet G-L9
Primary estimandexactly one, e.g. the within-child difference in held-out check accuracy (or log-loss, with direction stated as in §5) between L1 and fixed-ladder conditions
N / powerfor Phase 3: the explicit label "exploratory, single-child; no confirmatory claim". A power calculation is required only on the confirmatory route (§9, Phase 3C)
Carryoverchildren keep what they learn, so a crossover does not reset knowledge and a washout does not undo learning. The protocol picks one design and justifies it: (a) arm by skill family: disjoint skill families randomly allocated to L1 or the ladder, with cross-family transfer reported; or (b) a period crossover with a stated period × arm analysis and its carryover limits; or (c) parallel groups across children (confirmatory route only). A washout alone is not accepted as handling carryover
CI methodthe named method (e.g. a block bootstrap over sessions, or a permutation test over the randomised allocation), the number of resamples, and the confidence level
Denominators and missing datathe assignment denominator (every scheduled held-out and delayed check counts, as in intention-to-treat); how missing held-out or delayed outcomes are handled and reported; how human inactivity and stalls are classified; human quits stay in the denominator; automation stalls are excluded and listed
Stop rulesthe fixed duration and allocation schedule; safety stops that trigger instant rollback to the fixed ladder (operator instruction, a child-distress or quit-rate threshold stated as a number, any gate going red). Every safety stop is reported with its trigger. No early stop for efficacy unless an alpha-spending rule is predeclared
Multiplicitythe single primary; for the secondaries, either a named correction (e.g. Holm) or the label "descriptive only"
Holdout manifestthe fixed manifest file sha256 and seal hash. Current candidate: ci/learn-holdout-manifest.json, seal dcf9ddf92f64fe6934e850f33410ee204c3d00378e35039facf9d3799409b888. The protocol pins whatever is current at authoring; G-L8 enforces it
Anti-gaming configthe values of K and W (§4)
Analysis planinclusion/exclusion rules (human play only), and what is reported if the result is null or negative

The confirmatory protocol (Phase 3C) is a separate document with the same rules plus: the intended population (the children a general release would reach), the independent unit (the child, not the session or the item), a power calculation giving N in children, and a randomised design from the carryover options above.

7. Architecture

1. Module learn.js in the factory kit (games/_factory/learn.js, standalone):
- learn.observe(id, enumOutcome) records an outcome, schema-validated;
- learn.suggest(eligibleIds) returns an ID that must be one of eligibleIds; the caller re-checks;
- learn.flag() is builder-only;
- learn.botLevel() is clamped and starts at the player's chosen level (D54). It adapts from child outcomes only if L4b is approved (§4, §10);
- learn.wipe() follows the §2.3 scope.
2. Storage: MM.store("<game>-learn-v1", {v:1,…}, migrate), a dedicated key with in-place migration (D42) and the ≤ 8,000-byte budget (§3). The §4 mastery history is a schema addition, so it needs a migration and the G-L6 checks. MM.store syncs to the hub cloud copy for signed-in children; that is the D48-approved path. The operator switch (mm-learn-op) is device-only and is not stored here.
3. Aggregates: OFF (D48). Not built. If ever proposed, they need:
- a closed aggregate-only export schema: no UID, no per-child rating, no rows, no arbitrary keys;
- bounded contribution per child;
- minimum cohort and rare-cell suppression;
- release cadence and query controls;
- revocable opt-in that cancels queued uploads;
- a new operator decision.
With one family the cohort is too small, so the answer today is no export.
4. Compute: in the browser, simple statistics only. Training experimental neural or shared-trunk arms offline is part of the Phase 5 research that produces the §5 evidence. Shipping fixed, versioned weights to children happens only after that evidence meets §5. L4a self-play runs on oldisgold with bot-only data (D51).

8. Release gates (executable, evidence retained, rollback = fixed default)

GateChecks
G-L1 budgetthe gate FAILS if the measured combined per-game payload (progress + .bak + learning + .bak), built at the admitted caps (the game's own migrate caps and the learning caps), reaches 100,000 bytes or leaves less than the stated progress headroom. Logging the worst case is not enough. The learning namespace, including the §4 mastery history at its worst case, is ≤ 8,000 bytes including overhead; overflow trims and recovers. If a game's own pre-existing caps make this impossible (Whetstone today, §0 gap 4), there are two options: lower those caps (a game change), or narrow the claim to "the realistic payload fits". A narrowed claim is stated in the gate output and in §0, and is never reported as the admitted-cap result. The current test (v2.1 contract) passes only the realistic case
G-L2 fail-safemissing, corrupt or newer state, and switch OFF, give exactly the fixed behaviour; tested
G-L3 sinkplant-and-render runtime tests with unsafe, corrupt or newer learning state, checked in the DOM, attributes, canvas and document title
G-L4 trusted boundarysuggest can't return an ID outside the eligible set; injected bad IDs are rejected
G-L5 wipewiping clears local and cloud state in every game namespace that records, cancels pending writes, reads back as clear, and leaves unrelated unknown fields preserved. Run per game before that game may record
G-L6 migrationunknown fields survive; newer versions are quarantined, not deleted
G-L7 anti-gaming (session)adversarial failure trajectories within one session can't push difficulty more than one step below the session start, or below the floor
G-L7b anti-gaming (cumulative)runs on the shadow "would have chosen" log. Cases: (1) mastery shown at level m in session s0, then all-failure sessions: the suggestion is never below max(ladder floor, m − K) at sessions s0 … s0 + W − 1, and the floor may relax only from s0 + W; (2) several maxima: the A/B example in §4 gives M = 7 and 9 after expiry; (3) ties: an equal level in a later session extends the window; (4) fewer than 4 attempts never credits mastery; (5) a corrupt mastery history, including an age outside 0 … W − 1, falls back to the ladder placement; (6) long play / encoding boundary: a skill played across the 1,295 → 1,296 skill-session boundary (and well beyond, e.g. 1,400 sessions) keeps every stored age in 0 … W − 1, with no wrap or overflow, and gives the same floor as a fresh history with the same recent sessions; (7) stale-device overwrite / reconnect: device A shows mastery at level m; device B, holding an older copy, reconnects and writes last. Device A's next suggestion follows the surviving record, is never below the ladder placement, and the test records the high-water mark as lost (per-device scope, §4). It does not assert a player-wide floor. Scope: per-device continuity. Not implemented: no test exists yet (§0 gap 7)
G-L8 holdout integritythe sealed manifest matches the hash pinned in §6.1; no overlap between training and holdout lineage
G-L9 promotiongeneral release of live L1 only if the held-out learning gain against the frozen comparator has a CI lower bound above 0, under the confirmatory protocol (Phase 3C) with its N/power met. An "exploratory, single-child" result cannot meet G-L9. Band occupancy is never a promotion gate
Cross-game read (documents)a game can read another game's learn key: expected to succeed today and recorded as such (D52). It becomes a denial test only when isolation ships

9. Rollout (simplest first)

PhaseWorkChild-visible?Status / exit
0Operator decides the boundary, authority and pilot—done: D48–D52, D54
1Check Whetstone's save/event coverage; run L2 offline on synthetic and replayed historical dataNobuilt; flags the known old bugs (§0); builder report
2L1 in shadow mode in Whetstone, operator-enabled for one child; learning state on the device and the hub cloud copy (D48), no exportNowired, not exited. No pilot enablement or collection until G-L1 passes as defined in §8 for the pilot state (or the operator accepts the narrowed claim), so that progress saves are never put at risk. Exit: calibration measured; G-L1..G-L8 green under a test contract updated to v2.4; the §4 mastery history built and G-L7b green; §0 gaps 3–4 closed for Whetstone
3Bounded live pilot: L1 against the fixed ladder, one child, fixed duration, instant rollback. It produces feasibility, calibration, safety and exploratory evidence only; it cannot meet G-L9. Requiring proven benefit before any trial would be circular, so none is requiredYesentry: a new operator decision (D50) and the dated, version-pinned §6.1 protocol and G-L1..G-L8 plus G-L7b green, under a test contract updated to v2.4. (The D50 row says G-L1..G-L8; G-L7b is this design's added condition.) Exit: protocol-reported result, labelled exploratory
3CConfirmatory evaluation, prospectively specified in its own protocol (§6.1): intended population, the child as the independent unit, power-based N, randomised design with carryover handledYesentry: its own operator decision and frozen protocol. It needs more than one child, so it may need a decision on cross-child data handling first (§10). With one family it may be infeasible; then G-L9 is not met and live L1 is not generally released. That is an acceptable outcome
—General release of live L1 to all playersYesG-L9 met on Phase 3C evidence
L4a (parallel)Bot balance: self-play on oldisgold, bot-only data (D51); changes ship through normal releasesVia releasesown gates
L4bPer-child adaptive bot level (§4): proposal only—needs an operator decision on child-outcome use; then shadow first, starting at the chosen level (D54)
4L3 judge "not sure", only after the pl21 judge contract shipsYesown gates
5Neural or shared-trunk arm: offline research, then adoption only per §5—predeclared G lower bound > 0 and every D_g upper bound ≤ τ

10. Decisions

Decided (operator, 19 Oct 2026):

Open (for a future operator decision):
1. D49 meaning and the operator grant (§2.3). Either (A) "operator-only" is UI authority under the trusted-first-party-code assumption, with forged-switch shadow recording accepted as a residual; or (B, recommended) require an unforgeable hub-side or db-backed operator grant before any collection. (B) also lets the switch be enabled on a child's own claude.ai account (§0 gap 1).
2. G-L1 for Whetstone (§8): lower Whetstone's own save caps so the admitted-cap gate can pass, or accept a narrowed "realistic payload" claim.
3. Phase 3 go-live: authorise the bounded live pilot, with the §6.1 protocol attached.
4. Phase 3C: whether and how to run a confirmatory evaluation (population, cross-child data handling), with its own protocol.
5. L4b: whether a per-child bot controller may consume that child's match outcomes on device (§4).
6. Storage isolation: adopt the proposals/storage-isolation.md design (a separate platform project).
7. Numbers: K and W (§4; W ≤ 36 under the current encoding), and τ and the confidence levels (§5), each fixed before the data they govern.
8. Player-wide floor: whether the §4 floor should later become player-wide through a monotonic merge (not required for Phases 2–3).


Appendix A. Revision history

Versionsha256What changed
v17243190113d7f1838893719e37174dd4651fec7cfe005ccdb24abe522d2edc97first draft
v2eac0771a85432175743962583a993823741f8a98f0c2439f4998261be1a40acdfolded 19 review findings, none rejected: Codex master-mind-games seq 1012 (10), codex-ann-coordinator ANN seq 8421 (6), muse-alpine-libra ANN seq 8416 (3). Codex's SDK claims verified at games/_sdk/mm-sdk.js:25,27,55,57,99 and docs/02-architecture.md:92-110 (CLOUD_MAX 100,000 bytes for the whole payload, newest write wins, no opts.merge). Mapping: privacy/data locations → §2.2/§7.3; trusted boundary → §2.1/§7.1/G-L4; sink → §3/G-L3; size and sync → §3/G-L1; authority and wipe → §2.3/G-L5; L1 metric → §4/§6/G-L9; L3 cap → §4; gates → §8; build order → §9; R1/R2 status → §5; separate objectives → §4; human play only → §6
v2.15645df3780b99ec32fc55c314098ef616ceb57e713fa40a08f91e1d039ba1587working copy, never frozen at the time; it is the exact artifact Codex hashed in seq 1047 and 1066, snapshotted afterwards (a retrospective snapshot, not a historical freeze). Added §12 amendments from round 2 (Codex MM seq 1019/1022/1029, coordinator ANN seq 8426/8430): cloud path via MM.store, budget including .bak, same-origin boundary, G/D direction, live trial vs release, quit denominators, and the D48–D52 decided list. Left the v2 body unchanged, so it contradicted itself
v2.208324a7976b2d8ce99efcd83edc92cb1d92a4f8c0377f8c97b3b93496b50d714one current policy. Resolved Codex seq 1047/1066: §2 table, §9 Phase 2 and §10 rewritten to the decided state (D48–D52, D54); old questions removed; added the cumulative floor and G-L7b; added the §6.1 pre-data evaluation protocol as a Phase 3 entry condition; multi-device loss restated as an accepted risk; added §0 Status and known gaps from the pilot; history moved here
v2.3bcf68c80af35e2c6dfa8eabffee5e77c8d7cf87bfeb3e9012fdb3ffda68a69cbfolded the ANN coordinator's v2.2 review. Provenance: the coordinator requested the four amendments at ANN seq 8495 (REVIEW.json 58b51f18…, manifest 3f066949…); the author accepted them at ANN seq 8497; the coordinator's root readback of v2.3 is ANN seq 8504 (REVIEW.json fc0cde9a…), which accepted the substance with two document corrections (folded in v2.4). That readback is design acceptance, not code verification. (v2.3's own text said "the coordinator accepted all four amendments", which conflated these steps.) LFP22-1: bounded mastery history (per-skill session counter, monotone deque of per-session maxima, per-level last-four outcomes), minimum 4 attempts, update order, expiry boundary, load validation, size estimate, and G-L7b cases including the A/B example. LFP22-2: Phase 3 is feasibility/calibration/safety/exploratory only; new Phase 3C confirmatory route; carryover handling in §6.1; G-L9 unchanged in strength. LFP22-3: intersection–union non-inferiority, where every D_g upper bound must be ≤ τ, with signed G and every D_g always reported. LFP22-4: L4 split into L4a bot balance (approved) and L4b per-child controller (proposal). Minor notes folded: C1 bounded guarantee and indexing; C2 single primary, denominators, missing data, safety-stop reporting; C3 wipe precondition and unverified built claims; C4 offline research vs shipping weights. Phase numbering as in v2.2 (Phase 4 judge, Phase 5 neural)
v2.4(this file)folded the ANN coordinator's root readback of v2.3 (ANN seq 8504, REVIEW.json fc0cde9a5bce731b…, sha verified) and codex-game-review on v2.2 (master-mind-games seq 1097 and its precision follow-up 1098; still relevant to v2.3). Triage: raised 12 (8504: 4; 1097: 4; 1098: 4). 1098-1 and 1098-2 duplicate 1097-1 and 1097-2 and refine them, so there are 10 distinct findings. Folded 10. Rejected 0. Code claims checked against source before folding: start() trusts only readSwitch() (learn.js:184), while operatorEnable and operatorWipe call ownerCheck() (:283, :312); the G-L1 admitted-cap case is only console.logged, not asserted (learn-gates-test.mjs:323-325); the test header names design v2.1 (:1); the stale wipe comment is at learn.js:307. Folded: 8504-1 session counter replaced by bounded ages (rebased together each skill-session, W ≤ 36, no wrap), plus G-L7b case 6 at 1,295 → 1,296; 8504-2 appendix provenance (requested 8495 / accepted 8497 / readback 8504); L4b wording "no additional aggregate or export beyond its declared hub sync"; IUT scoped to the fixed predeclared comparison; 1097-1/1098-1 D49 residual restated as a storage-integrity limitation of Phase 2 shadow capture, with an operator choice: (A) UI authority under trusted first-party code, or (B) an unforgeable hub/operator grant (recommended); 1097-2/1098-2 G-L7b scoped to per-device continuity with a safe ladder fallback, player-wide merge left as a future option, and G-L7b case 7 for stale-device overwrite/reconnect; 1098-3 G-L1 must fail at the admitted caps, or the claim is narrowed; Whetstone's pre-existing caps noted; 1097-4 Phase 2 marked not exited, with no enablement or collection until G-L1 passes; 1097-3 §2 given real 2.1–2.6 subsections so the §2.x references resolve, and the learn.js:307 comment recorded as a code TODO (code not edited); 1098-4 test-contract drift recorded: the test file is the v2.1 contract, G-L7b is not counted as implemented, and D50's G-L1..G-L8 wording is noted against this design's added G-L7b condition

Continue exploring