Design Record: Why an Execution Fabric#
Status: FOUNDATIONAL — the product boundary. The reader-facing comparison lives in Why pgmi ; this page records the decision and its deliberate omissions.
Decision#
pgmi is an execution fabric: it prepares a session and executes the project’s SQL, and the project’s SQL owns every deployment semantic — selection, ordering, transactions, tests, idempotency, retry. It is not a migration framework, where those semantics belong to the tool:
What pgmi deliberately does not do#
Each omission is a decision, not a gap — and each has a documented home on the SQL side:
- No version/history table. Tracking is a choice you implement (the advanced template ships a complete one).
- No tool-imposed execution order. The plan is a derived, queryable view ; your deploy.sql decides what to run and in which order.
- No retry logic or error taxonomy. Errors are raw PostgreSQL errors with numbered exit codes ; retry policy belongs to the layer that owns the transaction.
- No implicit idempotency.
CREATE OR REPLACE,IF NOT EXISTS, and checksum-tracking patterns are yours to apply — pgmi will faithfully re-run whatever you give it. - No daemons, schedulers, or servers in the deployment path. One invocation, one session, one exit code.
The one place pgmi’s Go code reads your SQL to decide how to execute it — the first top-level transaction terminator that splits atomic head from psql-mode tail — is deliberately a ceiling, not a precedent: one token class, read to preserve PostgreSQL’s own semantics, never to add pgmi’s.
Rejected alternative#
The framework model itself. A version table, up/down pairs,
tool-owned transaction boundaries, and flags for behavior were the obvious
design — every major tool in the space works that way, and users arrive
expecting it. It was rejected because the framework’s model is a fixed
vocabulary: anything it didn’t anticipate (test-gated commits, data-dependent
branching, multi-phase ordering
, interleaved
concurrent-index builds) becomes a feature request. Making the deployment a
PostgreSQL program makes those the user’s ordinary SQL instead. The cost is
recorded, not hidden: PL/pgSQL expertise is required
,
and pgmi is overkill for some projects
.
The contract that makes it safe#
A fabric without a stable surface would couple every project to pgmi
internals. The versioned session API
is the counterpart
decision: internal _pgmi_* tables stay free to change, public
pgmi_*_views are the contract —
drawn in the session API surface diagram
.
See also#
- Why session-centric — the mechanism underneath
- Why no orchestration flags — the policy at the CLI boundary