Skip to content

Your first plan

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
);
Terminal window
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.

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:

Terminal window
onwardpg plan add-account-status

The durable bundle appears under the configured bundle_root:

migrations/onward/app/add-account-status/
├── manifest.json
├── decisions.json
├── plan.json
├── phases/
│ ├── expand.sql
│ └── contract.sql
└── verify.sql

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.

Terminal window
onwardpg verify 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:

Terminal window
onwardpg verify --check

If onwardpg exits with needs_decisions or needs_sql_edits, the bundle is intentionally incomplete. Follow the printed fingerprinted hint, replace any phase-local ONWARDPG TODO, and verify again.