Skip to main content

Module modules

Module modules 

Source
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 deploy ModuleSelection.
  • [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-time ModuleRuntime: the stored subscription plus the two-phase crossing, delegating all SQL to the tracking store.

Structs§

CouplingViolation
The first intra-migration coupling constraint the classifier found violated: a selected section would run while an EARLIER unselected earlier_section of an established module is still pending — a potential prerequisite.
HistoricalAttribution
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 module attribute.
ModuleGeneration
Module context for one generation run (migrate new / update).
ModulePartition
The validated file→module partition for one project.
ModuleReferenceReport
Findings from validating cross-module object references.
ModuleRuntime
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.
PendingCrossing
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.
SectionClassification
The verdict for one migration’s sections. Every vector pairs a section with its index in the FULL parsed file, so registration section_order stays stable per version regardless of which subset a call handles.
SkippedModule
A skipped module and the notice level to surface for it.
StepSection
A contiguous run of same-module migration steps, ready to render as one -- pgmt:section block.
Subscription
The target’s stored module subscription.

Enums§

ModuleSelection
Which modules a deploy names. Bare apply deploys only the base — modules are always explicit (flag > PGMT_MODULES env), never inferred.
SkipNotice
Notice level for a skipped, unrequested module’s sections.
SubscriptionSource
How a module came to be in the subscription — recorded on the {name}_modules row’s source column for audit.

Constants§

UNMODULED_DISPLAY
Display/input form of the unmoduled base wherever it must be printed or typed (warnings, status output, remaps attributes). 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_version whose base/established-module sections are NOT yet applied on the target — i.e. versions the established set still needs before it is caught up to through_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 None for non-module projects. When divergence exists and re_anchor_allowed is false, fails with re_anchor_guidance appended — the caller supplies the remediation, since only some subcommands own a --create-baseline flag (see the two migrate update call sites, which point the user at migrate new instead 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. None means nothing to write (no changes and — for modules — no module-sourced moves: a pure base-sourced re-tag stays baseline-only). The two migrate update sites that need a String map None to their “– No changes detected” placeholder.
render_sectioned_migration
Render sectioned steps as a migration file: one -- pgmt:section header 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 in migrate 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 in plan_annotated, this only cuts.
validate_module_references
Validate every object-level dependency in the catalog against the module partition and the declared module DAG: