On this page
Package migrate provides migration generation, application, rollback, squash, baseline recording, and safety linting with risk classification.
#internal/migrate
#internal/migrate
Package migrate provides migration generation, application, rollback, squash consolidation, and safety linting with risk classification for schema changes.
#PhaseExpand
const PhaseExpand = "expand"Phase constants for expand/migrate/contract annotation.
#PhaseMigrate
const PhaseMigrate = "migrate"#PhaseContract
const PhaseContract = "contract"#LegacyArchiveDir
const LegacyArchiveDir = "archive"LegacyArchiveDir is the sibling directory under a legacy (semver-TOML) migrations dir into which squash-superseded originals retire. It mirrors chain mode's migrations/archive/ (chainArchiveDir).
#CHECK
const CHECK (phase IN ('', 'expand', 'migrate', 'contract')),The three managed structures, verbatim per design/tracking_schema.sql. Executed together (single call) so the view's dependency on the ops table is satisfied.
#CONSTRAINT
const CONSTRAINT pgdesign_migration_ops_confirm_time#PRIMARY
const PRIMARY KEY (edge_id, seq)#ErrNoEdgeOps
var ErrNoEdgeOps = fmt.Errorf("migrate: migration has no operations; nothing to generate")ErrNoEdgeOps is returned by GenerateEdge when the migration lowers to zero DDL and zero DML ops (the zero-op guard). Callers treat it as "nothing to generate", mirroring the semver path's no-op behavior.
#ErrRevisionManifestNotFound
var ErrRevisionManifestNotFound = errors.New("revision manifest not found")ErrRevisionManifestNotFound marks the ABSENCE of a revision manifest file (as distinct from a present-but-corrupt one). Callers that must tell "no recorded pre-state" from "store corruption" match with errors.Is — reconstruction failures on a PRESENT manifest (unresolved object id, decode error) never carry it.
#ApplyHooks
type ApplyHooks structApplyHooks carries optional test seams. AfterOp runs after an op executes and journals, before the edge's transaction commits; a non-nil error aborts the edge (the transactional path rolls back — the in-process crash-before-commit equivalent). It is nil in production.
#EdgePlan
type EdgePlan structEdgePlan is a previewed edge and its rendered per-op SQL.
#BaselineReport
type BaselineReport structBaselineReport summarizes a chain-mode baseline.
#Edge
type Edge structEdge is an on-disk chain edge: a content-identified migration between two revisions, its ops self-contained in the object store. It wraps the kernel's identity/graph model (chain.Edge) with the on-disk facets — the model class and the resolved SelfContainedOps — plus file bookkeeping (never part of identity).
#ChainProject
type ChainProject structChainProject holds the migrations/ root and its content-addressed object store. Edge and revision-manifest files are read/written relative to it.
#Migration
type Migration structMigration represents a parsed migration file.
#DDLOp
type DDLOp structDDLOp represents a single DDL operation in a migration.
#DMLOp
type DMLOp structDMLOp represents a DML operation in a migration.
#DownOp
type DownOp structDownOp represents the rollback operation(s) for a DDL or DML op.
#RemapTable
type RemapTable map[string]stringRemapTable maps a rebased-away revision's String() form to its live re-parented revision's String() form (roadmap 5.10, store_layout.md). It is a REBASE-ONLY on-disk artifact; outside a rebase it is empty. The path-finder consults it so a database stamped at a rebased-away position is served forward, never orphaned.
#NoPathError
type NoPathError struct{ Pos string }NoPathError reports that pos is not reachable to any live head (corrupt / off-chain position).
#ForkError
type ForkError struct{ Heads []string }ForkError reports that more than one live head is reachable (an unresolved fork). It points at migrate rebase.
#RebaseResult
type RebaseResult structRebaseResult reports a chain-mode rebase.
#SelfContainedOp
type SelfContainedOp structSelfContainedOp is a migration op whose full payload lives in the object store, referenced by content id. It implements chain.Op.
#OpJSON
type OpJSON structOpJSON is the serialized edge-file op entry.
#SquashResult
type SquashResult structSquashResult holds the result of a legacy-mode (semver-TOML) squash.
The op-list OPTIMIZER (inverse-pair cancellation, sequential type merging, and CREATE TABLE folding) was RETIRED in roadmap 5.3: squash is now defined as ORDERED CONCATENATION, never a rewriting system (the roadmap: "today's optimizeDDLOps and its tests ... RETIRE with it as superseded dead code"). The legacy path keeps only the minimal concatenation + phase-strip + down-build mechanics pre-upgrade projects still need. Chain-mode consolidation lives in squash_chain.go.
#ChainSquashResult
type ChainSquashResult structChainSquashResult reports a chain-mode consolidation squash.
#AppliedChainEdge
type AppliedChainEdge structAppliedChainEdge is one confirmed edge from pgdesign_applied_migrations. For post-upgrade prefix rows Version is the legacy semver label; for chain edges it is the edge_id.
#ChainStatus
type ChainStatus structChainStatus is a database's chain position: the confirmed edges (from the applied-migrations view) and the pending edges (from the path-finder).
#AmnestyEntry
type AmnestyEntry structAmnestyEntry names one legacy migration file whose current bytes no longer hash to the checksum the database recorded when it was applied (a historical post-apply edit). The fold proceeds by content; this preserves the evidence.
#UpgradeReport
type UpgradeReport structUpgradeReport summarizes an upgrade for the CLI/tests.
#UpgradeHooks
type UpgradeHooks structUpgradeHooks carries optional test seams. BeforeCommit runs inside runUpgradeTxn after the fold + assert + drop, immediately before COMMIT; a non-nil error aborts the transaction (the in-process crash-before-commit equivalent — PG rolls back on disconnect). It is nil in production.
#Apply
func Apply(ctx context.Context, conn *pgx.Conn, migrationsDir string, lockTimeout string) ([]string, error)Apply discovers pending migrations in migrationsDir, applies them in semver order, and returns the list of applied versions. lockTimeout sets the PostgreSQL lock_timeout for each migration (e.g. "5s"); empty defaults to "5s".
#ApplyChain
func ApplyChain(ctx context.Context, conn *pgx.Conn, p *ChainProject, dbURL, lockTimeout string, hooks *ApplyHooks) ([]string, error)ApplyChain applies pending chain edges to conn and returns the applied edges' display ids (edge-id prefix + slug). A fresh database (no chain structures) is seeded here: the three managed structures are created and chain_position is set to genesis before path-finding. lockTimeout sets the session lock_timeout.
After the path lands, ReconcileAfterApply runs UNCONDITIONALLY (roadmap 5.8, L5's codomain check): the applied database is introspected and N-normalized DiffLive'd against the reconstructed target model; a residual mismatch is a hard error. dbURL is the connection string reconcile uses for its own introspection and live-normalizer sessions (conn is the apply session, still holding the advisory lock). An empty dbURL SKIPS reconcile — reserved for in-process callers that have no URL and drive their own verification (production always passes it).
#PlanChainEdges
func PlanChainEdges(p *ChainProject, from string) ([]Edge, error)PlanChainEdges is the PURE preview (roadmap 5.9): it enumerates the ordered edges from a starting revision to the single live head, reading only the on-disk chain — no database. from is "" to enumerate from GENESIS, or an explicit revision string. It returns an empty slice when from is already the head. This is migrate plan's engine; per-database pending is migrate status's job (it resolves against a live chain_position).
#RenderedEdgeSQL
func RenderedEdgeSQL(store *objstore.Store, e Edge) ([]string, error)RenderedEdgeSQL returns the ordered rendered SQL for an edge's ops (the exact sequence apply executes). It underpins the byte-identity test comparing chain-mode apply against legacy apply for the same Migration.
#PlanApplyChain
func PlanApplyChain(ctx context.Context, conn *pgx.Conn, p *ChainProject) ([]EdgePlan, error)PlanApplyChain previews the path-finder's chosen edges and their rendered SQL without executing (apply --dry-run). It reads the position when the chain structures exist, else treats the database as genesis. It never writes.
#BaselineChain
func BaselineChain(ctx context.Context, conn *pgx.Conn, p *ChainProject, actual *model.Schema, description string) (*BaselineReport, error)BaselineChain adopts a database whose schema was created by other means, or that has intentionally drifted, onto the on-disk chain (roadmap 5.10). Unlike migrate upgrade, it does NOT reconcile the TOML against the database and does NOT refuse drift — it ADOPTS the live state as the truth:
1. It synthesizes a revision manifest FROM INTROSPECTION (actual, a registry-absent model) and attaches it as a GENESIS-PARENTED edge carrying the introspected manifest. Per the 5.2 as-built precedent, the genesis edge builds its ops FROM THE MODEL via the shim (the same path upgrade uses for its genesis prefix edge), except the source is the INTROSPECTED model, not the TOML. Degraded objects that introspection cannot fully model are the documented lossiness (SM-vs-enum, etc.). 2. It stamps chain_position with boundary_kind='baseline' (rollback-frozen per 5.6; the boundary logic refuses to roll back across it).
The two legacy semver guards are re-expressed against the chain graph: - DIVERGENCE: the stamped position (if any) must be chain-reachable — an off-chain current_revision is corruption, the chain analogue of a recorded version with no migration file. - OUT-OF-ORDER: the baseline target must be reachable from the stamped position — you cannot baseline backward. A genesis-parented baseline target is reachable only from genesis, so re-baselining is admitted only from the genesis floor; a database already advanced on the chain is refused.
TWO-HEADS GUARD (hard error): the baseline edge is REGISTRY-ABSENT class and is genesis-parented, so appending it to a chain that ALREADY has a live head would create a second, cross-class head — an unresolvable fork (cross-class rebase is not supported). Baseline is for adopting a FOREIGN database into an EMPTY chain, so a pre-existing live head is refused outright: the remediation is to regenerate the chain from the adopted state, not to rebase the two heads.
#Baseline
func Baseline(ctx context.Context, conn *pgx.Conn, migrationsDir string, targetVersion string, description string) errorBaseline marks a database as being at a specific migration version without actually applying any migrations. This is used when adopting pgdesign migrations for an existing database whose schema was created by other means.
All discovered migration files with version <= targetVersion are recorded as baseline-applied. This ensures that a subsequent Apply sees them as already applied and skips them.
Additive idempotency: re-running baseline records any versions that are discovered but not yet recorded (versions <= target). A conflict is reported only when a previously recorded version is absent from the discovered set (true divergence -- the migration file was deleted).
Out-of-order guard: if a discovered migration file has a version < the maximum already-applied version and is not yet recorded, this indicates a migration file was added after later versions were applied. This is a hard error requiring explicit adoption.
#GenerateEdge
func GenerateEdge(p *ChainProject, m *Migration, desired *model.Schema, prev *model.Schema, parent rev.Revision, class rev.ModelClass, slug string) (string, error)GenerateEdge builds and writes the chain edge for migration m against the desired POST-STATE model. parent is the current chain-head revision (zero for a genesis edge); prev is the model AT that head (nil for genesis). class is the endpoints' model class. slug is the edge's human display name. It returns the written edge filename.
#IsChainMode
func IsChainMode(migrationsDir string) boolIsChainMode reports whether migrationsDir is an on-disk chain project (it holds a chain/ subdirectory). This is the file-vs-chain mode discriminator (item 6): legacy semver-TOML projects have no chain/ dir.
#OpenChainProject
func OpenChainProject(migrationsDir string) (*ChainProject, error)OpenChainProject opens (creating if necessary) the chain-on-disk layout under migrationsDir: the objstore root plus the revisions/, chain/, and archive/ directories. The object store is bound to the current codec epoch.
#VerifyChainConsistency
func VerifyChainConsistency(p *ChainProject) errorVerifyChainConsistency runs the three consistency checks over an on-disk chain project. It is the shared checker roadmap 6.2 and 7.2 invoke. A nil return means the store, revision manifests, and edges are mutually consistent.
#GenerateMigration
func GenerateMigration(d *diff.SchemaDiff, desired *model.Schema, version string, extReg *extregistry.Registry) (*Migration, []diagnostic.Diagnostic)GenerateMigration converts a SchemaDiff into a Migration with DDL/DML ops and safety diagnostics. The desired schema is used to look up full table definitions for create_table ops.
Generation is PURE (L5): it never reads the world. It has no row counts, so it ALWAYS emits the large-table-safe forms — FK adds split into NOT VALID + VALIDATE, columns becoming NOT NULL get a backfill-then-set_not_null pair, and expand/contract phasing is applied unconditionally. The same TOML edit yields the same migration regardless of any database's state.
#ParseMigrationFile
func ParseMigrationFile(path string) (*Migration, error)ParseMigrationFile reads and parses a TOML migration file.
#ParseMigration
func ParseMigration(data string) (*Migration, error)ParseMigration parses a TOML migration string.
#WriteMigrationFile
func WriteMigrationFile(path string, m *Migration) errorWriteMigrationFile serializes a Migration to a TOML file.
#FormatMigration
func FormatMigration(m *Migration) stringFormatMigration serializes a Migration to a TOML string.
#FindPath
func FindPath(pos string, remap RemapTable, liveEdges, allEdges []Edge) ([]Edge, error)FindPath returns the ordered edges a database at chain position pos must apply to reach the single live head. pos is a revision String() (or "" if the database has never been stamped — genesis). liveEdges is migrations/chain/; allEdges is chain + archive (archive-inclusive traversal). remap is the rebase remap (empty until 5.10).
It returns: - an empty slice and nil when the database is already at the head (up to date); - a NoPathError when pos is off-chain; - a ForkError when more than one head is reachable.
#AnnotatePhases
func AnnotatePhases(m *Migration, pgVersion int)AnnotatePhases sets the Phase field on all DDLOps and DMLOps in a migration. It re-derives the risk level for each DDLOp using a minimal OpContext built from the op's own fields and the target PG version. After annotation, it collapses single-phase migrations (all expand) to empty phases.
#HasPhases
func HasPhases(m *Migration) boolHasPhases returns true if any DDLOp or DMLOp has a non-empty Phase.
#RebaseChain
func RebaseChain(p *ChainProject, keepRef string) (*RebaseResult, error)RebaseChain resolves a two-head fork by re-parenting the tail of the head NOT named by keepRef onto the head named by keepRef. keepRef is a revision-or-edge reference (resolveSquashEndpoint semantics, at-target). It requires EXACTLY two live heads; anything else is a hard error.
#ReconcileAfterApply
func ReconcileAfterApply(ctx context.Context, dbURL string, p *ChainProject) errorReconcileAfterApply is the always-on codomain check. It is a no-op at a genesis head (nothing was ever applied). A nil return means the applied database matches the target model exactly on every introspectable object.
#ReconstructModel
func ReconstructModel(p *ChainProject, r rev.Revision) (*model.Schema, error)ReconstructModel rebuilds the model for revision r from p's revision manifest and object store. A missing manifest, an unresolved object id, or a decode failure is a hard error (no silent partial model).
#ChainHead
func ChainHead(p *ChainProject) (rev.Revision, *model.Schema, error)ChainHead returns the single live head's revision and reconstructed model. When the chain has no live edges it returns the zero revision and a nil model (genesis). More than one live head is a *ForkError.
#Rollback
func Rollback(ctx context.Context, conn *pgx.Conn, migrationsDir string, lockTimeout string) (string, error)Rollback rolls back the most recently applied migration. Returns the version that was rolled back. lockTimeout sets the PostgreSQL lock_timeout (e.g. "5s"); empty defaults to "5s".
#RollbackTo
func RollbackTo(ctx context.Context, conn *pgx.Conn, migrationsDir, targetVersion, lockTimeout string) ([]string, error)RollbackTo rolls back all migrations from the most recent down to (but not including) the target version. All intermediate migrations are pre-checked for reversibility before any rollback begins. Returns the list of versions that were successfully rolled back. On partial failure, returns both the rolled-back versions and the error.
#RollbackChain
func RollbackChain(ctx context.Context, conn *pgx.Conn, p *ChainProject, toRevision, lockTimeout string) ([]string, error)RollbackChain reverses applied chain edges against conn. toRevision is empty for a single-step rollback (reverse the most-recent edge, or abort the in-progress edge) or a target REVISION string for rollback --to (reverse every edge down to, but not including, toRevision). It returns the reversed edges' display ids.
#BuildCreateTable
func BuildCreateTable(store *objstore.Store, tbl model.Table, schema string, pgVersion int, enums []model.Enum, domains []model.Domain) (SelfContainedOp, error)BuildCreateTable stores the table plus its transitive enum/domain closure by content id and builds a create_table op. The closure lets rendering qualify enum/domain type names; PGVersion gates version-dependent DDL (e.g. STORED vs VIRTUAL generated columns) — both are recorded on the op, never hardcoded.
#BuildCreateView
func BuildCreateView(store *objstore.Store, v model.View, schema string) (SelfContainedOp, error)BuildCreateView builds a create_view op referencing the view def by content id.
#BuildCreateMaterializedView
func BuildCreateMaterializedView(store *objstore.Store, mv model.MaterializedView, schema string) (SelfContainedOp, error)BuildCreateMaterializedView builds a create_materialized_view op.
#BuildCreateSequence
func BuildCreateSequence(store *objstore.Store, s model.Sequence, schema string) (SelfContainedOp, error)BuildCreateSequence builds a create_sequence op preserving all parameters (start/increment/min/max/cache/cycle/owned_by) via the encoded def.
#BuildCreateCompositeType
func BuildCreateCompositeType(store *objstore.Store, c model.CompositeType, schema string) (SelfContainedOp, error)BuildCreateCompositeType builds a create_composite_type op.
#BuildCreateDomain
func BuildCreateDomain(store *objstore.Store, d model.Domain, schema string) (SelfContainedOp, error)BuildCreateDomain builds a create_domain op.
#BuildCreateFunction
func BuildCreateFunction(store *objstore.Store, f model.Function, schema string) (SelfContainedOp, error)BuildCreateFunction builds a create_function op. The function def (args, return type, body, volatility, ...) is stored by content id, so a parsed op renders the true function — never the deny-mutation fallback.
#BuildCreateTrigger
func BuildCreateTrigger(store *objstore.Store, t model.Trigger, table string, pgVersion int) (SelfContainedOp, error)BuildCreateTrigger builds a create_trigger op on a table. The trigger def is stored by content id, so a parsed op renders the true trigger — never the append-only fallback.
#BuildCreatePolicy
func BuildCreatePolicy(store *objstore.Store, p model.Policy, table string, pgVersion int) (SelfContainedOp, error)BuildCreatePolicy builds a create_policy op on a table.
#BuildCreatePartition
func BuildCreatePartition(store *objstore.Store, childSpec model.PartitionSpec, parentTable string) (SelfContainedOp, error)BuildCreatePartition builds a create_partition op. The child PartitionSpec and its parent table are recorded by content id / value, so a parsed op renders the true CREATE TABLE ... PARTITION OF.
#BuildCreateOrReplaceView
func BuildCreateOrReplaceView(store *objstore.Store, v model.View, prev *model.View, schema string) (SelfContainedOp, error)BuildCreateOrReplaceView builds a create_or_replace_view op whose recorded inverse restores the previous view definition. prev is nil when there is no prior view (then the down is a drop_view).
#BuildCreateOrReplaceFunction
func BuildCreateOrReplaceFunction(store *objstore.Store, f model.Function, prev *model.Function, schema string) (SelfContainedOp, error)BuildCreateOrReplaceFunction builds a create_or_replace_function op whose recorded inverse restores the previous function. prev is nil when there is no prior function (then the down is a drop_function).
#BuildAlterSequence
func BuildAlterSequence(store *objstore.Store, s model.Sequence, prev model.Sequence, schema string) (SelfContainedOp, error)BuildAlterSequence builds an alter_sequence op whose recorded inverse restores the previous sequence parameters (prev), so a rollback re-issues the ALTER.
#BuildSchemaMeta
func BuildSchemaMeta(store *objstore.Store, desired *model.Schema, prev *model.Schema) (SelfContainedOp, error)BuildSchemaMeta builds a schema_meta op covering Extensions/PGVersion/Groups changes (the manifest's schema:
#BuildRawOp
func BuildRawOp(store *objstore.Store, kind string, seq int, upSQL string, downKind string, downSeq int, downSQL string) (SelfContainedOp, error)BuildRawOp builds an opaque-SQL op (SM triggers, partman config) whose body is a content-addressed blob and whose recorded inverse is the down blob. seq and downSeq are the ops' zero-based positions within their edge (they pin the raw:
#BuildDMLOp
func BuildDMLOp(store *objstore.Store, kind string, seq int, upSQL string, downSeq int, downSQL string) (SelfContainedOp, error)BuildDMLOp builds a data-manipulation op (backfill/transform) whose body is a content-addressed SQL blob. Its inverse is DECLARED and may be VACUOUS (data is not restored — today's reversibility semantics, made explicit): pass the reverse-DML SQL, or a vacuous marker, as downSQL.
#MarshalOp
func MarshalOp(o SelfContainedOp) ([]byte, error)MarshalOp serializes an op to canonical JSON bytes (the edge-file op entry).
#ParseOp
func ParseOp(store *objstore.Store, j OpJSON) (SelfContainedOp, error)ParseOp reconstructs a self-contained op from its edge-file entry, RESOLVING its payload against the store. A payload id that does not resolve is a HARD ERROR: the op cannot render its true SQL, so it is unrepresentable — never a silent degraded op. The down reference is parsed as a cache; callers verify it against the up payload via VerifyDown.
#UnmarshalOp
func UnmarshalOp(store *objstore.Store, data []byte) (SelfContainedOp, error)UnmarshalOp parses an op from canonical JSON bytes and resolves its payload.
#VerifyDown
func VerifyDown(store *objstore.Store, up SelfContainedOp) errorVerifyDown is the LOAD-time down-cache verifier (edge_format.md TENSION 1, amendment A3). The edge-file down is never independently trusted: it must be a pure function of the up payload. VerifyDown re-derives the down from the up op (structurally for mechanically-invertible ops; from the inverse embedded in the up payload for declared-inverse ops) and asserts the re-derivation matches the stored down on every identity facet (kind, target, payload id). A mismatch is a HARD ERROR — corruption or tamper is caught at read time, before any apply, and never fed to rollback. Non-invertible ops must carry no down.
Roadmap 5.2's edge reader calls VerifyDown on every op as it loads a chain edge.
#DDLOpToSelfContained
func DDLOpToSelfContained(store *objstore.Store, op DDLOp, desired *model.Schema, seq int) (SelfContainedOp, error)DDLOpToSelfContained converts one legacy DDLOp (at edge position seq) against the POST-STATE model desired into a self-contained op.
#NextSemverVersion
func NextSemverVersion(dir string) (string, error)NextSemverVersion derives the next legacy-mode migration version from the semver *.toml files already in dir: the maximum existing version with its patch bumped, or "0.1.0" when the directory has none. This is the TRANSITIONAL auto-derivation for legacy-mode migrate generate after the --version flag was removed (roadmap 5.9 makes chain-mode identity content-derived; legacy-mode generate before migrate upgrade still needs a semver filename).
#InSemverRange
func InSemverRange(version, from, to string) boolInSemverRange returns true if version is in the [from, to] range (inclusive).
#OpToSQL
func OpToSQL(op DDLOp) stringOpToSQL converts a DDLOp to a SQL statement.
#IsNonTransactional
func IsNonTransactional(op DDLOp) boolIsNonTransactional returns true if the op must run outside a transaction.
#SquashMigrations
func SquashMigrations(ctx context.Context, conn *pgx.Conn, dir, from, to string) (*SquashResult, error)SquashMigrations squashes all LEGACY (semver-TOML) migrations in the given directory from version from to version to (both inclusive) into a single migration. Chain-mode projects use SquashChain (squash_chain.go); this path is guarded off for them.
It is a MANDATORY-DB operation: the caller must supply a live connection so the M200 applied-version safety check can run. Squashing a range that contains applied migrations would desynchronize the LEGACY tracking table, so the operation refuses. This blocks offline squash even of never-applied ranges (a deliberate stopgap for the legacy path; chain mode replaces the M200 refusal with the consolidation model — originals archive intact and mid-range databases resume via the path-finder — so applied state is irrelevant there).
#OutputPath
func OutputPath(dir, toVersion string) stringOutputPath returns the path for the squashed migration file.
#ArchiveLegacyOriginals
func ArchiveLegacyOriginals(dir string, paths []string) ([]string, error)ArchiveLegacyOriginals retires the given legacy (semver-TOML) migration files INTACT into a sibling migrations/archive/ directory via a pure-Go file move. This honors the same "retire originals, never destroy" contract chain-mode squash keeps (moveEdgeToArchive), but shells out to NOTHING: it must run on CI runners and consumer machines that have no developer-only file-archival tool on PATH. Returns the destination paths in the order given.
#SquashChain
func SquashChain(p *ChainProject, fromRef, toRef, slug string) (*ChainSquashResult, error)SquashChain consolidates the live path from fromRef to toRef into one consolidation edge, archiving the superseded originals intact. fromRef/toRef are rev-or-edge references (see resolveSquashEndpoint). slug is the consolidation edge's display name; empty auto-derives one.
It is a pure file operation: it does not read or trust the database (applied state is irrelevant to consolidation). The caller keeps --db mandatory and runs the pre-upgrade guard, per 0.6d.
#EnsureMigrationsTable
func EnsureMigrationsTable(ctx context.Context, conn *pgx.Conn) errorEnsureMigrationsTable creates the pgdesign_migrations table if it doesn't exist.
#AppliedVersions
func AppliedVersions(ctx context.Context, conn *pgx.Conn) ([]string, error)AppliedVersions returns all applied migration versions, sorted by semver.
#RecordMigration
func RecordMigration(ctx context.Context, conn *pgx.Conn, version, checksum, description string) errorRecordMigration inserts a migration record into the tracking table.
#AcquireAdvisoryLock
func AcquireAdvisoryLock(ctx context.Context, conn *pgx.Conn) (bool, error)AcquireAdvisoryLock acquires a session-level advisory lock for migrations. Returns true if the lock was acquired, false if another migration is in progress.
#ReleaseAdvisoryLock
func ReleaseAdvisoryLock(ctx context.Context, conn *pgx.Conn) errorReleaseAdvisoryLock releases the session-level advisory lock for migrations.
#ComputeChainStatus
func ComputeChainStatus(ctx context.Context, conn *pgx.Conn, p *ChainProject) (*ChainStatus, error)ComputeChainStatus reads conn's chain position and applied view, then asks the path-finder for the pending edges to the live head — WITHOUT creating any managed structure. A database with no chain structures is reported as genesis (nothing applied; every edge pending). A pre-upgrade database is a hard error (the shared guard names migrate upgrade).
#CreateTrackingStructures
func CreateTrackingStructures(ctx context.Context, tx pgx.Tx) errorCreateTrackingStructures creates the three managed structures in tx. It runs the exact reviewed DDL; a failure leaves tx to roll them all back atomically.
#ChainStructuresExist
func ChainStructuresExist(ctx context.Context, conn *pgx.Conn) (bool, error)ChainStructuresExist reports whether the chain-era tracking structures are present (probed via pgdesign_chain_position, the singleton position table).
#LegacyTrackingExists
func LegacyTrackingExists(ctx context.Context, conn *pgx.Conn) (bool, error)LegacyTrackingExists reports whether the pre-upgrade pgdesign_migrations table is present.
#GuardNotPreUpgrade
func GuardNotPreUpgrade(ctx context.Context, conn *pgx.Conn) errorGuardNotPreUpgrade is the shared pre-upgrade preflight for EVERY migrate subcommand that takes --db (roadmap 5.2). A PRE-UPGRADE database has the old pgdesign_migrations table AND lacks pgdesign_chain_position; running any subcommand against it is a hard error naming migrate upgrade. A fresh database (neither present) proceeds — apply creates the chain structures; a post-upgrade database (chain present) proceeds normally.
#Upgrade
func Upgrade(ctx context.Context, conn *pgx.Conn, p *ChainProject, desired, actual *model.Schema, ln diff.LiveNormalizer, migrationsDir string, schemaFiles []string, hooks *UpgradeHooks) (*UpgradeReport, error)Upgrade runs the one-time legacy -> chain upgrade against conn. desired is the TOML model (pg_version already resolved); actual is the caller's introspected model of the same database; ln is the live round-trip normalizer (may be nil). migrationsDir is the on-disk chain/migrations root; schemaFiles are the schema TOML paths guarded for a clean working tree. hooks may be nil.
#Edge.ID
func (e Edge) ID() string { return e.chainEdge().ID() }ID returns the edge's content-derived identity (chain.Edge.ID()).
#Edge.IsGenesis
func (e Edge) IsGenesis() bool { return e.Parent.IsZero() }IsGenesis reports whether the edge has a null parent.
#ChainProject.WriteEdge
func (p *ChainProject) WriteEdge(e Edge) (string, error)WriteEdge serializes e into migrations/chain/ under its content-derived name and returns the filename. The write is idempotent: an identical edge yields the same filename and byte-identical content. class must be valid.
#ChainProject.ArchiveEdge
func (p *ChainProject) ArchiveEdge(e Edge) (string, error)ArchiveEdge writes e into migrations/archive/ (retired originals). Same format and naming as a live edge; only the directory differs.
#ChainProject.LoadEdge
func (p *ChainProject) LoadEdge(path string, archived bool) (Edge, error)LoadEdge reads and fully verifies an edge file at path. archived records whether it came from archive/.
#ChainProject.LoadLiveEdges
func (p *ChainProject) LoadLiveEdges() ([]Edge, error)LoadLiveEdges reads and verifies every edge in migrations/chain/.
#ChainProject.LoadArchivedEdges
func (p *ChainProject) LoadArchivedEdges() ([]Edge, error)LoadArchivedEdges reads and verifies every edge in migrations/archive/.
#ChainProject.LoadAllEdges
func (p *ChainProject) LoadAllEdges() ([]Edge, error)LoadAllEdges returns live edges followed by archived edges (the path-finder's archive-inclusive traversal domain).
#ChainProject.WriteRevisionManifest
func (p *ChainProject) WriteRevisionManifest(r rev.Revision, class rev.ModelClass, m chain.Manifest) errorWriteRevisionManifest serializes manifest m (the revision r's key->id map) into migrations/revisions/ under its content-derived name. class must be valid and must equal r's class (L7). The write is idempotent.
#ChainProject.ReadRevisionManifest
func (p *ChainProject) ReadRevisionManifest(r rev.Revision) (chain.Manifest, error)ReadRevisionManifest reads the manifest file for revision r and reconstructs it as a chain.Manifest (enc.Key -> object-id). It verifies the file's revision string and class match r (L7 class-awareness). A missing file is reported so callers can distinguish "not written" from a parse error.
#ChainProject.Store
func (p *ChainProject) Store() *objstore.Store { return p.store }Store returns the content-addressed object store.
#ChainProject.Root
func (p *ChainProject) Root() string { return p.root }Root returns the migrations/ root.
#opSimulator.Simulate
func (s opSimulator) Simulate(from chain.Manifest, ops []chain.Op) (chain.Manifest, error)Simulate maps a from-manifest to a to-manifest by applying each op. It is TOTAL over the self-contained inventory (roadmap 5.1b): whole-object creates/replaces set the target key to the op's def-id; whole-object drops remove it; nested-modifier ops map the owning key to the payload's post-state id; rename_table swaps keys; schema-meta maps the schema key; DML/raw pseudo-targets and refresh are no-ops. An op kind outside the inventory is a hard error, never a silent fake.
#NoPathError.Error
func (e *NoPathError) Error() string#ForkError.Error
func (e *ForkError) Error() string#ChainProject.LoadRemap
func (p *ChainProject) LoadRemap() (RemapTable, error)LoadRemap reads migrations/remap.json and returns the rebase remap table. A missing file is an EMPTY table (the identity), never an error. The file's format/codec framing is verified against this build; the entries are validated as parseable, same-epoch revision strings so a corrupt remap is a hard error, never a silent mis-canonicalization.
#ChainProject.WriteRemap
func (p *ChainProject) WriteRemap(additions RemapTable) errorWriteRemap merges additions into the on-disk remap and writes it back. rebase calls it with the rebased-away -> live-re-parented mappings. Merging (rather than overwriting) makes successive rebases accumulate: a second rebase over an already-remapped chain never loses the first rebase's served-forward mappings. A collision that maps an existing key to a DIFFERENT target is a hard error (never silently overwrite a served-forward mapping). The write is idempotent for identical content.
#SelfContainedOp.Kind
func (o SelfContainedOp) Kind() string { return o.kind }Kind is the op-family name.
#SelfContainedOp.Target
func (o SelfContainedOp) Target() enc.Key { return o.target }Target is the kind-qualified manifest key of the object the op acts on (a dml/raw pseudo-target for data/opaque-SQL ops).
#SelfContainedOp.Invertibility
func (o SelfContainedOp) Invertibility() chain.InvertibilityClass { return o.inv }Invertibility is the op's L4 class.
#SelfContainedOp.PayloadID
func (o SelfContainedOp) PayloadID() string { return o.payload }PayloadID is the objstore content id of the op body.
#SelfContainedOp.Inverse
func (o SelfContainedOp) Inverse() (chain.Op, bool)Inverse returns the op's down and true when it is mechanically-invertible or declared-inverse; (nil, false) exactly when non-invertible.
#SelfContainedOp.RenderSQL
func (o SelfContainedOp) RenderSQL(store *objstore.Store) (string, error)RenderSQL resolves the op payload from the store and renders the op's SQL.
#SelfContainedOp.Serialize
func (o SelfContainedOp) Serialize() OpJSONSerialize projects a self-contained op to its edge-file op entry.