Skip to content

Commit 96964b4

Browse files
committed
Bump the session save envelope to v13 after renaming unroll phases.
Old mid-unroll v12 records cannot decode the new semantic_phase names; discard them under the alpha no-migration policy instead of adding aliases.
1 parent 611b872 commit 96964b4

4 files changed

Lines changed: 15 additions & 15 deletions

File tree

FRONTEND_ARCHITECTURE.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@ resumable-session marker, and tab/reset coordination keys, inside the same-origi
398398
trust model described above.
399399

400400
The current and only legal envelope schema is `chia-gaming-session` version
401-
`12`. Because the project is
401+
`13`. Because the project is
402402
still alpha, every other version is deleted wholesale without decoding or
403-
migration. A decoded v12 record must also satisfy the complete phase-owned
403+
migration. A decoded v13 record must also satisfy the complete phase-owned
404404
envelope contract (keyed game membership, game-owned payload/type agreement,
405-
terminal data, and frozen terminal coin list); malformed v12 records are
405+
terminal data, and frozen terminal coin list); malformed v13 records are
406406
deleted rather than partially restored. The boot marker is retained after an
407407
incompatible or malformed resumable record is discarded so the failure remains
408408
visible at the Resume / Start Over boundary. The `version` field is kept as a
@@ -426,7 +426,7 @@ are grouped under those phase-owned payloads:
426426

427427
| Field | Type | Purpose |
428428
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
429-
| `version` | `bigint` | Save schema version; currently `12`. |
429+
| `version` | `bigint` | Save schema version; currently `13`. |
430430
| `playerId` | `string` | Stable local hub/player identity for this browser state. |
431431
| `sessionId` | `string?` | Stable token linking the hub iframe and game-channel WebSocket. |
432432
| `alias` | `string?` | Local hub display alias preference. |
@@ -550,7 +550,7 @@ independently, and the accepted entry is removed only after the hand is fully
550550
settled. Schema version 12 also makes
551551
`gameInstances` plus `lastDisplayedGameId` the only persisted game protocol
552552
presentation and stores the canonical `GameProtocolPresentation` discriminant.
553-
Under the alpha no-migration policy, version 11 and all other incompatible
553+
Under the alpha no-migration policy, version 12 and all other incompatible
554554
records are deleted rather than translated from aggregate current-game fields.
555555

556556
#### Delivery-critical saves
@@ -1572,16 +1572,16 @@ not to limit concurrency.
15721572
| `front-end/src/components/GameSession.tsx` | Game session UI: header, coin status, game area, overlays |
15731573
| `front-end/src/hooks/useGameSession.ts` | Thin React boundary: controller/runtime setup, host subscription, typed dispatch, selector projection |
15741574
| `front-end/src/lib/session/sessionMachine*.ts` | Root dispatcher plus cohesive channel, between-hand, proposal, durable-game, notification, command, effect, runtime, and persistence modules |
1575-
| `front-end/src/lib/session/persistence*.ts` | Canonical strict-v12 phase decoder plus primitive, between-hand/proposal, and phase-payload codecs; accepted records always produce a normalized `SessionModel` |
1576-
| `front-end/src/lib/session/sessionSnapshot.ts` | Canonical `SessionModel`v12 presentation snapshot encoder |
1575+
| `front-end/src/lib/session/persistence*.ts` | Canonical strict-v13 phase decoder plus primitive, between-hand/proposal, and phase-payload codecs; accepted records always produce a normalized `SessionModel` |
1576+
| `front-end/src/lib/session/sessionSnapshot.ts` | Canonical `SessionModel`v13 presentation snapshot encoder |
15771577
| `front-end/src/lib/gameRegistry.ts` | Exhaustive pure feature registration and game-owned codec/terms/compose dispatch |
15781578
| `front-end/src/lib/gameMountRegistry.tsx` | Exhaustive React live/frozen mount registration |
15791579
| `front-end/src/features/calPoker/useCalpokerHand.ts` | Calpoker hook: five-step protocol, card parsing, move submission |
15801580
| `front-end/src/hooks/SessionController.ts` | WASM bridge (`SessionController` class): message delivery, block data, event queue, `getWasmFields()` for persistence |
15811581
| `front-end/src/hooks/WasmStateInit.ts` | WASM initialization: load binary, deposit .hex files, create cradle |
15821582
| `front-end/src/hooks/blobSingleton.ts` | Singleton management: `getOrCreateSessionController` / `destroySessionController`; restore path for session persistence |
15831583
| `front-end/src/services/PeerSession.ts` | Per-session peer state: session ID, peer ID, liveness, message buffering/routing, send methods |
1584-
| `front-end/src/hooks/save.ts` | v12 cache/write and live/terminal lifecycle facade |
1584+
| `front-end/src/hooks/save.ts` | v13 cache/write and live/terminal lifecycle facade |
15851585
| `front-end/src/hooks/saveCoordination.ts` | Resume markers, active-tab lease, and cross-tab persistence fencing |
15861586
| `front-end/src/hooks/saveHardReset.ts` | Hard-reset and WalletConnect browser-storage cleanup |
15871587
| `front-end/src/hooks/savePreferences.ts` | Local preference encoding and decoding |

