kiroku-store-migrations: Schema migrations for kiroku-store

[ bsd3, database, eventing, library, program ] [ Propose Tags ] [ Report a vulnerability ]

Native pg-migrate component, Codd history mapping, and migration executable for installing and upgrading the PostgreSQL schema used by kiroku-store.


[Skip to Readme]

Modules

[Last Documentation]

  • Kiroku
    • Store
      • Kiroku.Store.Migrations
        • History
          • Kiroku.Store.Migrations.History.Codd
        • Kiroku.Store.Migrations.New

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.1.0, 0.2.0.0, 0.3.0.0, 0.3.1.0, 0.3.2.0, 0.3.2.1, 0.4.0.0 (info)
Change log CHANGELOG.md
Dependencies aeson (>=2.1 && <2.3), base (>=4.18 && <5), bytestring (>=0.11 && <0.13), containers (>=0.6 && <0.8), filepath (>=1.4 && <1.6), hasql (>=1.10 && <1.11), kiroku-store-migrations, optparse-applicative (>=0.17 && <0.20), pg-migrate (>=1.1.0.0 && <1.2), pg-migrate-cli (>=1.1.0.0 && <1.2), pg-migrate-embed (>=1.1.0.0 && <1.2), pg-migrate-import-codd (>=1.1.0.0 && <1.2), template-haskell (>=2.20 && <2.24), text (>=2.0 && <2.2) [details]
License BSD-3-Clause
Author Nadeem Bitar
Maintainer nadeem@gmail.com
Uploaded by shinzui at 2026-08-16T14:09:48Z
Category Database, Eventing
Home page https://github.com/shinzui/kiroku
Bug tracker https://github.com/shinzui/kiroku/issues
Source repo head: git clone https://github.com/shinzui/kiroku.git
Distributions
Reverse Dependencies 2 direct, 1 indirect [details]
Executables kiroku-store-migrate
Downloads 30 total (9 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2026-08-16 [all 2 reports]

Readme for kiroku-store-migrations-0.4.0.0

[back to package description]

kiroku-store-migrations

kiroku-store-migrations owns Kiroku's PostgreSQL schema as one native pg-migrate component named kiroku. The component embeds an ordered manifest and eleven SQL payloads, so applications can compose it with other libraries without copying Kiroku SQL. The first seven payloads are immutable historical Codd bytes; 0008 through 0011 are native-only forward migrations.

Public API

import Kiroku.Store.Migrations

kirokuMigrations :: Either DefinitionError MigrationComponent
kirokuMigrationPlan :: Either PlanError MigrationPlan

Applications with more than one component should consume kirokuMigrations and build their own explicit dependency-ordered plan. The single-component kirokuMigrationPlan is convenient for Kiroku-only deployments.

Existing databases can import their Codd ledger through Kiroku.Store.Migrations.History.Codd:

kirokuCoddHistoryMappings :: NonEmpty HistoryMapping
kirokuCoddSourcePayloads :: Map FilePath ByteString
kirokuCoddManifestText :: Text

kirokuCoddSourceConfig
  :: ConnectionProvider
  -> Bool
  -> Text
  -> Confirmation
  -> Either CoddDefinitionError CoddSourceConfig

The mapping selects the seven historical timestamped Codd names, verifies the checked-in migrations.lock SHA-256 evidence against the exact embedded native bytes, and maps them to kiroku/0001-kiroku-bootstrap through kiroku/0007-stream-truncate-before. Import writes only the pgmigrate ledger; it never executes already-applied SQL. Consumers with a shared Codd ledger can combine the exported names, payload map, manifest text, and history mappings with their own component evidence before constructing one atomic import.

CLI

kiroku-store-migrate mounts the standard pg-migrate-cli command groups:

kiroku-store-migrate --help
kiroku-store-migrate plan
kiroku-store-migrate list
kiroku-store-migrate check --manifest kiroku-store-migrations/migrations/manifest
kiroku-store-migrate up --database-url "$DATABASE_URL"
kiroku-store-migrate verify --database-url "$DATABASE_URL"
kiroku-store-migrate status --database-url "$DATABASE_URL"

Database commands accept --database-url. When it is omitted the executable uses DATABASE_URL. Local plan, list, check, and new commands need no database environment variable. verify compares the declared plan strictly with the pgmigrate ledger; it is not a live schema snapshot comparison.

For Haskell callers:

import Database.PostgreSQL.Migrate
import Hasql.Connection.Settings qualified as Settings
import Kiroku.Store.Migrations

main :: IO ()
main = do
  plan <- either (fail . show) pure kirokuMigrationPlan
  result <- runMigrationPlan defaultRunOptions (Settings.connectionString databaseUrl) plan
  either (fail . show) (const (pure ())) result

Authoring

The authoritative source is migrations/manifest; each line names one SQL file in execution order. Create the next numeric file with the standard CLI:

kiroku-store-migrate new \
  --manifest kiroku-store-migrations/migrations/manifest \
  --description "add widget index"

The helper exclusively creates the inferred file and atomically appends its name to the manifest. Never edit a released payload. Correct mistakes with a new forward migration. The seven initial payloads intentionally retain their exact historical bytes, including old comments, because Codd import uses SamePayload evidence.

Run the package suite after every migration change:

cabal test kiroku-store-migrations:kiroku-store-migrations-test

It proves manifest order, legacy SHA-256 parity, fresh apply, strict verify, idempotent rerun, concurrent locking, current Codd V5 import, legacy codd_schema import, partial-row rejection, import audit records, and source-ledger preservation. The relation contract suite also proves the frozen kiroku.subscription_checkpoints_v1 catalog, non-null value semantics, owner-rights privilege isolation, structural read-only behavior, downstream view survival, and indexed query plan. cabal test kiroku-store:kiroku-store-test consumes the same native plan through kiroku-test-support and proves the complete store behavior, including append and read scenarios.

Migration 0010 adds replay-history retention leases, the per-schema coordinator, an indexed active-lease predicate, and statement-level DELETE/TRUNCATE guards on the three event-store data tables. Migration 0011 converges databases that applied the withdrawn 0.3.2.x payload of 0010 (see below).

The kiroku.uuidv7() generator

uuidv7() is a PostgreSQL 18 builtin. On PostgreSQL 17 0001 installs a fallback into the Kiroku schema, and it does so under its own SET search_path, so the bare name resolves only in a session that ran 0001. Every migration after 0001 runs in whatever session the operator's upgrade happens to use, so none of them may name it unqualified — that is BUG-1, fixed in 0.4.0.0.

0010 therefore publishes kiroku.uuidv7() on every supported major version: PostgreSQL 17 already has it from 0001, and PostgreSQL 18 gets a thin alias for the builtin. New migrations that need a UUIDv7 value must call kiroku.uuidv7(), never bare uuidv7(). The qualified name resolves without any session state on every version the component supports.

The same rule holds for every other object: name it kiroku.<name>. Only 0001 may rely on search_path, because it is the only migration guaranteed to have set it.

Recovery

Migrations are forward-only. Before a persistent upgrade, take a backup. If an applied migration is bad, either restore that backup or append a corrective migration. Do not delete or rewrite an applied pgmigrate.migrations row except through the reviewed pg-migrate repair workflow.

ledger-fixups/ holds operator scripts that adjust the migration ledger's bookkeeping without touching your schema. Read the header of a script before running it; each states exactly which databases need it.

  • 2026-07-05-realign-kiroku-migration-timestamps.sql is historical, kept as source evidence for databases that once needed Codd timestamp repair. New native migrations use component-local numeric identities.
  • 2026-08-16-rebaseline-0010-checksum.sql re-baselines 0010's stored checksum for databases that applied the withdrawn 0.3.2.0/0.3.2.1 payload. Required before migrating such a database onto 0.4.0.0 or later; see the changelog.