Feature matrix
Evidence verified
For each capability, the matrix records what Ptah does, what the open Atlas community binary does, and what Atlas keeps outside its community build. Every row cites the evidence it rests on.
It is a status index, not an argument. The measured evidence is on Conformance, the differences Ptah keeps on purpose are on Compatibility differences, and the Atlas-documentation crosswalk is on Atlas docs coverage.
How to read the tables
Section titled “How to read the tables”| Symbol | Meaning |
|---|---|
| ✅ | Supported today |
| 🟡 | Partial. The difference column states what is missing |
| ❌ | Not implemented |
| 🔷 | Ptah does this job in its own form. What is missing is wire compatibility with a hosted, account-bound service, which an independent implementation cannot obtain |
| ➖ | Does not apply to that product |
| ❔ | Not established by the evidence this page uses |
🔷 and 🟡 answer different questions, and the difference decides whether a reader should wait for a release. 🟡 means the work is unfinished: the difference column names the issue that owns it, and a later Ptah closes it. 🔷 means the capability is already here under a Ptah spelling, running against infrastructure the team already operates, and the only thing absent is speaking the wire protocol of a service somebody else hosts behind their own accounts. No release closes that, so a 🔷 cell carries no tracking issue. A capability that is merely incomplete is never 🔷, whatever it sits next to.
🔷 appears in the Ptah column only. The Atlas columns describe the hosted product itself, where the distinction does not arise.
Each table has the same columns. Ptah, CE, and Pro carry one symbol each:
- Ptah — the native
ptahbinary plus the separateptah-compatdrop-in. - CE — the pinned Atlas community binary, version 1.3.0, which the
conformance harness runs against. The pin itself lives in
scripts/atlas-ce-reference.lock, which is what a bump changes. - Pro — capabilities Atlas keeps outside its community build, per the Atlas feature availability page and pricing page.
Every Atlas cell has to come from an Atlas-side source: the command, usage, and flag inventory the conformance harness reads out of the pinned community binary, measured behavior of an Atlas binary, or a classification Atlas publishes. Measurement outranks published classification when they disagree. Where nothing settles a question, the cell is ❔ rather than a guess.
Atlas plans are not the CE column
Section titled “Atlas plans are not the CE column”Atlas’s public plans are Starter (free), Pro, and Enterprise, and Atlas’s own pricing page classifies capabilities by plan. That classification and the CE column answer different questions: the CE column reports what the pinned community binary does, and the two diverge in both directions. Both examples below were measured on 2026-08-01 against CE v1.2.0:
- The pricing page places migration linting outside the Starter plan, yet the
CE binary runs
migrate lintand reports destructive changes. - The pricing page checks ERD visualization for Starter, yet the CE binary
rejects
schema inspect --webas an unknown flag; the ERD lives in the hosted service, not in the binary.
Where the pricing page settles a Pro-side question, the Pro column cites it.
Where plan marketing and measured binary behavior differ, the measured behavior
wins the CE cell and the difference column records the tension. The
schema-object rows are the clearest case: the HCL reference marks partition a
Pro feature and the pinned community binary plans PARTITION BY RANGE anyway,
while a live schema holding a domain, a composite type, a range type, a
sequence and an extension inspects on the same binary to nothing but its one
table. Both readings are in the row.
At a glance
Section titled “At a glance”Across the 192 capabilities below:
| Reading | Count |
|---|---|
| Ptah supports it fully | 180 |
| Ptah supports it with a stated limitation | 1 |
| Ptah does not implement it | 0 |
| Ptah covers it in its own form, against a hosted service it cannot interoperate with | 11 |
| Ptah and Atlas CE both support it | 63 |
| Ptah implements it openly where Atlas gates it behind Pro or Cloud | 53 |
| Ptah has it and neither Atlas edition does | 27 |
| Atlas CE has it and Ptah does not, or only in part | 0 |
| An Atlas column is ❔ — not established by this page’s evidence | 4 |
Every 🟡 and every ❌ in the Ptah column names its specific limitation and the issue that owns it, reproduced against a binary built from this repository; Atlas-column verdicts rest on the cited Atlas-side sources only. A 🔷 names no issue on purpose, because nothing an independent implementation can build closes it. Confirmed gaps are tracked in #926 to #942 and #944.
The command surface is counted separately, because it is measured rather than
assessed. The conformance harness inventories every command in the pinned Atlas
CE binary and compares it with the ptah-compat surface: 19 of the 37
inventoried commands are open parity targets, and they match on help usage and
flags across 107 observations with one gap — schema inspect --include, a
Pro-surface flag the pinned CE binary does not register and Ptah implements
openly (#951). The remaining 18
are registry, Cloud, or Pro verbs that are not drop-in targets. Ptah implements
seven of them as open capabilities regardless.
Schema sources
Section titled “Schema sources”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
| Annotated Go models from a live database | ✅ | ❌ | ❌ | Writes Ptah annotation source from introspection, with optional db/json tags. No Go-model generator in the CE inventory or Pro list. |
| Atlas CE inspect HCL parses back into Ptah | ✅ | ✅ | ✅ | 30 differential observations parse Atlas schema inspect HCL on PostgreSQL, MySQL and SQLite with zero schema-fact mismatches. |
| Atlas HCL data “external_schema” | ✅ | ❌ | ✅ | Ptah evaluates the data source and runs the program, gated behind --allow-external-schema/PTAH_ALLOW_EXTERNAL_SCHEMA. Community Atlas rejects data.external_schema. |
| Composite multi-source desired schema | ✅ | ❌ | ✅ | Repeatable --root-dir/--schema-file merge into one schema; conflicts error. Repo docs cite composite_schema as an Atlas Pro data source. |
| Desired-schema artifacts in an OCI registry | ✅ | ❌ | ✅ | ptah schema push/pull publish and fetch canonical HCL resolved from Go, YAML, HCL or SQL sources. Verified round trip against registry:2. |
| Directory of .hcl files as one schema source | ✅ | ✅ | ✅ | --schema-file dir and --to file://dir read a directory of .sql or .hcl files in filename order as an ordered script: mixed formats, an empty directory, a subdirectory and a redeclaration refuse. |
| External program / ORM loaders | ✅ | ✅ | ✅ | --schema-cmd or ptah.yaml external_schema (needs --allow-external-schema) runs a program without a shell emitting SQL, HCL, or YAML. |
| Go struct annotations | ✅ | ❌ | ❌ | Ptah parses //ptah:schema:* comments into the desired schema. Atlas’s route to Go models is an external ORM provider program. |
| HCL foreign_key deferrable | ✅ | ❌ | ❌ | deferrable and initially are carried through HCL, the IR, the renderer and the PostgreSQL catalog read. The community binary plans no DEFERRABLE for the same file. |
| HCL function calls in schema files | ✅ | 🟡 | 🟡 | sql() reduces to its SQL everywhere, and all 67 names the schema evaluator registers evaluate. uuid is a type, not a function. sql() inside check.expr and index.where is a retained divergence. |
| HCL locals, lock, atlas, dynamic/for_each | ✅ | 🟡 | 🟡 | locals is evaluated and local.x resolves. dynamic blocks expand: for_each, labels, iterator and content. lock and atlas are accepted and reported as ignored. |
| HCL names outside the parsed subset | ✅ | ✅ | ❌ | ptah-compat accepts an unmodeled top-level name whose body names a declared schema and reports it as ignored; schema.nope exits 1 on both. Native ptah refuses by name. |
| HCL table and column child blocks | ✅ | 🟡 | ✅ | column, primary_key, index, unique, foreign_key, check, partition, row_security, constraint, platform; column nests as, identity, platform. The binary drops row_security; ptah-compat plans it. |
| HCL top-level blocks Ptah parses | ✅ | 🟡 | ✅ | schema, enum, table, extension, sequence, domain, composite, range, function, view, materialized, trigger, policy, role, permission, data. The community binary plans DDL for table and enum. |
| HCL variable blocks and var.* references | ✅ | ✅ | ✅ | variable blocks bind var.x, --var name=value overrides them, and a typed variable with no value exits 1 with missing value for required variable "x" — the community binary’s own text. |
| Live database as desired state | ✅ | ✅ | ✅ | One connectable DB URL can be the desired side of compat schema apply/diff and migrate diff; ptah db read introspects natively. |
| Live database to Go annotation source | ✅ | ❌ | ❌ | ptah introspect writes annotated Go models from a live DB; repo docs record Go annotations as a first-party Ptah workflow. |
| Migration directory as a source | ✅ | ✅ | ✅ | Atlas-format directory with atlas.sum, replayed on a required --dev-url. Works on ptah schema inspect and compat apply/diff/migrate diff. |
| Ptah-only HCL schema extensions | ✅ | ➖ | ➖ | platform/override per dialect, EXCLUDE constraint block, column enum, table checks/custom, index ops, ClickHouse granularity, seed data block. |
| SQL DDL schema files | ✅ | ✅ | ✅ | Accepted by native --schema-file and compat --to/--from. Reads back every object kind Ptah renders; DO blocks, COMMENT ON and raw routine bodies still parse and are dropped. |
| YAML schema files | ✅ | ❌ | ❌ | Strict parser; unknown keys fail. Repo docs list Atlas OSS data sources as SQL, HCL, external schema, and remote/template dirs. |
Direct schema changes
Section titled “Direct schema changes”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
--dry-run, --auto-approve, and --edit |
✅ | ✅ | ✅ | All three registered and functional; --edit opens $VISUAL/$EDITOR and the edited SQL is applied. --dry-run and --auto-approve exclude each other on the command line, as on CE. |
--exclude glob and type selectors |
✅ | ✅ | ✅ | Resource globs, one final [type=…], and leading [type=schema]. Qualified globs reach every kind. A column selector works in both scopes, and the depth rule matches the pinned binary exactly. |
--include resource selectors |
✅ | ❌ | ✅ | CE registers --include on apply/diff but aborts it as non-community, and registers none on inspect. Ptah has all three, with union semantics and cross-scope dependency diagnostics. |
--schema / -s scoping of both sides |
✅ | ✅ | ✅ | Schema names scope resources; non-extension matches carry extensions as support. Diff refuses exact PostgreSQL-family server namespaces before SQL because catalogs do not round-trip safely. |
schema diff --export |
✅ | ❌ | ✅ | An exporter block declares a Go template and an env’s exporter attribute selects it; --export renders through it, on both schema diff and schema inspect. |
schema inspect --include filtering |
✅ | ❌ | ✅ | Compat and native inspect select top-level resources with the apply/diff selector engine. CE rejects the flag as unknown. A selection matching nothing renders nothing, exits 0, and says so on stderr. |
schema inspect --output |
✅ | ❌ | ✅ | -o/--output writes the rendered schema to a file instead of stdout, published atomically so a reader never sees a partial document. |
| An include selector matching neither diff side fails closed | ✅ | ❌ | ❌ | Compat and native retain --include; no-match exits nonzero. Qualified PostgreSQL extension creates preserve installation schema; moves fail before SQL. |
Apply advisory lock, --lock-timeout, --lock-name, --skip-lock |
✅ | 🟡 | ✅ | Real locks on PostgreSQL, YugabyteDB, MySQL, MariaDB, SQL Server; others run unlocked with a note. --lock-name and --skip-lock are Pro surface adopted openly; CE registers only --lock-timeout. |
| Compat inspect block superset opt-in | ✅ | ❌ | ❌ | Compat inspect omits unreferenced extension, sequence and policy blocks; an env variable restores them. |
Desired-state sources for --to and --from |
✅ | ✅ | ✅ | Files, a file:// directory of .sql or .hcl schema files, one DB URL, one atlas.sum dir, or env://; atlas:// fails early. |
| Dev-database rehearsal before apply | ✅ | ✅ | ✅ | Dev DB reset, target schema recreated, exact plan rehearsed, under --dry-run too; dev==target and failed rehearsal abort. A non-database --to requires --dev-url. |
| Drift detection against desired schema | ✅ | ❌ | ✅ | Native ptah schema drift: --severity, --exit-code, --ignore, text/json/github-actions. Atlas Cloud drift monitoring is out of scope. |
| Exclude selector that matches nothing is diagnosed | ✅ | ❌ | ❌ | A selector naming no object warns on inspect and diff and exits 1 on apply, and only a filter that asked it may call it empty; a PTAH_ATLAS opt-in restores the permissive behavior. |
| Exclude subtracts a named schema and its contents | ✅ | ✅ | ✅ | A one-part selector names a schema by catalog or quoted spelling, and it leaves with all contents. Case-preserving names remain addressable without collapsing case or quoted whitespace. |
| Exclude subtracts sequences, domains, composite types and range types | ✅ | ❔ | ✅ | --exclude reaches the same object kinds --include selects. Before, these four were read and cloned but never offered to a pattern, so excluding one was a silent no-op that still planned its DROP. |
Go-template --format output |
✅ | ✅ | ✅ | schema apply registers the shared helper set; schema inspect registers its own (base64url, hcl, json, mermaid, sql, split, write). schema diff registers sql by default and the rest behind an opt-in. |
Inspect --exclude field selectors |
✅ | ❌ | 🟡 | Six resource types subtract a field: version on an extension, comment on the rest. A field Ptah cannot subtract is refused, and the refusal names the ones that work. |
Inspect non-database sources via --dev-url |
✅ | ✅ | ✅ | Schema file, atlas.sum migration dir, or env:// is materialized on a reset dev DB then introspected; without --dev-url it fails. |
| Inspect split/write file exports | ✅ | ❌ | ✅ | {{ hcl . | split | write "dir" }} writes object/schema/type trees; pinned Atlas CE rejects split, write, hcl as non-community. |
| Inspected document declares what it does not describe | ✅ | ❌ | ❌ | A compat inspect document records the block kinds it omitted, in its own header and in every split member, so a later apply reads the omission as unknown rather than as deletion intent. |
| JSON output for native schema diff | ✅ | ➖ | ➖ | Native ptah schema diff --format json emits a machine-readable statements document; the Go-template row only states that {{ json . }} fails on the compat diff, leaving native JSON unstated. |
| Local pre-approved plan files | ✅ | ❌ | ✅ | schema plan writes Atlas .plan.hcl by default (.json keeps the native plan); apply --plan reads both, Atlas-authored included, verified by replay against --to plus an end-state check. |
| schema apply against a live database | ✅ | ✅ | ✅ | Diffs --url against the --to desired state, prints the SQL plan, applies after confirmation. Verified end to end on SQLite. |
| schema clean | ✅ | ✅ | ✅ | --include/--exclude narrow cleanup. PostgreSQL-family scoped drops are dependency-safe and transactional, and a dependent left outside the selection is named before any DROP runs. |
| schema diff between two schema states | ✅ | ✅ | ✅ | SQLite rebuilds a table for changes ALTER TABLE cannot express, including one other tables refer to: the plan brackets itself in PRAGMA foreign_keys. |
| schema fmt (HCL canonical layout) | ✅ | ✅ | ✅ | Formats .hcl paths recursively and prints only changed files. Native ptah schema fmt --check adds a no-write CI gate. |
| schema inspect to HCL, SQL, or JSON | ✅ | ✅ | ✅ | Default HCL; rendered HCL/SQL/JSON use explicit helper templates. Bare and whitespace-wrapped hcl/sql/json are literal template text. Native shorthands still render and add file export. |
| Schema-qualified exclude globs for enums and functions | ✅ | 🟡 | ✅ | Enums and functions match schema-qualified globs on the rule tables and views use, and the match reaches the planned DROP. The community binary matches app.mood; it reports no functions. |
Verb schema stats |
✅ | ❌ | ✅ | Ptah implements it as schema stats inspect on the compat surface and schema stats natively, emitting OpenMetrics counts for 18 object kinds. Unlike Atlas it accepts SQLite. |
Verb schema validate |
✅ | ❌ | ✅ | ptah schema validate and the compat verb report every structural problem in a desired state without a database; exit 1 when any is found. |
Versioned migrations
Section titled “Versioned migrations”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
--dir defaults to file://migrations |
✅ | ✅ | ✅ | Every migrate verb documenting a --dir default uses file://migrations. Never a fallback: the flag, PTAH_DIR, PTAH_MIGRATIONS_DIR and atlas.hcl outrank it, and atlas.sum is still gated. |
| An empty migration directory is not a checksum error | ✅ | ✅ | ✅ | ptah-compat migrate validate and migrate lint --latest exit 0 on a directory holding no migration files. Native ptah migrations validate and ptah migrations lint keep their refusals. |
| Apply pending migrations (apply/up) | ✅ | ✅ | ✅ | Dry runs read stored revisions and select only pending files. Per-migration timeouts reach every target whose server takes one; a dry run defers later checks. |
Atlas R-suffixed (1R_, R__) migration execution |
✅ | ✅ | ✅ | Both execute a native Atlas R or <number>R file once and record its version token, and neither reapplies it when the body changes: reapply-on-checksum is a Flyway feature. |
Atlas SQL template migrations (--atlas-env) |
✅ | ❌ | ❌ | Go-template actions in Atlas-format migration files render before execution with .Env set by --atlas-env; sibling *.sql files supply shared {{ template }} definitions. CE runs the braces as SQL. |
| Atlas txtar migration sections (– atlas:txtar) | ✅ | ❌ | ✅ | -- atlas:txtar executes migration.sql/down.sql and enforces checks.sql plus ordered checks/*.sql, including atlas:assert oneof; unrelated files are ignored. CE runs every section as plain SQL. |
| Atlas-format checkpoint output | ✅ | ❌ | ✅ | migrate checkpoint --dir-format atlas writes the single -- atlas:checkpoint file plus atlas.sum, and is compat’s default; --dir-format ptah writes the reversible pair. Up-only, as Atlas is. |
| Baseline an existing database | ✅ | ✅ | ✅ | Ptah adds a standalone baseline verb with --shadow-db verification and --dry-run; CE exposes baselining as migrate apply --baseline. |
| Create an empty migration file | ✅ | ✅ | ✅ | Native create writes an up/down pair; compat new writes the selected layout’s skeleton for atlas and all five external formats, refreshes atlas.sum, --edit opens $VISUAL or $EDITOR on atlas. |
| Direct Flyway revision identity | ✅ | ✅ | ✅ | Flyway tokens persist; numeric keys order them. Empty identities render as “”. Baselines use raw-token order. A repeatable target preserves history CE deletes; unknown roles and ties fail closed. |
| Directory integrity file and execution gate | ✅ | ✅ | ✅ | Both sums support hash/validate. Native SQL execution gates hashed dirs; compat apply/status/set/new/diff/down do too. Import verifies source sums. Replay uses one verified snapshot and refuses drift. |
| Directory maintenance: edit, rebase, rm | ✅ | ❌ | ✅ | Each rewrites ptah.sum/atlas.sum and refuses a migration applied in --db-url unless --force; CE aborts all three as non-community verbs. |
Dynamic down planning (migrate down --plan) |
✅ | ❌ | ✅ | --plan builds the target schema on --dev-url and derives the rollback from the difference, so a migration with no down body is revertible. --to-tag and --skip-checks land too. |
Execution order (--exec-order) |
✅ | ✅ | ✅ | linear fails on a pending migration below the current version, linear-skip leaves it pending, and non-linear applies it. Atlas chained revision hashes remain valid after an insertion. |
External --dir-format outside migrate import |
✅ | ✅ | ✅ | Five external layouts read and write, and all five carry a no-transaction requirement in whatever their own format offers – a directive, a sidecar, or a migration of its own. |
| Failed rollback state is recorded and recoverable | ✅ | ❌ | ❌ | Ptah records failed rollback direction, error, and completed-statement count in both revision-table formats; compat keeps the Atlas schema but does not copy Atlas’s hidden failed-down state. |
Flyway repeatable (R__) migration import |
✅ | ✅ | ✅ | Compat import converts R__ to a one-time migration ordered last, as the format requires. Editing the body is then refused, naming the conversion and both remedies. |
| Generate migrations from a schema diff | ✅ | ✅ | ✅ | diff and new stamp the UTC second, stepping past a version already taken; checkpoint and rebase bump past the newest. A plan mixing transaction modes is split into ordered files. |
migrate apply --allow-dirty semantics and the not-clean adoption gate |
✅ | ✅ | ✅ | Exact-identity retries require the current provider to own the dirty body; the flag also permits unmanaged-object adoption. Recovery preserves the committed prefix. |
| Migration checkpoints (squash history) | ✅ | ❌ | ✅ | Replays the directory on --shadow-db into a cumulative checkpoint: the ptah reversible pair, or Atlas’s single -- atlas:checkpoint file under --dir-format atlas. CE gates the verb. |
| Migration import from other tools | ✅ | ✅ | ✅ | Native import writes Ptah format; compat import writes Atlas format and orders R__ last. All four Liquibase serializations import; unconvertible changelog constructs are refused by name. |
| Migration linting | ✅ | 🟡 | ✅ | CE registers migrate lint with Open rules; its features page marks the CLI Pro. Compat requires --dev-url. --latest 0 disables latest selection but preserves Git; opt-ins lift each precondition. |
Migration lock, lock timeout, --lock-name, --skip-lock |
✅ | 🟡 | ✅ | Compat --lock-timeout bounds directory and dev-db locks. --lock-name and --skip-lock on migrate apply are Pro surface adopted openly; CE registers only --lock-timeout. |
| Migration status report | ✅ | ✅ | ✅ | Compat status mirrors the Atlas default report shape and renders Go templates over .Env, .Available, .Applied, .Pending, .Current, .Next. Native ptah keeps its own block. |
| Online DDL routing via gh-ost or pt-osc | ✅ | ❌ | ❌ | ptah.yaml online_ddl.tool (ghost|pt-osc), threshold_rows, args, and fallback (error|plain) route large-table ALTERs through an online-DDL tool during migrations up/down. CE has no such routing. |
Pre-migration database backups (--pg-dump-to) |
✅ | ❌ | ❌ | --pg-dump-to writes a pg_dump custom-format backup and --mysqldump-to a SQL backup before applying or rolling back; ptah.yaml key migration.pg_dump_to. |
| Pre-migration webhook and shell hook gates | ✅ | ❌ | ❌ | --webhook POSTs migration metadata and requires HTTP 200; --pre-up-hook/--pre-down-hook run a shell command that must exit 0, else the run aborts. Also ptah.yaml migration.webhook/pre_up_hook. |
Prometheus metrics endpoint (--metrics-addr) |
✅ | ❌ | ❌ | migrations up, down, and status serve a Prometheus /metrics endpoint at the given address for the run. |
| Repair dirty or partial revision state | ✅ | ❌ | ❌ | Under the migration advisory lock, --resume-from verifies the committed prefix, then finishes up before marking applied or down before removing the revision. Atlas CE has no repair verb. |
Report of an ignored --dir URL query key |
✅ | ❌ | ❌ | Only ?format= selects a layout. On the eight verbs accepting a --dir query, other keys are ignored, named on stderr, exit 0 unchanged; PTAH_STRICT_DIR_QUERY=1 refuses. Six verbs take no query. |
| Revision table format and placement | ✅ | ✅ | ✅ | --revision-format ptah|atlas plus --migrations-table and --migrations-schema; the compat path defaults to Atlas rows. |
| Roll back applied migrations (down) | ✅ | ❌ | ✅ | Ptah validates all down bodies before changing state, dry-run reports separate preflight rejection from attempted rollback, and --plan, --to-tag and --skip-checks are implemented. |
| Set revision state to a version | ✅ | ✅ | ✅ | Removes revision rows above the target, keeps rows at or below it, and inserts missing rows through it as manually set. |
Structured JSON log output (--log-format) |
✅ | ❌ | ❌ | migrations up, down, and status take --log-format text|json and --log-level debug|info|warn|error for machine-readable run logs. |
Transaction modes (--tx-mode file/all/none) |
✅ | ✅ | ✅ | File/all/none behavior is tested and none-mode partial progress is pinned both ways. --tx-mode all decides on transactional DDL and carries neither checks nor timeouts. |
Verb migrate ls |
✅ | ❌ | ✅ | ptah migrations ls lists a migration directory with no database; ptah-compat migrate ls is the drop-in spelling (--dir, -s, -l). Beyond the CE pin, so strict compatibility omits it. |
Verb migrate show |
✅ | ❌ | ✅ | ptah migrations show prints a stored migration’s SQL with no database; ptah-compat migrate show {name | version}... is the drop-in spelling. Beyond the CE pin, so strict compatibility omits it. |
Linting and safety
Section titled “Linting and safety”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
migrate lint requires --latest or --git-base |
✅ | ✅ | ✅ | Refused before the directory is read and before --dev-url is contacted. PTAH_ATLAS_LINT_ALL_VERSIONS=1 restores linting the whole directory here; native ptah migrations lint needs no scope. |
schema apply --skip-lint |
✅ | ❌ | ✅ | With an atlas.hcl lint policy, the planned SQL is linted against the rules it names and an error-rated finding refuses the apply; --skip-lint applies anyway. No policy, no lint pass, as in CE. |
| Analyzers that need a dev-database schema diff | ✅ | ✅ | ✅ | Rules declare whether they read migration SQL or the replayed dev schema; the versions read come from that declaration, and a rule that asks and gets nothing says so on stderr. |
| Apply-time destructive-change gate | ✅ | ❌ | ➖ | migrations up refuses destructive pending files; .ptah-lint.yaml disabled-rules reopens the gate and ptah.sum does not hash that file. |
| Atlas Pro analyzer code coverage | ✅ | ➖ | ✅ | OW101/OW102 are recorded waivers: both bind to an account model Ptah has none of. Every other Atlas code is accepted in a lint config, aliased where the rule is spelled differently. |
Atlas web reports (--web) |
🔷 | ❌ | ✅ | The flag publishes a report into the hosted web UI and is rejected here as unknown. Ptah renders the same lint and diff findings locally through --format, including {{ json . }}. |
| Check bypass on the compat surface | ✅ | ❌ | ❌ | No Atlas build registers --skip-checks on migrate apply, so the compat bypass is PTAH_SKIP_CHECKS. On migrate down the flag is registered and reads the same variable. |
| CI integration (GitHub Action, annotations) | ✅ | 🟡 | ✅ | stokaro/ptah-action@v1 posts a sticky PR comment; --format github-actions emits annotations. The community binary has no annotation mode; its lint --format takes a Go template only. |
| Custom lint rules and check-level policy | ✅ | ❌ | ✅ | A rule is declared in .ptah-lint.yaml or in an atlas.hcl rule block as an expression over the statement. Atlas review, naming, non_linear and force stay accepted and reported as having no effect. |
| Default-firing Atlas analyzer concern mapping | ✅ | ➖ | ➖ | lint-analyzer-catalog maps every default-firing Atlas concern to a covering Ptah rule, severity and line; 0 gap on the committed corpus. |
Dev-URL schema scope on migrate lint |
✅ | ✅ | ✅ | ptah-compat migrate lint reviews only the schema the dev URL’s search_path names, matching the pinned CE binary. Native ptah migrations lint reads SQL text and deliberately does not scope. |
| Generation-time destructive-change gate | ✅ | ❌ | ❌ | migrations generate and plan fail with --check-destructive when the generated SQL contains destructive statements; --allow-destructive reopens the gate. Distinct from the apply-time gate row. |
| Inline nolint suppression | ✅ | ✅ | ✅ | Every code the compat surface prints is silenced by that code; analyzer names work on both surfaces; a blank line detaches a directive. Unknown selectors accepted silently, matching CE. |
| Native migration lint rule set | ✅ | 🟡 | ✅ | 42 codes across 9 families, gated by --dialect. Atlas lists destructive and backward-incompatible rules Open; concurrent-index rules Pro. |
| Per-rule severity policy | ✅ | ❌ | 🟡 | Severity vocabulary is info|warning|error; only error gates. The community binary carries no severity attribute: it accepts one and ignores it, exactly as it treats an invented attribute. |
| Pre-migration assertion checks | ✅ | ❌ | ✅ | Scalar SELECTs in either direction; txtar checks.sql and checks/*.sql support all-of/oneof groups. One failure mode, abort, and no checks under --tx-mode all. |
| SARIF 2.1.0 lint report | ✅ | ❌ | ➖ | Native --format sarif emits SARIF 2.1.0 with ruleId, level and file:line; Atlas documents Go-template --format output for migrate lint. |
| Schema security findings over roles, grants and policies | 🔷 | ❌ | ✅ | Findings over a live schema’s grants, policies, routines and role graph: code, severity, structured detail and a suggestion, local and with no account. Skipped rules are named rather than silent. |
Standalone SQL file linting (ptah sql lint) |
✅ | ❌ | ❌ | Lints arbitrary SQL files or stdin against per-dialect capability presets (9 dialects incl. sqlserver), refined by a --server-version server string; text/json output, rule disable. |
| Statement safety classification report | ✅ | ➖ | ➖ | plan --report text|html|json and generate --report html|json emit highest severity, a destructive flag, and per-statement assessments. |
Testing
Section titled “Testing”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
Atlas .test.hcl ingestion |
✅ | ❌ | ✅ | Implemented: .test.hcl runs beside YAML on schema test, migrate test and schema plan test, with for_each, var, self, catch, assert, log, cleanup, gated external and parallel. |
| Atlas CE strict oracle profile | ✅ | ➖ | ➖ | Strict mode builds the CE tree and refuses unsafe sources, migration extensions, and catalog-only live objects before output, comparison, or mutation. Default retains the full surface. |
| Atlas-shaped migrate test / schema test verbs | ✅ | ❌ | ✅ | Reports and seed directories are exposed. schema test accepts -s/--schema, Go, SQL/HCL, database or env:// sources; --var reaches HCL files. |
| Dev / shadow database verification | ✅ | ✅ | ✅ | --shadow-db on generate, checkpoint, baseline and down; schema apply --dry-run runs the real rehearsal. All four resolve a docker:// shadow value. |
| Embeddable test runner (Go package) | ✅ | ❔ | ❌ | migration/dbtest exports RunMigrationTest and RunSchemaTest. CE stays unknown: a CLI probe cannot see a Go API; an Atlas-side source naming a test-runner entry point would settle it. |
| Exit-code contract for CI gates | ✅ | ✅ | ➖ | Native 0/1/2 separates expected negative results from command errors; ptah-compat collapses to Atlas CE 0/1, recovered panics still exit 2. |
Migration test framework (ptah migrations test) |
✅ | ❌ | ✅ | Declarative YAML cases: migrate_to, apply_schema, seed, exec, assert. Fresh ephemeral SQLite per case unless --db-url is set. |
Schema test framework (ptah schema test) |
✅ | ❌ | ✅ | Desired schema from Go annotations, SQL or HCL files, or a live database converges before steps. HCL sources take repeatable --var; migrate_to is rejected. |
Configuration and dev databases
Section titled “Configuration and dev databases”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
--var does not require an atlas.hcl |
✅ | ✅ | ✅ | -c and --env select a project file and still require one. --var only supplies values to one, on every verb. Its syntax is still checked with no atlas.hcl present. |
A malformed --var is refused wherever it is spelled |
✅ | ✅ | ✅ | CE parses --var while parsing flags, so a value with no = is refused before any project file is sought. Ptah checks it on every command under schema and migrate, even ones that never read it. |
| Atlas project config (atlas.hcl) | ✅ | ✅ | ✅ | Envs, variables, locals, data sources and for_each are evaluated. A collection env expands where a verb takes one and is refused by name elsewhere. |
| atlas.hcl file() and fileset() path confinement | ✅ | ❌ | ❌ | Ptah confines file() and fileset() to the atlas.hcl directory: absolute, parent-traversal and symlink escapes are refused by name. Atlas reads them. Deliberate divergence; exit 1 either way today. |
| atlas.hcl from the native ptah binary | ✅ | ➖ | ➖ | ptah --env reads ./atlas.hcl, --config names one anywhere else when the path ends in .hcl, and --var name=value supplies a variable with no default on every env-aware verb. |
| AWS RDS token project data source (data “aws_rds_token”) | ✅ | ✅ | ✅ | Resolves to a SigV4 rds-db connect token, matching the pinned community binary parameter for parameter. endpoint and username required; region and profile optional. |
| data “hcl_schema” reference | ✅ | ✅ | ✅ | Takes path, paths and vars, and exports .url. vars is scoped to the files that data source selects and --var does not cross that boundary, as on CE. A bad path or scheme names its rule. |
Docker dev databases (docker:// --dev-url) |
✅ | ✅ | ✅ | Every verb taking a dev or shadow URL provisions and removes a container. schema plan starts none on purpose: a saved plan reads local files and has nothing to replay. |
| env:// desired-state references | ✅ | ✅ | ✅ | Resolves on --to/--from/--url, on --schema-file and on schema test’s -u when a run selects an env. Refusing on --exclude/--include is deliberate. |
| External program project data source (data “external”) | ✅ | ✅ | ✅ | Runs argv directly without a shell and returns untrimmed stdout. Caller cancellation, a 60-second timeout, bounded output, process-tree termination, and sanitized errors define the boundary. |
| GCP Cloud SQL token project data source (data “gcp_cloudsql_token”) | ✅ | ✅ | ✅ | Resolves to an OAuth2 access token from application default credentials under the sqlservice.admin scope. The block takes no required attribute. |
| Native project config (ptah.yaml) | ✅ | ➖ | ➖ | Keys url, dev, schemas, exclude, external_schema, migration, lint, migrate, diff, online_ddl. No variables or functions. An unknown key fails, naming the key, its line, and the accepted keys. |
| PTAH_* environment-variable flag equivalents | ✅ | ❌ | ❌ | Every flag on every native verb has a documented PTAH_* environment variable ([env: PTAH_X] in help) except the --auto-approve flags, which stay explicit-only. CE annotates no flag with one. |
| Remote directory project data source (data “remote_dir”) | ✅ | ❌ | ✅ | Resolves through Ptah’s OCI backend: name, tag and version map onto a movable or a write-once tag in the namespace PTAH_ATLAS_REGISTRY names. |
| Remote schema project data source (data “remote_schema”) | ✅ | ❌ | ✅ | data "remote_schema" resolves through Ptah’s OCI backend via an internal marker. The oci:// spelling stays refused on compat flags, where the community binary answers unknown driver. |
| Runtime variable project data source (data “runtimevar”) | ✅ | ✅ | ✅ | Reads Go CDK runtime-variable URLs with byte-preserving string output and a configurable positive timeout. Constant, file, HTTP(S), AWS, and Google Cloud providers are registered. |
| SQL project data source (data “sql”) | ✅ | ✅ | ✅ | Runs one query and exports count, first value, and all values. Requires one column and one HCL row type. Heterogeneous rows fail explicitly; Atlas CE panics. Unreferenced blocks stay lazy. |
| Template directory project data source (data “template_dir”) | ✅ | ✅ | ✅ | Shared Go templates emit root lowercase .sql migrations only. New and diff synchronize new files and checksum to the confined source path; hash-only stays virtual. |
| Variables, locals, and HCL functions | ✅ | ✅ | ✅ | Variables, locals and data sources are evaluated in both files, against one function set: the project evaluator shares the schema evaluator’s, overlaying the three names bound to its own directory. |
Databases and schema objects
Section titled “Databases and schema objects”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
Capability profile of a live target (ptah db capabilities) |
✅ | ❔ | ❌ | Reports the dialect, resolved preset and how it was reached, the support level and every capability key for a connected server, as text or stable JSON. No source here names an Atlas equivalent. |
| ClickHouse (clickhouse, ch) | ✅ | ❌ | ✅ | Tables, indexes, plain views, materialized views including the refreshable form, roles, grants, row policies and named table CHECKs. Other kinds are named on render and on the plan path. |
| CockroachDB (cockroachdb, crdb) | ✅ | ❌ | ✅ | CONCURRENTLY, XML, advisory locks and DEFERRABLE are engine limits; 25.4 also refuses generic DROP CONSTRAINT, and 26.2 accepts it. Row-level TTL is fully managed. |
| Declared support level per database release line | ✅ | ❔ | ❔ | Every declared release line carries a support level, counted in the generated table the evidence names. End-of-life lowers the level, not the behavior; an undeclared line resolves to best-effort. |
| Domains, composite types, and range types | ✅ | ❌ | ✅ | Domains and composites compare and change in place, each kind gated per target. Range types rebuild because PostgreSQL offers no ALTER TYPE … AS RANGE. |
| Enum types | ✅ | ✅ | ✅ | An enum is whatever the schema declares as one. PostgreSQL alters values in place; MySQL, MariaDB, SQLite and SQL Server carry them in the column type or a check constraint. |
| Extensions | ✅ | ❌ | ✅ | PostgreSQL and YugabyteDB create, compare and relocate extensions, version included. Every other target names the declaration it cannot host rather than dropping it. |
| Functions | ✅ | ❌ | ✅ | Functions and procedures render, read and plan on the PostgreSQL and MySQL families and SQL Server. ClickHouse and SQLite host neither. |
| MySQL and MariaDB | ✅ | ✅ | ✅ | Roles, grants, stored functions and MariaDB sequences render, read back and plan. An inline enum change plans a real MODIFY COLUMN and converges; matviews fail closed. |
| Oracle, Snowflake, Redshift, Databricks | 🟡 | ❌ | ✅ | Oracle renders, plans, reads and converges; Snowflake, Redshift and Databricks have no endpoint anyone can measure and are out of scope with the reason (stokaro/ptah#1875). |
| PostgreSQL 12+ (postgres, postgresql) | ✅ | ✅ | ✅ | Reference engine of the PostgreSQL family: views, matviews, functions, triggers, sequences, roles, RLS and domains all render. Presets 12-13, 14-16, 17+ from the server banner. |
| Roles, grants, and row-level security | ✅ | ❌ | ✅ | Roles and grants wherever the role_management key is true, which the preset matrix names. Row-level security on the PostgreSQL family, SQL Server and ClickHouse; the rest have no such object. |
| Spanner PostgreSQL interface (spanner) | ✅ | ❌ | ✅ | Enums, matviews, functions and triggers render as named skips; sequences render with the start counter only, foreign keys render, SERIAL errors. Probed live, with a compose service and a suite. |
| SQL Server and Azure SQL (sqlserver, mssql, tsql) | ✅ | ❌ | ✅ | Every spelling renders the same DDL. Tables, views, triggers, synonyms, sequences, roles/grants, row-level security, functions and extended properties all render, read back and plan. |
| SQLite (sqlite, sqlite3) | ✅ | ✅ | ✅ | Column drops, type, nullability, default, generated, table-constraint and add-column changes all rebuild, inbound foreign keys included. The engine has no other object kind Ptah models. |
| Standalone sequences | ✅ | ❌ | ✅ | Every target with standalone sequences emits, reads and plans them, Spanner included. MySQL, ClickHouse and SQLite have none and name the omission (stokaro/ptah#1856). |
| TiDB and LibSQL | ✅ | ✅ | ✅ | TiDB is reached through mysql://, which both binaries do and neither exposes as its own driver. libsql:// and libsql+ws:// resolve onto the SQLite dialect over the remote transport. |
| Triggers | ✅ | ❌ | ✅ | Every engine spelling renders the same trigger DDL and four readers read them back. ClickHouse and Spanner have none and name the omission; MySQL statement triggers and SQL Server BEFORE do not exist. |
| Views and materialized views | ✅ | ❌ | ✅ | Plain views work everywhere. Materialized views render on PostgreSQL, CockroachDB, YugabyteDB and ClickHouse, whose scheduled form carries its REFRESH EVERY|AFTER clause. |
| YugabyteDB (yugabytedb, ysql) | ✅ | ❌ | ✅ | Roles, grants, RLS, sequences, domains, views, matviews, functions, triggers and CREATE INDEX CONCURRENTLY are enabled. Three keys stay off because the server refuses them, not Ptah. |
Go embedding and developer tooling
Section titled “Go embedding and developer tooling”| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
| Annotation metadata as JSON Schema | ✅ | ➖ | ➖ | Emits a JSON Schema describing every //ptah directive and attribute; Atlas has no //ptah annotation set for the concept to apply to. |
| API schema export: OpenAPI 3.0 and GraphQL | ✅ | ❌ | ❌ | Exports from Go, YAML, HCL, SQL, or DBML. Go, YAML, and HCL author metadata; SQL and DBML derive public names from storage. No handlers or resolvers. Absent from CE inventory and cited Pro list. |
| Concurrency-guarded migration plan publication | ✅ | ➖ | ➖ | generator.PlanMigration binds a plan to a directory snapshot; WriteFiles rejects changed history (ErrMigrationDirectoryChanged) under a cross-process lock; concurrent reuse fails (ErrMigrationPlanInUs |
| Go annotations to HCL export with cleanup | ✅ | ➖ | ➖ | Writes HCL from Go annotations; cleanup requires zero diagnostics and refuses unparsed directives. Opaque function, view, materialized-view, and trigger bodies are reported and block cleanup. |
| Pinned database sessions (WithSession) | ✅ | ➖ | ➖ | WithSession on DatabaseConnection pins one physical session for a callback, rebinding reader/writer/SQL runner, and discards the connection so session state cannot leak. |
| Protobuf schema export with pinned field numbers | ✅ | ❌ | ❌ | Edition 2023 from Go, YAML, HCL, SQL or DBML. Go, YAML and HCL author export metadata; SQL and DBML carry storage only. --out pins field numbers and compatibility policies. Not in CE inventory. |
| ptah-ls annotation language server | ✅ | ➖ | ➖ | stdio LSP over //ptah annotations: hover, completion, diagnostics, plus a VS Code extension. Tied to Ptah’s own annotation syntax. |
| Public API compatibility gate | ✅ | ➖ | ➖ | check-public-api.sh keeps the committed API baseline and the package tree in sync; pre-v1 breaks need a per-baseline approval line. |
| Query builder for parameterized SQL | ✅ | ➖ | ➖ | Joins, DISTINCT, GROUP BY, HAVING, RETURNING, LIKE, upsert, CTEs, subqueries, arithmetic, function calls, INSERT … SELECT and window functions all render. No frame clause yet. |
| Reusable Go packages (embedder API) | ✅ | ➖ | ➖ | Documented embedder packages cover parse, diff, plan, render, migrate, lint and seed. CE conformance measures CLI commands, not Go APIs. |
| Schema visualization (ERD diagrams) | ✅ | ❌ | ✅ | Mermaid, DOT or SVG ERD from Go annotations only; SVG shells out to Graphviz dot. Atlas ERD lives in the hosted service (any plan per its pricing page); the CE binary rejects --web. |
| Statement observer and validator hooks (Go API) | ✅ | ➖ | ➖ | migrator.WithStatementObserver runs a read-only callback per executed statement; WithStatementValidator gates all statements pre-execution; both compose with StatementInterceptor. |
| testkit companion module for database tests | ✅ | ➖ | ➖ | Separate repository and module go.5x5.cz/ptah/testkit wraps testcontainers-go for tests needing real databases; versions independently and stays out of the main module graph. |
Data and distribution
Section titled “Data and distribution”Ptah’s registry story differs from Atlas’s in storage, not in function.
Everything artifact distribution needs — publish a migration directory or a
desired schema, pull it elsewhere, pin an exact version, run migrations
straight from the registry — works against any OCI-compliant registry: GHCR,
ECR, GAR, Harbor, Docker Hub, or a self-hosted registry:2.
For a team this means the registry and credentials already used for container images also serve schema artifacts; there is no separate account, login verb, or hosted service to depend on; and a digest pin makes a deployment reproducible byte for byte. The artifacts are ordinary OCI 1.1 manifests, so registry-side controls — replication, retention, immutable-tag policy, access control — come from the registry, not from Ptah. The full workflow is on OCI registry artifacts.
| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
Artifact integrity check (--verify-sum) |
✅ | ➖ | ❌ | On migrations push (local, pre-upload) and on up/down/status (pulled). A sum checks a directory against the sum stored beside it, so an oci:// tag proves internal consistency only; pin a digest. |
| Declarative reference data | ✅ | ❌ | ✅ | //ptah:schema:data rows diffed by key into a reversible data migration. Atlas lists declarative data management as a Pro feature. |
| Digest pinning and write-once version tags | ✅ | ➖ | ❌ | Pushing to an @sha256 reference is refused; --version is write-once and a conflict exits 2. The reference tag, --tag values and latest all move. |
| Environment-scoped SQL seed runner | ✅ | ❌ | ❌ | NNN_desc.env.sql files recorded in schema_seeds with protected-env gates. No seed verb in the CE inventory or the cited Pro list. |
oci:// as a --schema-file desired-state source |
✅ | ❌ | ✅ | Accepted wherever a desired state or a migration directory is read from a registry. Every verb that resolves one exposes --plain-http, and a walk of the command tree gates the pairing. |
| Referrer attachments: lint, plan, deployment reports | ✅ | ❌ | ❌ | lint --attach, migrations plan --attach and up attach reports to an exact digest, and oci fetch returns the payload behind a descriptor rather than the descriptor alone. |
Registry-backed distribution: oci:// vs atlas:// |
✅ | ❌ | ✅ | atlas:// functions — publish, pull, digest-pin, run migrations directly, schemas via --schema-file — over any OCI registry, no account. See OCI registry artifacts. |
Atlas Registry and Cloud
Section titled “Atlas Registry and Cloud”These rows are the services Atlas hosts on top of its registry — approvals,
reporting, monitoring, the atlas:// scheme itself. They concern the hosted
service, not artifact storage; the storage function is covered under
Data and distribution.
This is where 🔷 and ❌ have to be read apart. 🔷 means the row’s job is done here already, over an ordinary OCI registry and local plan files, and only the hosted protocol is out of reach — nothing to wait for. ❌ means the capability is genuinely absent and the difference column names the issue that owns it.
| Capability | Ptah | CE | Pro | Difference |
|---|---|---|---|---|
atlas:// vendor protocol |
🔷 | ❌ | ✅ | Ptah addresses any OCI registry with oci:// and its own push and pull verbs. The vendor spelling resolves against the namespace PTAH_ATLAS_REGISTRY names, on desired-state flags and atlas.hcl. |
migrate push and schema push |
🔷 | ❌ | ✅ | ptah schema push and ptah migrations push publish to any OCI registry. The Atlas verbs address the hosted registry an account owns; the compat stubs say so and exit 1. |
schema plan --edit and --name-format |
✅ | ❌ | ✅ | --edit preserves comments and re-derives dialect-aware severity; --name-format uses Atlas-shaped Base64 .FromHash/.ToHash values. |
schema plan --format and --directive |
🔷 | ❌ | ✅ | Both are implemented under Ptah’s own payload and directive vocabulary. Atlas gates the verb behind its hosted registry, so its field names and directive set are not obtainable. |
schema plan --push, --pending, --repo |
🔷 | ❌ | ✅ | All three name a repository in the hosted registry and fail loudly. Ptah’s plan workflow saves and reads local plan files instead, so the function is here and the service is not. |
schema plan --skip-lint |
✅ | ❌ | ✅ | Accepted, and does nothing: schema plan runs no lint step, so there is nothing to skip. A Pro pipeline passing it keeps working; no check is loosened. |
schema plan lint |
✅ | ❌ | ✅ | Implemented: the plan is verified against the transition, then Ptah’s lint rules report on its SQL. Findings do not change the exit code; an opt-in variable makes an error-severity finding exit 1. |
schema plan new and schema plan validate |
✅ | ❌ | ✅ | Implemented. Flag sets match the documented Atlas help; runtime parity remains unverified. Successful Ptah runs keep stderr free of development notes. |
schema plan test |
✅ | ❌ | ✅ | Runs test "plan" cases: establish a state, verify the plan was computed for it, apply the plan file, assert. Local by its flag set, and now by its implementation. |
schema plan registry sub-verbs (approve, list, pull, push, rm) |
🔷 | ❌ | ✅ | These five arbitrate plan state inside the hosted registry. Ptah keeps plan state in local plan files that the ordinary schema plan verbs read and write; the service is out of reach. |
| Atlas Cloud deployment reporting | 🔷 | ❌ | ✅ | Ptah attaches a deployment-report referrer to its own OCI artifact after an oci:// migrations up, so the report is readable from the registry. There is no account model to report into. |
| Atlas Copilot (AI assistant) | 🔷 | ❌ | ✅ | ptah mcp gives any AI client Ptah’s schema operations over the Model Context Protocol, locally, plus a gated write surface for migration, schema and test files (stokaro/ptah#1487). |
| Column-level data lineage | ✅ | ❌ | ✅ | ptah schema lineage derives column-to-column edges from view and materialized-view bodies and emits them as a table or JSON. A body it cannot resolve is reported, not omitted. |
| Hosted Schema Docs (schema documentation) | 🔷 | ❌ | ✅ | ptah schema export --to markdown writes reference documentation locally: a section per table with columns, types, defaults, keys, comments, indexes and enums. Not a hosted service. |
| Reviewer approval and policy workflows | ✅ | ❌ | ✅ | ptah schema approve signs a plan with an SSH key; --require-approval refuses to apply one that does not verify against a committed allowed_signers file. No identity service. |
| Schema monitoring, hosted UI, login | 🔷 | ❌ | ✅ | ptah schema serve shows drift live and schema export --to html writes the same view as one file. No login, and none intended (stokaro/ptah#1857). |
How these rows were established
Section titled “How these rows were established”The Ptah column is derived from the built binaries. ptah --help and
ptah-compat --help are the strongest available proof that a capability
exists, and a row that could not be demonstrated that way is marked 🟡 with the
limitation named, or ❌.
🔷 is the one verdict --help cannot settle on its own. It is claimed only
where two things hold at once: the capability is demonstrable on a Ptah
binary in a Ptah spelling, and the remainder is access to a service another
company hosts behind its own accounts. Both halves are stated in the row’s
difference column, so the claim can be argued with. Where only the first holds,
the row is ✅; where only the second does, it is ❌ with an issue.
The Atlas columns are narrower on purpose. Ptah is a clean-room implementation that studies observable behavior only, so the Atlas CE column is derived from the command, usage, and flag inventory the conformance harness reads out of the pinned Atlas community binary, and the Pro/Cloud column from the classification Atlas publishes on its feature availability page. Where neither source settles a question, the row says so rather than guessing.
The full per-row evidence — the command that was run or the source cited for
every cell — is version-controlled at
docs/site/scripts/data/feature-matrix-rows.json, so a row can be re-verified
or disputed without archaeology.
Four sources carry most of the weight:
cli-surface.mdinventories every command in Atlas CE v1.3.0 and classifies it as an OSS parity target or out of scope, with the reason recorded per command.ce-gating.mdgoes further than the inventory: it runs the pinned CE binary through the capability set this page asserts about the CE column and records the observed class per scenario — works, community-abort stub, absent verb, unknown flag, or silently unenforced. A version bump that changes Atlas’s gating turns that gate red.gaps.md,gaps-live.md, andgaps-diff.mdrecord measured outcomes over Atlas fixtures, live databases, and Atlas CE differential checks.docs-surface.mdindexes the full atlasgo.io documentation universe — 351 pages from the site’s own sitemap — into a triage registry, so parity is built against the whole documented Atlas surface rather than a hand-picked subset. The registry starts mostly untriaged and its budget ratchets down as pages are worked through (campaign); a weekly job re-fetches the sitemap so new or renamed Atlas docs pages surface as red rather than silently missing from this page.
What this page does not claim
Section titled “What this page does not claim”A green conformance run is a floor on the distance to Atlas, never a ceiling. The conformance repository states it directly: no number it produces is a full feature-set parity test, and several runtime dimensions stay unmeasured.
Specifically, this page does not claim that Ptah reproduces Atlas byte for byte, that a ✅ row behaves identically under every flag combination, or that the Atlas columns are exhaustive for capabilities Atlas ships outside its documented CLI surface.
Next steps
Section titled “Next steps”- Differences Ptah keeps on purpose, each with its measurement: Compatibility differences.
- The measured evidence and how to re-run it: Conformance.
- Which Atlas documentation area maps where: Atlas docs coverage.
- Why Ptah can be Atlas-compatible without Atlas code: License boundary.