Problem
Over the API adapter, APIAdapter.saveVersion() is a deliberate no-op (adapter-api/src/index.ts:523) — the server is the only snapshot writer, snapshotting prior state as a side effect of each mutating endpoint. But both places the spec enumerates those endpoints list only five:
- §Versions "Storage per adapter" (API bullet): "PATCH /records/:id, associations, permissions, delete, undelete"
- §API Adapter Wire Format → Versions: same enumeration
Two mutating endpoints that do rely on a prior-state snapshot are missing:
POST /records/:id/migrate — Stack.migrateAll() calls saveVersion(record) before commitMigration locally; over the wire that's a no-op, so the server must snapshot on /migrate or the pre-migration state is lost.
POST /records/:id/restore/:version — restore "always creates a new version"; Stack.restoreVersion() snapshots the current state before restoring (stack.ts:1132). A server that doesn't snapshot on /restore makes a restore un-undoable and drops the pre-restore state from history.
A server implementing the literal five-endpoint list silently loses rollback history for migrations and restores — a real drift between the spec's own text and the one-versioning-rule it describes.
Fix
- Spec §Versions ("Storage per adapter") and §API Adapter Wire Format (Versions): add
POST /records/:id/migrate and POST /records/:id/restore/:version to the auto-snapshot endpoint enumeration. State the invariant positively: the server snapshots prior state on every mutating endpoint that bumps version, and list them exhaustively so "which endpoints snapshot" isn't a per-implementer guess.
@haverstack/conformance-fixtures: add fixtures asserting a new version row appears after POST /migrate and after POST /restore/:version (i.e. GET /records/:id/versions count increments), so the contract is pinned where §7's fixtures already enforce the rest of the wire.
Refs
#61 (one-versioning-rule — the invariant the enumeration must match), #62 (restore creates a new version), #52 (conformance fixtures). From docs/design-assessment-2026-07.md §B3 (PR #105).
Problem
Over the API adapter,
APIAdapter.saveVersion()is a deliberate no-op (adapter-api/src/index.ts:523) — the server is the only snapshot writer, snapshotting prior state as a side effect of each mutating endpoint. But both places the spec enumerates those endpoints list only five:Two mutating endpoints that do rely on a prior-state snapshot are missing:
POST /records/:id/migrate—Stack.migrateAll()callssaveVersion(record)beforecommitMigrationlocally; over the wire that's a no-op, so the server must snapshot on/migrateor the pre-migration state is lost.POST /records/:id/restore/:version— restore "always creates a new version";Stack.restoreVersion()snapshots the current state before restoring (stack.ts:1132). A server that doesn't snapshot on/restoremakes a restore un-undoable and drops the pre-restore state from history.A server implementing the literal five-endpoint list silently loses rollback history for migrations and restores — a real drift between the spec's own text and the one-versioning-rule it describes.
Fix
POST /records/:id/migrateandPOST /records/:id/restore/:versionto the auto-snapshot endpoint enumeration. State the invariant positively: the server snapshots prior state on every mutating endpoint that bumpsversion, and list them exhaustively so "which endpoints snapshot" isn't a per-implementer guess.@haverstack/conformance-fixtures: add fixtures asserting a new version row appears afterPOST /migrateand afterPOST /restore/:version(i.e.GET /records/:id/versionscount increments), so the contract is pinned where §7's fixtures already enforce the rest of the wire.Refs
#61 (one-versioning-rule — the invariant the enumeration must match), #62 (restore creates a new version), #52 (conformance fixtures). From
docs/design-assessment-2026-07.md§B3 (PR #105).