Expand description
Module partition, sectioning, crossing, and apply-time runtime.
§Concepts
A module is a name attached to a set of schema files (declared via
modules: path globs in pgmt.yaml). From that one binding two derived
bindings follow: objects belong to the module of their defining file, and
migration/baseline sections are tagged with the module whose steps they
carry. Files matching no module form the base — not a module, no
name, always present on every target; it is represented as None
throughout and printed as UNMODULED_DISPLAY where a human needs to
read it.
A subscription is the stored, per-target set of modules a database has — the same species of fact as “which migrations ran”, so it lives in a table beside the migration-tracking table, never derived from config or catalog contents. A module in the subscription is established on that target: its sections run there, and its objects are expected there. The base is established everywhere and never listed.
A re-anchor is a baseline emitted when object ownership moved between modules (a re-tag, split, or merge). Its remap sections are one-time translation instructions to targets: “objects the source module held now belong to the destination”. A plain (checkpoint) baseline carries no remaps and is inert to subscriptions.
A crossing is a target consuming one re-anchor exactly once: check wholeness (would the relabel orphan objects into a module this target does not subscribe?), rewrite the subscription through the remaps, and record the consumption. Consumption is idempotent by construction — a consumed re-anchor is never evaluated again.
Consumption is recorded in the ledger, not a side table. When a
crossing consumes the re-anchor at version V it writes that re-anchor’s own
baseline main row — a what-happened fact recorded where what-happened facts
live — carrying the file’s checksum (which pins the consumed bytes, so an
edited re-anchor is detectable against every target that consumed it). It
also writes zero-trace satisfied section rows for exactly the remap
sections it relabeled (those whose source the target holds); an irrelevant
crossing that relabels nothing writes the main row and no section rows — a
legitimate version-level event that processed no local work.
The consumed-through cursor is DERIVED from those load-bearing rows: the highest baseline version on the target, whether a provision applied it or a crossing consumed it. The crossing loop keys off re-anchors strictly above it, so a crossing may legitimately change nothing else (an irrelevant remap still consumes and still advances the cursor by writing its row), and pruning a consumed re-anchor file from the repo stays safe. Distinct from the applied-baseline watermark (the highest baseline whose sections are all covered on the target — a coverage fact, also computed from section rows), which content-coverage checks use instead.
Layout:
- [
partition] — config-time file→module partition, attribution, reference and divergence validation, and the deployModuleSelection. - [
sectioning] — generation-time cutting of diff steps into module-tagged sections, provenance-cut baselines, and migration/baseline rendering. - [
crossing] — pure re-anchor crossing logic (no database access). - [
runtime] — apply-timeModuleRuntime: the stored subscription plus the two-phase crossing, delegating all SQL to the tracking store.
Structs§
- Coupling
Violation - The first intra-migration coupling constraint the classifier found violated:
a selected
sectionwould run while an EARLIER unselectedearlier_sectionof an establishedmoduleis still pending — a potential prerequisite. - Historical
Attribution - Object → owning module for a reconstructed (starting-state) catalog,
derived by snapshotting object identities after each replayed section and
tagging what appeared with that section’s
moduleattribute. - Module
Generation - Module context for one generation run (migrate new / update).
- Module
Partition - The validated file→module partition for one project.
- Module
Reference Report - Findings from validating cross-module object references.
- Module
Runtime - The per-run module state a deploy command carries: the target’s stored subscription plus the repo’s committed re-anchors. Built once per command (under the advisory lock, after the tracking tables are ensured), mutated only through its own methods so the in-memory view and the stored tables never diverge within a run.
- Pending
Crossing - A gate-passed crossing awaiting its commit (two-phase): the gate ran before version V’s sections; the commit (subscription rewrite plus the baseline row that records the consumption) runs after they complete — acquisition deltas live in migration V itself, so wholeness only finalizes once they’ve run.
- Section
Classification - The verdict for one migration’s sections. Every vector pairs a section with
its index in the FULL parsed file, so registration
section_orderstays stable per version regardless of which subset a call handles. - Skipped
Module - A skipped module and the notice level to surface for it.
- Step
Section - A contiguous run of same-module migration steps, ready to render as one
-- pgmt:sectionblock. - Subscription
- The target’s stored module subscription.
Enums§
- Module
Selection - Which modules a deploy names. Bare
applydeploys only the base — modules are always explicit (flag >PGMT_MODULESenv), never inferred. - Skip
Notice - Notice level for a skipped, unrequested module’s sections.
- Subscription
Source - How a module came to be in the subscription — recorded on the
{name}_modulesrow’ssourcecolumn for audit.
Constants§
- UNMODULED_
DISPLAY - Display/input form of the unmoduled base wherever it must be printed or
typed (warnings, status output,
remapsattributes). The parentheses put it outside the module-name grammar ([a-z][a-z0-9_]*), so it can never collide with a real module and nothing needs to be reserved.
Functions§
- classify_
sections - Classify a migration’s sections into the full deploy verdict. Pure — no DB access, no printing, no bailing; the caller acts on the returned struct.
- display_
module - Human-readable name for an
Option<&str>module. - established_
pending_ through - Migration versions
≤ through_versionwhose base/established-module sections are NOT yet applied on the target — i.e. versions the established set still needs before it is caught up tothrough_version. An empty result means caught up. - evaluate_
module_ generation - Run the module-aware generation checks: cross-module reference validation
(warnings printed, errors fail) and partition-divergence detection.
Returns
Nonefor non-module projects. When divergence exists andre_anchor_allowedis false, fails withre_anchor_guidanceappended — the caller supplies the remediation, since only some subcommands own a--create-baselineflag (see the twomigrate updatecall sites, which point the user atmigrate newinstead of the flag they lack). - parse_
section_ files - Parse every migration and baseline file into its sections, keyed by
(version, is_baseline)— the lookup used to resolve recorded section rows back to their modules. - remap_
source_ held - Whether a re-anchor baseline section’s remap source is already held by a
target with the given established set. A plain section (no
remaps) is never source-covered — it must run. The base source ((unmoduled)) is held everywhere; a module source is held iff established. Provenance-cut guarantees at most one source per section. - render_
generated_ migration - The shared “what SQL does this migration file get” decision for
migrate new/migrate update. A module project renders ordinary diff sections plus, at a re-anchor, the acquisition sections; a non-module project uses the plain diff SQL.Nonemeans nothing to write (no changes and — for modules — no module-sourced moves: a pure base-sourced re-tag stays baseline-only). The twomigrate updatesites that need a String mapNoneto their “– No changes detected” placeholder. - render_
sectioned_ migration - Render sectioned steps as a migration file: one
-- pgmt:sectionheader per section (module-tagged), steps rendered exactly as the header-less renderer would. - section_
baseline_ if_ moduled - Rewrite a freshly created baseline into provenance-cut per-module sections
when the project is moduled (a no-op otherwise). The shared tail of the
create_baseline(...)capture inmigrate new/migrate update: the baseline renders the desired post-V state; the migration’s acquisition sections render from the STARTING catalog instead, so nothing here feeds the migration. - sectionize_
steps - Section a diff into module-tagged sections. Attribute each step to its
owning module, run THE planning pipeline once (
diff::plan_annotated: diff → cascade → coalesce → annotate → module-affinity order), and cut the already-ordered stream at module boundaries. No re-ordering: the ordering lives inplan_annotated, this only cuts. - validate_
module_ references - Validate every object-level dependency in the catalog against the module partition and the declared module DAG: