Automatically detect and fix schema drift — without dropping data. When your live Postgres schema diverges from your Drizzle migrations, self-heal reconciles them non-destructively.
# Check if self-healing is active and if any drift exists
nself self-heal status
# Run a one-shot heal right now
nself self-heal run
# View past heal events
nself self-heal historynself self-heal <SUBCOMMAND> [FLAGS]Schema drift happens. A manual ALTER TABLE in production, a migration that ran on only one node, a plugin that added columns outside the migration track — these all leave the live schema out of sync with Drizzle's expected state.
The self-heal engine compares the Drizzle migration graph against the live Postgres information schema and generates the minimal set of safe DDL statements needed to reconcile them. It only adds missing columns, indexes, and constraints. It never drops columns or tables, and never runs without a dry-run preview first unless you explicitly pass --confirm.
Self-healing is controlled by the NSELF_SCHEMA_HEAL_ENABLED environment variable and runs automatically at stack start when enabled. Use the subcommands below to inspect, trigger, or disable the behavior.
Show whether self-healing is enabled, when it last ran, and how many drift items are currently detected.
nself self-heal status
# Self-heal: enabled
# Last run: 2026-05-07 08:14 UTC — 0 drift items
# Auto-run: on stack startEnable automatic schema healing at stack start. Sets NSELF_SCHEMA_HEAL_ENABLED=true in your active environment file.
nself self-heal enableDisable automatic schema healing. The engine stops running at stack start but can still be triggered manually with nself self-heal run.
nself self-heal disableRun the heal engine immediately. By default this is a dry run — it prints the DDL it would apply without executing it. Pass --confirm to apply changes.
# Preview what would be applied
nself self-heal run
# Apply the changes
nself self-heal run --confirm
# Run in CI without prompts (implies --confirm)
nself self-heal run --yes| Flag | Type | Default | Description |
|---|---|---|---|
--confirm | bool | false | Apply the generated DDL (default is dry-run) |
--yes | bool | false | Skip all interactive prompts; implies --confirm |
--format | string | text | Output format: text or json |
List past heal events with timestamps, drift counts, and whether changes were applied.
nself self-heal history
nself self-heal history --limit 20| Flag | Type | Default | Description |
|---|---|---|---|
--limit | int | 10 | Number of events to show |
--format | string | text | Output format: text or json |
| Action | Self-heal does this? |
|---|---|
| Add a missing column | Yes |
| Add a missing index | Yes |
| Add a missing constraint | Yes (non-destructive only) |
| Drop a column | Never |
| Drop a table | Never |
| Change a column type | Never (requires a manual migration) |
| Truncate or delete rows | Never |
NSELF_SCHEMA_HEAL_ENABLED — set to true to enable automatic healing at stack start (default: false)NSELF_SCHEMA_HEAL_LOG — path to the heal event log (default: logs/schema-heal.log)0 — no drift found, or drift was successfully healed1 — drift found but --confirm not passed (dry-run mode)2 — heal could not run (DB unreachable, invalid arguments)