front-end/src/lib/session/saveEnvelope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
} from './types';
1111

1212
export const SESSION_SAVE_SCHEMA = 'chia-gaming-session' as const;
13-
export const SESSION_SAVE_VERSION = 12n;
13+
export const SESSION_SAVE_VERSION = 13n;
1414

1515
export type BlockchainType = 'simulator' | 'walletconnect';
1616

front-end/src/lib/tests/session_save_envelope.boundary.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe('save boundary enforcement', () => {
5454
expect(await readSessionRecord()).toBeNull();
5555
});
5656

57-
it('deletes an invalid current-v12 game envelope while retaining the boot marker', async () => {
57+
it('deletes an invalid current-v13 game envelope while retaining the boot marker', async () => {
5858
markSavedSession();
5959
await writeSessionRecord(
6060
activeSave({
@@ -69,7 +69,7 @@ describe('save boundary enforcement', () => {
6969
errorSpy.mockRestore();
7070
});
7171

72-
it('deletes a cross-phase v12 payload during hydration', async () => {
72+
it('deletes a cross-phase v13 payload during hydration', async () => {
7373
markSavedSession();
7474
await writeSessionRecord(
7575
baseSave({
@@ -99,7 +99,7 @@ describe('save boundary enforcement', () => {
9999
errorSpy.mockRestore();
100100
});
101101

102-
it('deletes a live v12 record that restoreSession cannot consume', async () => {
102+
it('deletes a live v13 record that restoreSession cannot consume', async () => {
103103
markSavedSession();
104104
await writeSessionRecord(liveSave({ messageNumber: undefined }));
105105
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@@ -125,7 +125,7 @@ describe('save boundary enforcement', () => {
125125
errorSpy.mockRestore();
126126
});
127127

128-
it('deletes a malformed current-v12 metadata envelope read from IndexedDB', async () => {
128+
it('deletes a malformed current-v13 metadata envelope read from IndexedDB', async () => {
129129
markSavedSession();
130130
await writeSessionRecord(
131131
baseSave({

front-end/src/lib/tests/session_save_envelope.validation.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ describe('validateSessionSaveEnvelope', () => {
111111
).toThrow('unexpected');
112112
});
113113

114-
it('decodes one legitimate snapshot for every v12 phase', () => {
114+
it('decodes one legitimate snapshot for every v13 phase', () => {
115115
const preferences = baseSave({ blockchainType: 'simulator' });
116116
const preHandshake = baseSave({
117117
pairingToken: 'pair',
@@ -190,7 +190,7 @@ describe('validateSessionSaveEnvelope', () => {
190190
'waitingStateEnteredAt',
191191
'cleanShutdownGraceStartedAt',
192192
] satisfies Array<keyof SessionPresentationSave>)(
193-
'rejects a v12 presentation missing required %s',
193+
'rejects a v13 presentation missing required %s',
194194
(field) => {
195195
const save = liveSave();
196196
if (save.phase !== 'live') throw new Error('expected live fixture');

0 commit comments

Comments
 (0)