Skip to content

feat(api): report how an environment's targets diverge on pull - #1271

Draft
aparajon wants to merge 3 commits into
armand/multi-target-apply-fanoutfrom
armand/multi-target-pull
Draft

feat(api): report how an environment's targets diverge on pull#1271
aparajon wants to merge 3 commits into
armand/multi-target-apply-fanoutfrom
armand/multi-target-pull

Conversation

@aparajon

@aparajon aparajon commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Why this matters

Pull materializes an environment's live schema into the repository's schema root. For an environment whose targets each hold their own schema, it reads the primary and returns it as the environment's schema — silently presenting one target's state as all of them. An operator adopting a multi-target database that way would write a schema root that is wrong for every target but one, with nothing in the output saying so.

What it does

Fans out across every target and reports how each one differs from the primary:

pull environment
  ├─ mirrored deployments  → pull the primary only
  └─ targets list          → pull every target, compare each to the primary
                             └─ diverged_tables: differing / primary-only / target-only
  • The response body is still the primary's schema, which is what a caller materializes. Alongside it, each other target reports its table count and the tables the two do not agree on: held by both with different DDL, held only by the primary, or held only by that target.
  • Tables are compared by the dialect parser's canonical form, so a difference in whitespace, keyword case, or clause order never reads as a schema difference.
  • Deployments expected to hold the same schema are neither pulled nor compared. A difference between them is drift for the review-time rollup to block on, and pulling them would cost a round trip each to learn what the configuration already asserts.
  • Fails closed. A target that cannot be read fails the pull rather than being dropped from the comparison, so a partial fan-out never reads as agreement.

How it moves us toward the northstar

Pull was the last read path still collapsing a resolved target list to targets[0]. Consuming the full ResolveTargets result has to hold on reads as well as applies, or an operator's first look at a multi-target database misrepresents it.

Opened by Claude (Fable 5).

aparajon and others added 3 commits September 3, 2026 15:57
An environment whose targets each hold their own schema has no single
live schema, so pulling only the primary presented one target's schema
as the environment's. A pull now fans out across every target and reports
how each one differs from the primary.

The response body is still the primary's schema, which is what a caller
materializes. Alongside it, each other target reports its table count and
the tables the two do not agree on: held by both with different DDL, held
only by the primary, or held only by that target. Tables are compared by
the dialect parser's canonical form, so formatting never reads as a
schema difference.

Deployments that are expected to hold the same schema are neither pulled
nor compared. A difference between them is drift for the review-time
rollup to block on, and pulling them would cost a round trip each to
learn what the configuration already asserts.

A target that cannot be pulled, or a table whose DDL cannot be compared,
fails the pull. Reporting no divergence for a target that was never
compared would describe the environment as converged on the strength of a
comparison that did not happen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant