retrofit0.10.0-wip.8

retrofit snapshot

Emit canonical DDL for the materialized schema, shaped like
`pg_dump --schema-only` (docs/pg_dump-parity.md lists the differences).

Run with --help-all for the full --include-drop / --using semantics.

Usage:
  retrofit snapshot [flags]

Flags:
      --allow-reading-replace-body        downgrade the replace-body-reads-relation refusal to a warning; emit the body verbatim under a WARNING comment, and render its table's prologue as a whole-table clear
      --allow-stale-dml                   downgrade every stale-DML-reference refusal to a warning; emit the body under a stale-reference WARNING comment. It does NOT cover chain-collision, which is not attestable: two live chains for one element is a fork to resolve by retiring one, and exit 2 stands
      --allow-unnamed-label stringArray   attest that the dataset carrying this exact label is deliberately left unnamed in this run (repeatable; byte-exact, never trimmed); every other unnamed dataset still warns
      --at root                           emit DDL for the cut at <opid> prefix or anchor (root/`last`/`seal`, optional `^`/`~N`) (default: last)
      --data-only                         emit the data band only: the banner (unless --no-header), then the band as snapshot emits it; no DDL
      --data-root data_root               root that overrides the schema's data_root
      --exclude-schema strings            drop schemas matching <name> from emission (repeatable; pg_dump -N)
      --exclude-table strings             drop tables matching <name> or <schema>.<name> from emission (repeatable; pg_dump -T)
      --extra-seed-path seed_paths        root that appends to the declared seed_paths
  -h, --help                              help for snapshot
      --help-all                          show extended help (vocabulary, semantics, caveats)
      --include-drop string[="scoped"]    DROP prologue before the CREATEs: none | scoped | schema (default "none")
      --label stringArray                 apply the dataset carrying this exact label (repeatable; argv order is layer order; byte-exact, never trimmed; never cuts ref data)
      --no-comments                       suppress every COMMENT ON statement (pg_dump --no-comments)
      --no-header                         suppress the canonical banner line
      --over string                       with --data-only: emit only the tables the LAST-named --label's layer contributed to (a projection, never a diff)
      --schema <name>                     registered schema <name> (resolves via the chain when omitted)
      --seed-path seed_paths              root that replaces the declared seed_paths
      --skip-manifest string              write skipped view-render records (JSONL) to <path>
      --table strings                     restrict emission to tables matching <name> or <schema>.<name> (repeatable; pg_dump -t)
      --using string                      one-shot emit target override (format: <engine>:<major>; read-only)

Global Flags:
      --as string        output mode: text | json (default "text")
  -C, --chdir string     treat <dir> as the working directory for the entire run
      --config string    retrofit.toml path (overrides discovery; also accepts $RETROFIT_CONFIG)
  -f, --file string      oplog file path; selects a registered [[schema]] path (overrides discovery)
      --no-consolidate   render every advisory occurrence instead of collapsing repeats
  -q, --quiet count      suppress the advisory tier on stderr; stack (-qq) to drop it whole (errors and results still print)
  -v, --verbose          reveal info-tier advisories on stderr

Docs: https://docs.retrofit.sh/current/commands/retrofit-snapshot/

retrofit snapshot --help-all adds:

Extended help:

--include-drop modes:

  none     no DROP statements (default); emit pure CREATE.
           Pair with external dropdb/createdb if you need a clean reflash.
  scoped   per-element DROP ... IF EXISTS for tables/indexes/FKs in the
           emission set, then CREATE. Sibling objects in the same schema
           survive. The emitted script fails at apply, and rolls back
           inside its BEGIN/COMMIT, if any table outside the emission set
           holds an inbound FK into the set; pick --include-drop=schema in
           that case.
  schema   one DROP SCHEMA IF EXISTS <name> CASCADE per snapshot schema,
           then CREATE. CASCADE blast radius covers every dependent
           outside the emission set; use only when the developer owns
           the entire schema.

