Skip to content

Flyway migration generation regressed: ADR-0015 removed the meta:migrate --flyway mojo and the shared-engine Flyway output adapter was never built #192

Description

@dmealing

Summary

metaobjects once shipped Flyway-named migration generation for JVM consumers (the Java meta:migrate --flyway Maven mojo, plugin v7.0.0). ADR-0015 consolidated all migration onto the shared TS engine and removed that mojo, designating a "Flyway-prefix output adapter" on the shared engine as its replacement — but that adapter was never built.

Net effect: a Spring-Boot-Kotlin + Exposed + Flyway consumer today has no supported path to generate migrations from metadata. Yet the generated meta init agent-context (.metaobjects/AGENTS.md) still instructs adopters to "never hand-write SQL … apply schema only through meta migrate" — advice that is impossible to follow on a Flyway stack, because there is no meta migrate output that Flyway can consume. This misdirects adopters (human and agent) and forces hand-authored V<n>__*.sql that only a boot-time drift-gate keeps honest.

How it regressed

  • The Java maven-plugin MetaDataMigrateMojo gained a Flyway-naming option in 4ca10dd2 ("feat(maven-plugin): meta:migrate Flyway-naming option for codegen-kotlin consumers"), shipped in Java plugin 7.0.0 (its plugin.xml lists a migrate goal). Design of record: docs/superpowers/specs/2026-05-25-codegen-kotlin-design.md §5.1 — <flyway>true</flyway> → scan flywayDir for the highest V<N>__, increment, emit V<N+1>__<slug>.sql.
  • 77a5c46a ("refactor(omdb)!: remove meta:migrate goal + Java migration-conformance scenarios") removed the mojo and the Java migrate engine behind it, per ADR-0015 (single shared migrate engine). ADR-0015 §3 explicitly designates Flyway-prefix (V__/U__) as reference output adapter fix(cli): scaffold outDir defaults to src/generated, not ./src/db #1 and notes the prior Flyway-emit groundwork "should inform the shared adapter."
  • That adapter was never implemented: server/typescript/packages/migrate-ts/src has zero flyway references. meta migrate emits only its own <seq>-<slug>/up.sql + down.sql layout plus a private ledger table — incompatible with a Flyway flyway_schema_history boot without an adapter.

Impact on JVM/Flyway consumers

  1. No migration-generation path. The current Java maven-plugin (e.g. 7.7.8) exposes goals generate, verify, docs, editor, help — no migrate. The TS CLI's output layout can't feed Flyway. So metadata → Flyway migration must be hand-authored to match codegen — the exact thing the doctrine says never to do.
  2. The generated scaffold actively misdirects. meta init emits .metaobjects/AGENTS.md with "never hand-write SQL … apply schema only through meta migrate." On a Flyway stack there is no such command, so an agent/dev following the scaffold hunts for tooling that does not exist. (This recently cost a real multi-file investigation for one such consumer before the removal history was uncovered.)

Proposed fix

  1. Build the ADR-0015 Flyway-prefix output adapter on the shared TS migrate engine (already the accepted plan-of-record; the removed nextFlywayVersion scanner from 4ca10dd2 is prior art). Emit V<N+1>__<slug>.sql into a configurable flywayDir, diffing the offline snapshot (meta migrate baseline --from-db seeds it once). Prove emitted-DDL fidelity against the codegen-kotlin Exposed table shapes via meta verify --db. Note the known gaps the engine does not yet model (triggers, cross-column CHECKs, function-valued defaults, GIN array indexes) will still require some hand-authored SQL — the adapter should degrade gracefully, not silently drop them.
  2. Until it ships, correct the meta init scaffold so a Flyway-configured consumer's generated .metaobjects/AGENTS.md does not claim meta migrate is the schema-apply path. For a Flyway stack it should state that migrations are hand-authored to match codegen and enforced by the boot-time table/DB drift-gate (meta verify --db) — or at minimum not assert a command that isn't shipped for that stack.

Evidence (all in this repo)

  • ADR: spec/decisions/ADR-0015-single-shared-migrate-engine.md (§3 output-adapter design; Flyway-prefix reference; build path pending)
  • Removed mojo: git show 4ca10dd2 (added Flyway option) / git show 77a5c46a (removed the goal)
  • Superseded design: docs/superpowers/specs/2026-05-25-codegen-kotlin-design.md §5.1
  • The gap: no flyway references anywhere under server/typescript/packages/migrate-ts/src

Activity

  1. added 8 commits that reference this issue on Aug 2, 2026
  2. dmealing commented on Aug 5, 2026

    @dmealing
    MemberAuthor

    The ADR-0015 Flyway-prefix output adapter is built and on main (c504c982, 058ce03f, 36928ff6, 6b670c2b). CI green.

    Usage

    meta migrate --db "$DB_URL" --dialect postgres --migration-format flyway --slug add_program_view
    # -> src/main/resources/db/migration/V4__add_program_view.sql
    # -> src/main/resources/db/migration/U4__add_program_view.sql

    Also settable once as migrate.format in .metaobjects/config.json so a JVM shop never passes the flag.

    Design — a third output adapter beside the homegrown and D1/Wrangler layouts, exactly the slot ADR-0015 §3 specified. The diff/emit engine is untouched: it already produces the up/down SQL, and an adapter only chooses the envelope.

    • Versioning is scan-and-increment on the highest V<N>__, as the removed mojo did (4ca10dd2), so it composes with migrations already in the directory. A dotted version (V10.5__) increments on its leading integer, and the U__ files it emits do not bump the counter.
    • Undo is emitted as U<N>__, Flyway's own convention. Undo is a paid edition feature and Community ignores U__ files rather than failing, so they are inert-but-correct there and become live on Teams/Enterprise.
    • Output dir defaults to src/main/resources/db/migration; --out-dir overrides.
    • Flyway owns apply. --apply, apply-pending and --rollback are refused under this format, each naming the Flyway command instead — writing behind Flyway desyncs flyway_schema_history. --dialect d1 with it is refused too.

    Two notes on the issue text. The flag is --migration-format, not --format: that name is already the global output-rendering flag (toon/json/text). And the issue's second half — the meta init scaffold telling Flyway adopters to "apply schema only through meta migrate" — was already fixed in PR #263, so this covers the adapter only.

    Gates — the real-engine round-trip this repo requires of every migrate change: V1__init.sql applies to a real sqlite database, and a second migrate against the migrated DB reports no changes and writes no V2__ (convergence); then a field is added, V2__ is emitted past the existing V1__, applies, and the column is present. Plus adapter unit tests (9), CLI refusal + precedence tests, and a no-churn assertion that default-format output is unchanged. migrate-ts 697 / cli 432 / workspace build + typecheck all green.

    Design and plan: docs/superpowers/specs/2026-08-04-issue-192-flyway-output-adapter-design.md, docs/superpowers/plans/2026-08-04-issue-192-flyway-output-adapter.md. Documented in docs/features/cli.md.

    Unreleased — ships in the next npm cut (migrate-ts + cli + sdk); see CHANGELOG.md [Unreleased]. The other three ADR-0015 adapters (two-file, dbmate/goose divider, Liquibase) stay deliberately unbuilt — they become mechanical now the format axis exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions