feat: anchor first checkpoint for cold restart

This commit is contained in:
MaxTomahawk
2026-08-11 08:59:47 +02:00
parent 4e20f4585f
commit 4db97164bb
9 changed files with 305 additions and 19 deletions
@@ -11,11 +11,13 @@ checkpoint, title, save-slot, and no-mod parity suites.
A tool checkpoint may be the first durable record of a new playthrough. The
engine intentionally keeps normal Pokémon SAVE independent: before the first
normal write, identity is retained by the engine-owned selected-slot mapping,
while title starts with a fresh New Game skeleton. Calling ordinary active
while title starts with a fresh New Game skeleton. A durable checkpoint tool may
explicitly create one ordinary progress anchor after its first checkpoint has
committed; later tool writes must remain independent. Calling ordinary active
`mod.storage` there would allocate/adopt an identity, and live
`mod.checkpoints:restore` correctly refuses title because it has no gameplay
rollback state. A generic title capability is required; a tool must not use
private storage paths, slot ids, or a hidden normal SAVE.
rollback state. Generic public capabilities are required; a tool must not use
private storage paths, slot ids, or simulate the player's SAVE menu flow.
## Additive public API
@@ -40,6 +42,21 @@ Its detached context can include only `normalSavedAt` from a matching ordinary
save, so title tools can apply their own resume policy without receiving the
canonical normal-save record.
### `mod.checkpoints:ensureNormalSave(game, checkpoint)`
Available only at a live checkpoint-safe boundary. After a tool has durably
committed the supplied current checkpoint, it may request an ordinary progress
anchor for a playthrough that has never had one. The engine validates the
checkpoint, proves it exactly matches a fresh capture of the live runtime, and
uses the normal atomic save path including `save.write` lifecycle/veto hooks.
The operation is idempotent. It returns `true, "already_exists"` without writing
when matching normal progress already exists, so later checkpoints never move
the vanilla CONTINUE target. A stale/non-current checkpoint, unsafe runtime,
write veto/failure, or failed readback returns a structured failure. A tool
should call it only after its own checkpoint and index are durable and must not
report that first checkpoint as successful if the required anchor fails.
### `mod.checkpoints:resume(game, checkpoint)`
Available only from title. It validates format, data-only structure, selected
@@ -50,7 +67,7 @@ recaptures before committing. On success it emits `checkpoint.restored` once.
Title has no live runtime rollback. A reconstruction or verification failure
therefore rebuilds a clean title session from the pre-operation title save and
RNG; it emits no success event and never writes normal progress. Validation
RNG; it emits no success event and never rewrites normal progress. Validation
failure leaves the existing title session untouched. Stable errors include
`not_at_title`, `no_selected_playthrough`, normal checkpoint validation codes,
`resume_failed`, and `title_recovery_failed`.
@@ -65,9 +82,11 @@ does not rewind with a checkpoint; canonical `game.save` / `mod.save` does.
## Verification
The public SDK test starts a fresh playthrough, stores tool history without a
normal SAVE, simulates title/restart, reads the selected binding without
The public SDK test starts a fresh playthrough, stores tool history, creates and
readback-verifies exactly one normal anchor, proves subsequent calls do not
rewrite it, simulates title/restart, reads the selected binding without
allocating title identity, resumes an overworld checkpoint, preserves options,
performs no normal SAVE, differentially recaptures, and confirms a later
explicit NEW GAME receives another identity. Existing no-mod, storage,
checkpoint, battle, and title suites prove additive parity.
differentially recaptures, and confirms a later explicit NEW GAME receives
another identity. A separate two-process disk test proves cold-start routing and
reconstruction. Existing no-mod, storage, checkpoint, battle, and title suites
prove additive parity.