Your first plan
Establish history, evolve desired DDL, answer ambiguity, and verify a bundle.
Assume your desired schema begins with:
CREATE SCHEMA app;
CREATE TABLE app.accounts (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
display_name text NOT NULL
);
Establish replayable history
onwardpg config check
onwardpg init
init creates and clone-verifies the first content-addressed history entry. It does not apply anything to your development or production database.
Evolve desired DDL
Add a nullable status to the authoritative schema:
ALTER TABLE app.accounts
ADD COLUMN status text;
In a declarative schema file, write the resulting complete CREATE TABLE shape instead of the ALTER above. Then plan one feature:
onwardpg plan add-account-status
This creates one worktree-local PlanID. The durable bundle compares accepted history replayed in PostgreSQL (H) with the current exported schema materialized in PostgreSQL (W). If a development database is configured, the same command also reports a separate D → W reconciliation; it never uses D as migration history.
For this nullable additive change, the generated bundle appears under the
configured bundle_root as:
migrations/onward/app/add-account-status/
├── manifest.json
├── plan.json
└── phases/
└── expand.sql
Only non-empty phases exist. Decision receipts appear after hints are consumed.
Optional verify.sql appears when you add clone-only assertions; required live
readiness assertions stay in contract.sql and contract-gates.json. A
required column, rename bridge, or other compatibility change may also generate
contract.sql and editable pockets.
Review every statement and hazard. Continue editing your models or DDL and rerun onwardpg plan; the same active feature bundle is recalculated rather than stacked into a trail of local fixups. After rebasing on newly accepted migrations, run it again: the same PlanID is restacked on the new replayed head.
Prove the bundle
onwardpg verify
The command selects the active plan. In a clean checkout without that local
anchor, use onwardpg verify --bundle add-account-status.
Verification independently replays the chosen checkpoint and its continuation, runs boolean assertions, compares the final graph fingerprint, and requires an empty residual diff.
Use the read-only CI form after the bundle is reviewed:
onwardpg verify --check
If the high-level plan reports needs_input or needs_sql_edits, the bundle is intentionally incomplete. Supply one of the emitted semantic hints or replace the TODOs in the reported edit_files, then rerun plan and verify. The nested lower-level draft report uses needs_decisions for its compact decision envelope.