Skip to content
PtahDocs
v0.8.0
Page type: tutorial

Run an Atlas project on ptah-compat

Point the Atlas-compatible binary at the atlas.hcl and migration directory you already have, and check that nothing moved.

You have an atlas.hcl, a migration directory whose history is applied in real databases, and CI steps that call Atlas verbs. One thing changes: which binary runs them. The project file stays, the directory stays, atlas.sum stays, and the commands stay. At the end you are on ptah-compat, which is a place to stop rather than a staging area to escape from.

The two halves of the move are not equally provable, and the page treats them differently. The community-edition surface is what ptah-compat targets, and what it covers is measured rather than asserted: the feature matrix answers it per capability, and every command below runs in this repository’s continuous integration on Linux, macOS and Windows. Capabilities Atlas gates behind a paid tier are answered by different machinery, described rather than executed, in What the gated capabilities become.

  • ptah-compat and ptah on your PATH. Install Ptah ships both.
  • A terminal and about ten minutes.

No database server, Docker, or Go toolchain is required.

The fixture is an atlas.hcl with one env and a directory holding two migrations, which is the smallest shape that can prove anything. Yours is larger; nothing below cares how much larger.

Terminal window
mkdir -p ptah-from-atlas/migrations
cd ptah-from-atlas
cat > atlas.hcl <<'HCL'
env "local" {
url = "sqlite://app.db"
migration {
dir = "file://migrations"
}
}
HCL
cat > migrations/20240101000000_create_users.sql <<'SQL'
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL
);
SQL
cat > migrations/20240102000000_add_email_index.sql <<'SQL'
CREATE UNIQUE INDEX users_email_idx ON users (email);
SQL

Your own directory already carries atlas.sum. This one does not yet, so seal it the way the directory was sealed in the first place:

Terminal window
ptah-compat migrate hash --env local
Terminal window
ptah-compat migrate validate --env local

A sealed directory validates silently and exits zero. That is Atlas’s contract for this verb and it is kept here, so a pipeline step that asserts on empty output keeps passing.

Terminal window
ptah-compat migrate status --env local

Expected output on standard output:

Migration Status: PENDING
-- Current Version: No migration applied yet
-- Next Version: 20240101000000
-- Executed Files: 0
-- Pending Files: 2

No flag named the database. --env local selected the env block, and the url and migration { dir } in atlas.hcl answered the rest.

Terminal window
ptah-compat migrate apply --env local

Expected output on standard output:

Migrating to version 20240102000000 from 2 pending migrations.
Migration complete. Current version: 20240102000000
Terminal window
ptah-compat migrate status --env local

Expected output on standard output:

Migration Status: OK
-- Current Version: 20240102000000
-- Next Version: Already at latest version
-- Executed Files: 2
-- Pending Files: 0

The revisions landed in atlas_schema_revisions, the table Atlas writes, in the layout Atlas writes it. Nothing converted the history on the way in.

Editing an applied migration is the mistake the checksum file exists to catch. Make it:

Terminal window
cat > migrations/20240102000000_add_email_index.sql <<'SQL'
CREATE UNIQUE INDEX users_email_idx ON users (email, id);
SQL
Terminal window
ptah-compat migrate validate --env local

Expected output on standard output:

You have a checksum error in your migration directory.
L3: 20240102000000_add_email_index.sql was edited
Please check your migration files and run 'atlas migrate hash' to re-hash the contents

Expected output on standard error:

Error: checksum mismatch

The remedy names the atlas binary because this is the Atlas-compatible wording and Ptah keeps it as it is. A CI job that greps this output keeps working, which is the point of matching the wording rather than improving it.

Put the file back:

Terminal window
cat > migrations/20240102000000_add_email_index.sql <<'SQL'
CREATE UNIQUE INDEX users_email_idx ON users (email);
SQL
Terminal window
ptah-compat migrate lint --env local --dev-url "sqlite://dev.db" --latest 1

Expected output includes, on standard output:

Analyzing changes from version 20240101000000 to 20240102000000 (1 migration in total):
-- analyzing version 20240102000000

The finding it prints for this fixture is a unique index built over rows that already exist. Ptah’s rule catalog is its own and is larger than the Atlas-compatible surface needs; migration lint rules enumerates it.

Atlas keeps part of its product behind a paid tier, and a pipeline that depends on one of those parts is the reason this move needs thinking about rather than scheduling. The answer is usually better than expected: the capability exists here, behind different machinery, and behind no tier. What it is not is the same machinery, so each one is a change to your pipeline rather than a no-op.

What your pipeline uses What runs here
A hosted registry holding migration directories and schemas An OCI registry you already run. ptah oci logs in, inspects, fetches, copies and verifies artifacts and the metadata attached to them, and an oci-layout:// directory stands in where there is no registry to reach.
A hosted lint report ptah migrations lint --format writes sarif, gitlab, github-actions or json, and --attach puts the canonical JSON report on the migration artifact so it travels with what it describes.
Registry-mediated plan approval ptah-compat schema plan computes the plan and saves a .plan.hcl locally; ptah schema approve signs one and ptah schema verify-approval checks the signature against the signers you allow. There is no identity service to run, and plan and approve walks it.
Schema and migration testing ptah-compat schema test and ptah-compat migrate test read .test.hcl, and ptah schema test is the native path.

ptah-compat schema plan has no working approve, push, pull, list or rm: those sub-verbs address a remote registry and answer that they are not implemented. The local plan file plus the native signature is the whole replacement, and it is a different shape rather than a smaller one.

Atlas feature matrix is the row-by-row reference for everything above, and OCI registry documents the registry side in full.

Nothing so far required native Ptah, and nothing below changes the project. ptah project adopt --check reads the same atlas.hcl and reports what a native Ptah would make of every construct in it.

Terminal window
ptah project adopt --check

Expected output includes, on standard output:

exact (2):
database url
migration dir

Add --preflight and the same command reads the revision history the database holds, which is the half a verdict about a file cannot cover:

Terminal window
ptah project adopt --check --preflight

Expected output includes, on standard output:

✓ every recorded revision finished
✓ every recorded revision names a migration this directory contains
✓ no recorded checksum contradicts the migration it names

The non-zero status is the useful part. The file is native-ready and the database still holds its history in the Atlas-compatible layout, so one decision remains before a native writer could take over — and you do not have to make it. Staying on ptah-compat is a supported end state. Migrate from Atlas is the page for readers who want to go further, and it covers that decision in reversible stages.

Terminal window
cd ..
rm -rf ptah-from-atlas

Your commands, your project file and your history are where they were, and the binary in front of them is ptah-compat. What that binary covers is measured rather than asserted: Atlas compatibility is the summary, feature matrix the per-capability table, and retained divergences the list of places Ptah deliberately does not reproduce a behavior, each with the reason.

ptah-compat keeps every capability Ptah models, which means it accepts some input the community binary refuses. Strict CE mode is the switch that narrows it to a community-edition-only policy for conformance runs, and it is worth knowing about before you rely on the move. License boundary states how the compatibility work is done and what it does not touch.