diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
 # Changelog
 
+## 0.8.0.0 — 2026-09-26
+
+### Breaking Changes
+
+- Requires `keiro-migrations ^>=0.19.0.0`, `kiroku-store-migrations ^>=0.6.0.0`, and the
+  `pg-migrate` 1.2 family. The composed plan grows from 56 to **57** migrations (Kiroku 12,
+  Keiro 32, Kioku 13) through Kiroku's `0012`, which adds the `$all`-row `category` column, its
+  check constraint `ck_stream_events_all_category`, and a category index, and advances the Kiroku
+  schema comment to "through 0012". Apply it to a database holding data only with every Kiroku 0.8
+  writer stopped.
+- `test-support` requires `keiro-test-support ^>=0.19.0.0` and `ephemeral-pg ^>=0.3.1.0`.
+
+### Changed
+
+- Kioku's own thirteen migrations and their checksums are unchanged; no ledger fixup is required.
+
 ## 0.7.0.0 — 2026-09-18
 
 ### Changed
diff --git a/kioku-migrations.cabal b/kioku-migrations.cabal
--- a/kioku-migrations.cabal
+++ b/kioku-migrations.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: kioku-migrations
-version: 0.7.0.0
+version: 0.8.0.0
 synopsis: Schema migrations for kioku
 description:
   Owns kioku schema evolution as a native pg-migrate component and composes
@@ -71,11 +71,11 @@
     containers >=0.6 && <0.8,
     hasql >=1.10 && <1.11,
     hasql-transaction >=1.2 && <1.3,
-    keiro-migrations ^>=0.17.0.0,
-    kiroku-store-migrations ^>=0.4.0.0,
-    pg-migrate ^>=1.1.0.0,
-    pg-migrate-embed ^>=1.1.0.0,
-    pg-migrate-import-codd ^>=1.1.0.0,
+    keiro-migrations ^>=0.19.0.0,
+    kiroku-store-migrations ^>=0.6.0.0,
+    pg-migrate ^>=1.2.0.0,
+    pg-migrate-embed ^>=1.2.0.0,
+    pg-migrate-import-codd ^>=1.2.0.0,
     template-haskell >=2.20 && <2.24,
     text >=2.0 && <2.2,
 
@@ -86,9 +86,9 @@
   exposed-modules: Kioku.Migrations.TestSupport
   build-depends:
     base >=4.18 && <5,
-    ephemeral-pg ^>=0.2.2.0,
-    keiro-test-support ^>=0.17.0.0,
-    kioku-migrations ^>=0.7.0.0,
+    ephemeral-pg ^>=0.3.1.0,
+    keiro-test-support ^>=0.19.0.0,
+    kioku-migrations ^>=0.8.0.0,
     text >=2.0 && <2.2,
 
 test-suite kioku-migrations-test
@@ -109,13 +109,13 @@
     bytestring >=0.11 && <0.13,
     containers >=0.6 && <0.8,
     hasql >=1.6,
-    keiro-migrations ^>=0.17.0.0,
-    kioku-migrations ^>=0.7.0.0,
+    keiro-migrations ^>=0.19.0.0,
+    kioku-migrations ^>=0.8.0.0,
     kioku-migrations:test-support,
-    kiroku-store-migrations ^>=0.4.0.0,
-    pg-migrate ^>=1.1.0.0,
-    pg-migrate-embed ^>=1.1.0.0,
-    pg-migrate-import-codd ^>=1.1.0.0,
+    kiroku-store-migrations ^>=0.6.0.0,
+    pg-migrate ^>=1.2.0.0,
+    pg-migrate-embed ^>=1.2.0.0,
+    pg-migrate-import-codd ^>=1.2.0.0,
     tasty >=1.5,
     tasty-hunit >=0.10,
     text >=2.0 && <2.2,
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -459,7 +459,7 @@
         runMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan
           >>= either (assertFailure . show) pure
       let MigrationReport {results = repeatedResults} = repeated
-      length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 56
+      length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 57
       length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0
       verification <-
         verifyMigrationPlan defaultRunOptions (Settings.connectionString connStr) plan
