migrate: lifecycle module and CLI commands #9

Closed
opened 2026-10-26 22:16:49 -07:00 by end · 0 comments
Owner

Connects migrate (#7) to lifecycle (#5) and lifecycle/cli (#8). Blocked by all three.

Requirements

  • A lifecycle module for startup. The startup policy is chosen by the caller:
    • apply: run Up during Setup, which suits single-instance daemons;
    • require: fail Setup if migrations are pending, which suits replicas where a separate job migrates.
  • CLI commands: migrate up, migrate down-to <version> and migrate status, provided as ready-made lifecycle/cli commands that need only the database module.
  • Placement. Put this wherever it avoids an import cycle and keeps migrate usable without lifecycle, for example a migrate/lifecycle subpackage or functions in lifecycle/cli. Explain the choice in the PR.
  • Keep it small. This is glue. If it needs more than a couple of hundred lines, something upstream is wrong.

Done when

  • Tests cover:
    • both startup policies;
    • each CLI command against SQLite;
    • the require policy blocking startup when migrations are pending.

Completion gate: migration authoring compatibility

The default Goose Go template registers functions globally from init(). The current migrate convention deliberately disables that registry and requires provider-local registrations, so the stock generated Go file is not usable unchanged. Do not ship a CLI that perpetuates this manual adaptation.

  • Provide one consumer-facing authoring workflow for SQL and Go migrations, including creation and timestamp-to-sequential reconciliation (fix). Reuse Goose's supported creation/template facilities where practical.
  • Production boundary: provide create and fix as development-only helpers. They must not ship in production application binaries. Choose and document either explicit opt-in build tags for app-CLI inclusion (untagged production builds exclude them), or independent authoring tools. Merely hiding commands or gating them with a runtime flag is insufficient. Keep runtime migration commands available to production as required above.
  • Build verification: build and test the supported production and development artifacts. Verify authoring commands and their file-writing entry points are excluded from the production executable, while the tagged CLI or standalone tools can perform the creation/reconciliation flow. Document the required build tags or separate-tool installation/invocation.
  • Generated Go migrations must work unchanged with the house migrate configuration. Preserve provider-local isolation and the repository's no-global-state/no-init rule, unless a different integration is explicitly reviewed and approved.
  • Reconciliation must keep filenames and explicit Go registration versions consistent. Document that source renumbering does not rewrite database history and must happen before those IDs are deployed to shared databases.
  • Before completion, generate SQL and Go migrations, reconcile timestamp IDs, compile the generated result, and apply it against SQLite without hand-editing registration code or versions. Verify the resulting versions, pending state, and isolation between providers.
  • Update consumer docs to recommend this CLI for the supported authoring workflow instead of sending Go-migration users to the incompatible stock Goose template. Link upstream documentation for Goose concepts rather than duplicating its manual.
Kickoff prompt
Use the feature-delivery skill to resolve corestack/go#9 (the issue body is the spec).
Repo ~/Projects/corestack/go, base main (#5, #7 and #8 must be merged), branch
feat/migrate-lifecycle. Read AGENTS.md and the accepted ADRs first. Independent review
before the PR.
Connects `migrate` (#7) to `lifecycle` (#5) and `lifecycle/cli` (#8). Blocked by all three. ## Requirements - **A lifecycle module for startup.** The startup policy is chosen by the caller: - **apply:** run Up during Setup, which suits single-instance daemons; - **require:** fail Setup if migrations are pending, which suits replicas where a separate job migrates. - **CLI commands:** `migrate up`, `migrate down-to <version>` and `migrate status`, provided as ready-made `lifecycle/cli` commands that need only the database module. - **Placement.** Put this wherever it avoids an import cycle and keeps `migrate` usable without `lifecycle`, for example a `migrate/lifecycle` subpackage or functions in `lifecycle/cli`. Explain the choice in the PR. - **Keep it small.** This is glue. If it needs more than a couple of hundred lines, something upstream is wrong. ## Done when - Tests cover: - both startup policies; - each CLI command against SQLite; - the require policy blocking startup when migrations are pending. ## Completion gate: migration authoring compatibility The default Goose Go template registers functions globally from `init()`. The current `migrate` convention deliberately disables that registry and requires provider-local registrations, so the stock generated Go file is not usable unchanged. Do not ship a CLI that perpetuates this manual adaptation. - Provide one consumer-facing authoring workflow for SQL and Go migrations, including creation and timestamp-to-sequential reconciliation (`fix`). Reuse Goose's supported creation/template facilities where practical. - **Production boundary:** provide `create` and `fix` as development-only helpers. They must not ship in production application binaries. Choose and document either explicit opt-in build tags for app-CLI inclusion (untagged production builds exclude them), or independent authoring tools. Merely hiding commands or gating them with a runtime flag is insufficient. Keep runtime migration commands available to production as required above. - **Build verification:** build and test the supported production and development artifacts. Verify authoring commands and their file-writing entry points are excluded from the production executable, while the tagged CLI or standalone tools can perform the creation/reconciliation flow. Document the required build tags or separate-tool installation/invocation. - Generated Go migrations must work unchanged with the house `migrate` configuration. Preserve provider-local isolation and the repository's no-global-state/no-`init` rule, unless a different integration is explicitly reviewed and approved. - Reconciliation must keep filenames and explicit Go registration versions consistent. Document that source renumbering does not rewrite database history and must happen before those IDs are deployed to shared databases. - Before completion, generate SQL and Go migrations, reconcile timestamp IDs, compile the generated result, and apply it against SQLite without hand-editing registration code or versions. Verify the resulting versions, pending state, and isolation between providers. - Update consumer docs to recommend this CLI for the supported authoring workflow instead of sending Go-migration users to the incompatible stock Goose template. Link upstream documentation for Goose concepts rather than duplicating its manual. <details> <summary>Kickoff prompt</summary> ```text Use the feature-delivery skill to resolve corestack/go#9 (the issue body is the spec). Repo ~/Projects/corestack/go, base main (#5, #7 and #8 must be merged), branch feat/migrate-lifecycle. Read AGENTS.md and the accepted ADRs first. Independent review before the PR. ``` </details>
end added a new dependency 2026-10-26 22:17:23 -07:00
end added a new dependency 2026-10-26 22:17:23 -07:00
end closed this issue 2026-10-28 16:10:40 -07:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Reference: corestack/go#9