Skip to content

Latest commit

 

History

History
64 lines (44 loc) · 2.17 KB

migration_2.2.md

File metadata and controls

64 lines (44 loc) · 2.17 KB

SCOPE 2.2 Migration Guide

Summary

SCOPE 2.2 unifies grant lifecycle status (exhausted replaces used/consumed) and scopes consume idempotency to (tenant_id, grant_id, idempotency_key) with action_hash conflict detection.

Ledger schema (SQLite / Postgres)

Status semantics

Writers must emit:

State Meaning
active Valid; may have use_count > 0 while uses remain
exhausted Cardinality fully consumed
revoked / expired / superseded / invalid Terminal

Status payloads include use_count, maximum_uses, remaining_uses (alias cardinality_remaining), last_use_event_id, and last_use_sequence. Legacy reads of used / consumed normalize to exhausted.

Idempotency domain

Consume events store action_hash (column and/or event metadata). Uniqueness:

  • Same grant + key + action → replay original consume
  • Same grant + key + different action → idempotency_conflict
  • Different grant + same key → independent

Failed preflight never inserts or reserves a consume idempotency key. Concurrent retries remain serialized (BEGIN IMMEDIATE / advisory lock + FOR UPDATE).

SQLite

Schema version bumps to 3:

  1. Add nullable grant_id and action_hash columns on ledger_events
  2. Drop legacy idx_ledger_idempotency (UNIQUE(tenant_id, idempotency_key))
  3. Create idx_ledger_consume_idempotency on (tenant_id, grant_id, idempotency_key) where event_type = 'grant_used' and key/grant are present
  4. Backfill columns from event_json / metadata

Opening an existing DB with SqliteScopeLedger applies this automatically.

Postgres

On connect, PostgresScopeLedger:

  1. ADD COLUMN IF NOT EXISTS grant_id / action_hash
  2. DROP INDEX IF EXISTS idx_pg_ledger_idempotency
  3. Create idx_pg_ledger_consume_idempotency (same domain as SQLite)
  4. Backfill from JSONB

Operator notes

  • Pre-2.2 DBs that relied on tenant-global idempotency keys across grants must expect cross-grant keys to become independent after upgrade (intended).
  • Duplicate historical (tenant, grant, key) consume rows must be cleaned before the new unique index can be created; fresh installs are unaffected.