Design Record: Why No Orchestration Flags#
Status: STANDING POLICY — applied to every CLI proposal since the beginning. The CLI’s actual surface is in the CLI reference .
Decision#
pgmi’s CLI handles infrastructure only: connections, authentication,
parameters, observability, confirmation bypass. Every flag that would decide
what the deployment does is rejected, because deployment behavior is
declared in the project’s deploy.sql — where it is programmable, versioned,
and testable.
The rejected flags, and where each one lives instead#
Each of these was genuinely proposed or expected (they exist in comparable tools) and rejected on the same grounds: a flag is a fixed policy; SQL is a programmable one.
| Rejected flag | The SQL that replaces it |
|---|---|
--dry-run | A parameter your deploy.sql interprets — see the worked example below |
--rollback | Your transaction strategy: abort before COMMIT, or run your own compensating scripts — rollback strategies |
--skip-* / --only-* | A WHERE clause on pgmi_plan_view
— selection is a query |
--quiet / verbosity tiers | RAISE NOTICE/RAISE DEBUG in your SQL plus client_min_messages; the CLI only forwards PostgreSQL’s stream |
a pgmi test subcommand | CALL pgmi_test() inside deploy.sql — tests gate the same transaction
that applies the changes, which a separate command could never do |
The canonical worked example#
--dry-run is the strongest candidate flag, so it makes the best
demonstration that the flag is unnecessary, not merely unwanted. A
parameter plus three lines of SQL implements it — with semantics the project
controls, not semantics a tool guessed:
-- Place this before deploy.sql's first top-level COMMIT. Everything up to
-- that COMMIT runs as one transaction, and RAISE EXCEPTION rolls it all back.
-- Statements after it autocommit one by one, and this block cannot undo them.
-- The scaffolded templates COMMIT after the test gate, so put it above that.
DO $$
BEGIN
IF COALESCE(current_setting('pgmi.preview', true), 'false') = 'true' THEN
RAISE EXCEPTION 'preview mode: rolling back, no changes applied';
END IF;
END $$;pgmi deploy . -d mydb --param preview=true # runs up to the check, commits nothingA built-in --dry-run would have to choose one meaning (parse only? execute
and roll back? print the plan?) for every project. The parameter version
chooses per project, and the choice is reviewable in version control like
any other line of the deployment.
Consequence#
The CLI stays small and stable, and the answer to “can pgmi do X during a deployment?” is almost always “yes — write it in deploy.sql” rather than a feature request. The cost is symmetrical and real: pgmi will not stop you from writing a bad deployment program — the trade-offs page owns that honestly.
See also#
- Why execution fabric — the philosophy this policy enforces
- deploy.sql guide — the patterns that replace the flags