packages feed

kioku-migrations 0.10.0.0 → 0.11.0.0

raw patch · 5 files changed

+81/−16 lines, 5 filesdep ~kioku-migrationsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: kioku-migrations

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -2,6 +2,13 @@  ## [Unreleased] +## 0.11.0.0 — 2026-10-19++### Added++- Migration `0015-active-memory-recency.sql` adds an active-only memory-space/namespace/creation-time/ID index. It builds inside the migration transaction with a SHARE lock: reads continue while writers wait for commit.+- A previous fourteen-entry Kioku manifest-prefix upgrade test proves only 0015 applies and existing Memory values remain unchanged. The composed plan has 62 entries (15 Kiroku, 32 Keiro, 15 Kioku); all shipped SQL and checksums are preserved and no ledger fixup is needed.+ ## 0.10.0.0 — 2026-10-19  ### Changed
kioku-migrations.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: kioku-migrations-version: 0.10.0.0+version: 0.11.0.0 synopsis: Schema migrations for kioku description:   Owns kioku schema evolution as a native pg-migrate component and composes@@ -93,7 +93,7 @@     directory >=1.3 && <1.4,     ephemeral-pg >=0.3.1 && <0.4,     keiro-test-support ^>=0.21.0.0,-    kioku-migrations ^>=0.10.0.0,+    kioku-migrations ^>=0.11.0.0,     text >=2.0 && <2.2,     unix >=2.8 && <2.9, @@ -116,7 +116,7 @@     containers >=0.6 && <0.8,     hasql >=1.6,     keiro-migrations ^>=0.21.0.0,-    kioku-migrations ^>=0.10.0.0,+    kioku-migrations ^>=0.11.0.0,     kioku-migrations:test-support,     kiroku-store-migrations ^>=0.7.1.0,     pg-migrate ^>=1.2.0.0,
+ migrations/0015-active-memory-recency.sql view
@@ -0,0 +1,7 @@+-- Active recency ignores priority. The namespace page index is priority-first+-- and therefore requires sorting the whole matching population for this query.+-- This additive index builds in the migration transaction (not CONCURRENTLY):+-- reads continue, but writers wait for the build/transaction to finish.+CREATE INDEX IF NOT EXISTS memories_space_active_recency_idx+  ON kioku.memories (memory_space_id, namespace, created_at DESC, memory_id ASC)+  WHERE status = 'active';
migrations/manifest view
@@ -12,3 +12,4 @@ 0012-relocate-projections-to-kioku-schema.sql 0013-partition-aware-fts-index.sql 0014-bounded-session-memory-pages.sql+0015-active-memory-recency.sql
test/Main.hs view
@@ -88,6 +88,7 @@           testCase "public schema (long-lived dev databases)" (assertRegistryBump "public")         ],       testCase "the full migration chain applies to a fresh database" testFreshDatabase,+      testCase "0.10.0.0 upgrades with one recency index and unchanged rows" testRecencyUpgrade,       testCase "the released previous cohort preserves data and checkpoints through 0013–0015" testPreviousCohortUpgrade,       testGroup         "migration-session isolation"@@ -462,7 +463,7 @@   old <- either (assertFailure . show) pure (migrationPlan (oldKiroku :| [keiro, kioku]))   current <- either (assertFailure . show) pure kiokuMigrationPlan   installed <- runMigrationPlan defaultRunOptions settings old >>= either (assertFailure . show) pure-  length (appliedNow installed) @?= 58+  length (appliedNow installed) @?= 59   withConnection connStr $ \conn -> do     run conn (Session.script previousCohortSeed)     -- Seed all seven application projections using the existing preservation fixture.@@ -480,12 +481,12 @@   verification <- verifyMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure   let VerificationReport {issues, appliedMigrations, pendingMigrations, unknownMigrations} = verification   issues @?= []-  length appliedMigrations @?= 61+  length appliedMigrations @?= 62   pendingMigrations @?= []   unknownMigrations @?= []   repeated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure   let MigrationReport {results} = repeated-  length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 61+  length [() | MigrationResult {outcome = AlreadyApplied} <- toList results] @?= 62   appliedNow repeated @?= []   query connStr previousCohortSnapshot >>= (@?= before)   query connStr previousCheckpointSnapshot >>= (@?= checkpointsBefore)@@ -591,7 +592,7 @@         runMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan           >>= either (assertFailure . show) pure       let MigrationReport {results = repeatedResults} = repeated-      length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 61+      length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 62       length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0       verification <-         verifyMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan@@ -710,10 +711,10 @@     plan <- either (fail . show) pure kiokuMigrationPlan     let settings = Settings.connectionString connStr     initial <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure-    length (appliedNow initial) @?= 61+    length (appliedNow initial) @?= 62      baselineLedger <- query connStr fullLedgerSnapshot-    fst baselineLedger @?= 61+    fst baselineLedger @?= 62     baselineSchema <- query connStr cohortSchemaSnapshotStatement     fixup <- Text.IO.readFile ledgerFixupPath @@ -739,7 +740,7 @@      repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure     let MigrationReport {results = repeatedResults} = repeated-    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 61+    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 62     length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0      withConnection connStr \conn -> run conn (Session.script fixup)@@ -1210,7 +1211,7 @@     adoption <- runMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure     let MigrationReport {results = adoptionResults} = adoption     length [() | MigrationResult {outcome = AlreadyApplied} <- toList adoptionResults] @?= 15-    length [() | MigrationResult {outcome = AppliedNow} <- toList adoptionResults] @?= 46+    length [() | MigrationResult {outcome = AppliedNow} <- toList adoptionResults] @?= 47      -- Verified and skipped, never re-executed: the stored rows keep their checksums and their     -- original application timestamps.@@ -1223,7 +1224,7 @@     verification <- verifyMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure     let VerificationReport {issues = adoptionIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification     adoptionIssues @?= []-    length appliedMigrations @?= 61+    length appliedMigrations @?= 62     pendingMigrations @?= []     unknownMigrations @?= [] @@ -1574,13 +1575,13 @@     verification <- verifyMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure     let VerificationReport {issues = verificationIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification     verificationIssues @?= []-    length appliedMigrations @?= 61+    length appliedMigrations @?= 62     pendingMigrations @?= []     unknownMigrations @?= []      repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure     let MigrationReport {results = repeatedResults} = repeated-    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 61+    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 62     length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0  testSchemaConvergence :: Assertion@@ -1626,7 +1627,7 @@     use connStr  expectedKiokuSchemaChecksum :: Text-expectedKiokuSchemaChecksum = "54fa912ca9f6332cb30ed604eaca9e4fdf25d38c09efc74bd1a5b5760273a112"+expectedKiokuSchemaChecksum = "793da81763342806e2e29ea71b4fe17b5d620052dca23be355b8602bc61d6fbc"  kiokuSchemaSnapshotStatement :: Statement () Text kiokuSchemaSnapshotStatement =@@ -1770,7 +1771,8 @@           migrationId "kioku" "0011-kioku-memory-space-partition",           migrationId "kioku" "0012-relocate-projections-to-kioku-schema",           migrationId "kioku" "0013-partition-aware-fts-index",-          migrationId "kioku" "0014-bounded-session-memory-pages"+          migrationId "kioku" "0014-bounded-session-memory-pages",+          migrationId "kioku" "0015-active-memory-recency"         ]  expectRight :: (Show error) => Either error value -> value@@ -1847,3 +1849,51 @@  query :: Text -> Statement () a -> IO a query connStr statement = withConnection connStr \conn -> run conn (Session.statement () statement)++-- The previous released manifest prefix is preserved byte-for-byte. Only the+-- appended index runs when a data-bearing 0.10.0.0 database upgrades.+testRecencyUpgrade :: Assertion+testRecencyUpgrade = withBareDatabase $ \connStr -> do+  let settings = Settings.connectionString connStr+  entries <- checkMigrationManifest "migrations/manifest" >>= either (assertFailure . show) pure+  let prefix = takeWhile ((/= "0015-active-memory-recency.sql") . fst) (toList entries)+  length prefix @?= 14+  oldKioku <- either (assertFailure . show) pure (migrationComponentFromEmbeddedSql "kioku" (Set.singleton "keiro") (case prefix of first : rest -> first :| rest; [] -> error "empty historical prefix"))+  kiroku <- either (assertFailure . show) pure KirokuMigrations.kirokuMigrations+  keiro <- either (assertFailure . show) pure KeiroMigrations.keiroMigrations+  old <- either (assertFailure . show) pure (migrationPlan (kiroku :| [keiro, oldKioku]))+  current <- either (assertFailure . show) pure kiokuMigrationPlan+  initial <- runMigrationPlan defaultRunOptions settings old >>= either (assertFailure . show) pure+  length (appliedNow initial) @?= 61+  withConnection connStr $ \conn ->+    run+      conn+      ( Session.script+          """+          INSERT INTO kioku.memories+            (memory_space_id,memory_id,agent_id,namespace,memory_type,content,priority,confidence,tags,status,created_at,updated_at)+          VALUES ('upgrade-space','upgrade-memory','upgrade','upgrade','fact','complete 記憶',50,'high','["tag","長い"]','active','2026-01-01','2026-01-01');+          """+      )+  let snapshot = preparable "SELECT row_to_json(m)::text FROM kioku.memories m WHERE memory_id='upgrade-memory'" E.noParams (D.singleRow (D.column (D.nonNullable D.text)))+  before <- query connStr snapshot+  oldSchema <- query connStr kiokuSchemaSnapshotStatement+  checksumHex (Text.Encoding.encodeUtf8 oldSchema) @?= "54fa912ca9f6332cb30ed604eaca9e4fdf25d38c09efc74bd1a5b5760273a112"+  migrated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+  appliedNow migrated @?= [expectRight (migrationId "kioku" "0015-active-memory-recency")]+  query connStr snapshot >>= (@?= before)+  newSchema <- query connStr kiokuSchemaSnapshotStatement+  let oldFacts = Text.lines oldSchema+      newFacts = Text.lines newSchema+      addedFacts = filter (`notElem` oldFacts) newFacts+  length addedFacts @?= 1+  assertBool "only the recency index is added" (all (Text.isPrefixOf "index|memories|memories_space_active_recency_idx|") addedFacts)+  filter (`notElem` addedFacts) newFacts @?= oldFacts+  checksumHex (Text.Encoding.encodeUtf8 newSchema) @?= expectedKiokuSchemaChecksum+  indexExists <- query connStr (preparable "SELECT to_regclass('kioku.memories_space_active_recency_idx') IS NOT NULL" E.noParams (D.singleRow (D.column (D.nonNullable D.bool))))+  indexExists @?= True+  repeated <- runMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+  appliedNow repeated @?= []+  query connStr snapshot >>= (@?= before)+  VerificationReport {issues, pendingMigrations, unknownMigrations} <- verifyMigrationPlan defaultRunOptions settings current >>= either (assertFailure . show) pure+  (issues, pendingMigrations, unknownMigrations) @?= ([], [], [])