@@ -578,10 +578,10 @@
     plan <- either (fail . show) pure kiokuMigrationPlan
     let settings = Settings.connectionString connStr
     initial <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure
-    length (appliedNow initial) @?= 56
+    length (appliedNow initial) @?= 57
 
     baselineLedger <- query connStr fullLedgerSnapshot
-    fst baselineLedger @?= 56
+    fst baselineLedger @?= 57
     baselineSchema <- query connStr cohortSchemaSnapshotStatement
     fixup <- Text.IO.readFile ledgerFixupPath
 
@@ -607,7 +607,7 @@
 
     repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure
     let MigrationReport {results = repeatedResults} = repeated
-    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 56
+    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 57
     length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0
 
     withConnection connStr \conn -> run conn (Session.script fixup)
@@ -1072,12 +1072,12 @@
     full <- either (fail . show) pure kiokuMigrationPlan
 
     kirokuReport <- runMigrationPlan defaultRunOptions settings kirokuOnly >>= either (assertFailure . show) pure
-    length (appliedNow kirokuReport) @?= 11
+    length (appliedNow kirokuReport) @?= 12
     ledgerBefore <- query connStr kirokuLedgerSnapshot
 
     adoption <- runMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure
     let MigrationReport {results = adoptionResults} = adoption
-    length [() | MigrationResult {outcome = AlreadyApplied} <- toList adoptionResults] @?= 11
+    length [() | MigrationResult {outcome = AlreadyApplied} <- toList adoptionResults] @?= 12
     length [() | MigrationResult {outcome = AppliedNow} <- toList adoptionResults] @?= 45
 
     -- Verified and skipped, never re-executed: the stored rows keep their checksums and their
@@ -1091,7 +1091,7 @@
     verification <- verifyMigrationPlan defaultRunOptions settings full >>= either (assertFailure . show) pure
     let VerificationReport {issues = adoptionIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification
     adoptionIssues @?= []
-    length appliedMigrations @?= 56
+    length appliedMigrations @?= 57
     pendingMigrations @?= []
     unknownMigrations @?= []
 
@@ -1442,13 +1442,13 @@
     verification <- verifyMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure
     let VerificationReport {issues = verificationIssues, appliedMigrations, pendingMigrations, unknownMigrations} = verification
     verificationIssues @?= []
-    length appliedMigrations @?= 56
+    length appliedMigrations @?= 57
     pendingMigrations @?= []
     unknownMigrations @?= []
 
     repeated <- runMigrationPlan defaultRunOptions settings plan >>= either (assertFailure . show) pure
     let MigrationReport {results = repeatedResults} = repeated
-    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 56
+    length [() | MigrationResult {outcome = AlreadyApplied} <- toList repeatedResults] @?= 57
     length [() | MigrationResult {outcome = AppliedNow} <- toList repeatedResults] @?= 0
 
 testSchemaConvergence :: Assertion
@@ -1613,6 +1613,7 @@
           migrationId "kiroku" "0009",
           migrationId "kiroku" "0010",
           migrationId "kiroku" "0011",
+          migrationId "kiroku" "0012",
           migrationId "keiro" "0015-keiro-outbox-claim-order-index",
           migrationId "keiro" "0016-keiro-inbox-drop-received-idx",
           migrationId "keiro" "0017-schema-management-comment",
@@ -1678,7 +1679,7 @@
       (EXISTS (SELECT 1 FROM information_schema.columns
         WHERE table_schema = 'kiroku' AND table_name = 'streams' AND column_name = 'truncate_before'))::int
       + (coalesce(obj_description(to_regnamespace('kiroku'), 'pg_namespace'), '') =
-          'Managed by pg-migrate component kiroku through 0011')::int
+          'Managed by pg-migrate component kiroku through 0012')::int
       + (to_regclass('keiro.keiro_outbox_claim_order_idx') IS NOT NULL)::int
       + (to_regclass('keiro.keiro_inbox_received_idx') IS NULL)::int
       + (coalesce(obj_description(to_regnamespace('keiro'), 'pg_namespace'), '') =
