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 +7/−0
- kioku-migrations.cabal +3/−3
- migrations/0015-active-memory-recency.sql +7/−0
- migrations/manifest +1/−0
- test/Main.hs +63/−13
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) @?= ([], [], [])