Bare --include-drop (no value) resolves to scoped.

--using=<engine>:<major> overrides the emit target (read-only; one-shot).
Resolution chain when --using is absent: [[schema]] engine_version
(per-schema override) > [project] engine_version (fallback). The flag
value's <engine> must match the project engine; <major> must be in
this build's supported set.

Emit-time filters (pg_dump -N / -t / -T parity):

  --exclude-schema=<name>  drop schemas matching <name> from emission.
                           Exact-match on the registered name (no glob);
                           unknown name refuses with schema-not-in-cut.
  --table=<name>           restrict emission to the listed tables.
                           Accepts <name> or <schema>.<name>; both flag
                           forms repeat (--table=a --table=b). Unknown
                           name refuses with table-not-in-cut.
  --exclude-table=<name>   inverse of --table; drop the listed tables.
                           When both are supplied, exclude wins on
                           conflict (matches pg_dump).

Interactions:

  - --schema picks one schema in scope (root flag). When both --schema
    and --exclude-schema name the same value, the cut's emission body
    is empty (banner survives); when --exclude-schema names a value
    that isn't in the cut, the call refuses (never-silent).
  - --include-drop=schema is incompatible with --table: schema-level
    DROP CASCADE would remove siblings the --table filter spares
    (flag-conflict).
  - --include-drop=scoped + --table emits per-element DROPs ONLY for
    included tables.
  - FK reachability is checked against the filtered set: an FK from an
    included table to an excluded table refuses with
    fk-cross-schema-unreachable. Include the target or drop the FK.

Glob/pattern matching, --strict-names, --filter=<file>, and
--table-and-children are deferred; see docs/pg_dump-parity.md.

Data corpus (--label):

  snapshot always reads the data corpus under the schema's declared
  data_root (retrofit.toml [[schema]].data_root; addressed *.data.<format>
  files, plus readable legacy *.dml.sql files): purpose=ref records (production reference
  rows) apply with zero flags and are never label-filtered; seed
  records are opt-in.

  --label <label> is the WHOLE seed opt-in: it names the dataset to
  apply, and a seed chain no --label names is not applied. The flag is
  repeatable and ORDERED: argv order is layer order, lowest layer
  first, and matching is byte-exact membership (the selector is NOT
  trimmed; a record with no labels matches no selector). Labels are
  stamped at mint time by the producer's own --label. A blank --label
  is rejected (label-empty). Naming a label selects; it never reorders
  the band, whose records keep their intra-anchor seq order.

  Applied seed records are emitted in the
  `-- retrofit:snapshot-data v1` band, between the tables and the
  constraints and indexes (--as=json carries the band on its own
  snapshot-data record). --data-only emits
  that band alone (banner, then band, no DDL); --over <label> narrows
  a --data-only run to the tables the named layer actually contributed
  to (a projection, never a diff).

  Whatever is NOT applied is counted per table WITH ITS CAUSE (not
  selected, superseded, table dropped, or screened by schema
  ownership) and never silently dropped: a machine-parseable data-excluded
  count (stderr warning in text mode, stdout event under --as=json),
  so a label that matched nothing reads differently from one whose
  dataset was superseded. Run `retrofit data list --label <label>` to
  see what a selection resolves to without emitting SQL.

  Before emission, the emitted body follows table and column renames and
  drops removable write-only references to dropped columns; records for
  dropped tables are excluded. snapshot refuses a reference it cannot repair
  (stale-dml-reference) unless --allow-stale-dml is passed.

  Under --data-only, a replace floor's body that reads a relation refuses
  (data-replace-body-reads-relation) unless --allow-reading-replace-body
  is passed, which emits it under a WARNING and clears the table whole.

  Discovery runs BEFORE any DDL byte is written, so a malformed file
  (data-file-malformed), a corpus conflict (dml-data-conflict), or a
  declared-but-absent data_root (data-path-missing) aborts with no
  partial output.

Before 1.0, any release may change behavior; the release notes list what changed.