Context
Each Go service invents its own migration approach:
objectives: bespoke EnsureSchema() — runs all SQL via CREATE TABLE IF NOT EXISTS at startup. No history table, no rollback, no versioning.
asb: custom migrate.Runner reading .sql files from disk
entities/connectors/skills: re-run CREATE TABLE IF NOT EXISTS on every startup
- Python services use Alembic via
fermata/migrations
No service uses goose, golang-migrate, or Atlas. Migrations run inline at startup, making zero-downtime schema changes risky (DDL locks during traffic).
Requirements
Impact
Enables safe schema evolution across 15+ Go services. Currently any ALTER TABLE that needs a migration path beyond IF NOT EXISTS is impossible without custom code per service.
Context
Each Go service invents its own migration approach:
objectives: bespokeEnsureSchema()— runs all SQL viaCREATE TABLE IF NOT EXISTSat startup. No history table, no rollback, no versioning.asb: custommigrate.Runnerreading.sqlfiles from diskentities/connectors/skills: re-runCREATE TABLE IF NOT EXISTSon every startupfermata/migrationsNo service uses goose, golang-migrate, or Atlas. Migrations run inline at startup, making zero-downtime schema changes risky (DDL locks during traffic).
Requirements
golang-migrate(orgoose) as a shared dependency inservice-runtimemigrate.Run(db, migrationsDir)helper that services call at startupup,down,versioncommands via CLI flag or env varmigration-job.yamlArgoCD PreSync hook)objectivesoraudit) as a reference implementationCREATE INDEX CONCURRENTLY, advisory locksImpact
Enables safe schema evolution across 15+ Go services. Currently any
ALTER TABLEthat needs a migration path beyondIF NOT EXISTSis impossible without custom code per service.