Skip to content

Postgres -> MSSQL

This guide is a copy/paste-ready starting point for loading data from Postgres into MSSQL with dpone.

Status: Batch ETL supported

Type profile: postgres_to_mssql_native_v2 (applied at Postgres extract via sink-aware schema mapping). Vendor-live evidence uses a wide typed fixture (dpone_srcdpone_it) and covers Docker Postgres → MSSQL strategies full_refresh, incremental_append, incremental_merge, replace, partition_replace, snapshot_diff, scd2, and backfill via tests/integration/postgres/test_postgres_to_mssql_vendor_live_integration.py. bytea uses the hex character BCP wire (encode(..., 'hex') on extract, nvarchar staging, CONVERT(varbinary, …, 2) on finalize). True SQL Server native (bcp -n) producer from Postgres remains a separate path. See Route live wide certification and docs/feature-design-mssql-hex-binary-character-bcp-v1.md.

Vendor-live IT (manual)

docker compose -f docker/docker-compose.integration.yml up -d postgres mssql
export DPONE_RUN_INTEGRATION=1 DPONE_RUN_INTEGRATION_LIVE=1
uv run pytest tests/integration/postgres/test_postgres_to_mssql_vendor_live_integration.py -q

When to use this path

Use this path when Postgres is the system of record or ingestion boundary and MSSQL is the landing, warehouse, event-log, or downstream replication target.

Copy/paste manifest

# yaml-language-server: $schema=../../src/dpone/schema/etl-batch-manifest.schema.json
kind: dpone.batch.v1

defaults:
  name: postgres_to_mssql_example
  source:
    type: postgres
    connection_id: postgres_source
    options:
      batch_size: 50000
      export_format: csv
  sink:
    type: mssql
    connection_id: mssql_dwh
    table:
      schema: dbo
      name: orders
    strategy:
      mode: incremental_merge
      unique_key: order_id
      merge_policy: delete_insert
      duplicate_policy: fail

quality:
  gates:
    - id: source_target_rows
      type: row_count_reconciliation
      severity: error
      tolerance:
        mode: pct
        value: 0.1

schemas:
  public:
    tables:
      - orders

Run it locally:

dpone plan examples/source-sink/postgres-to-mssql.yaml --format md
dpone run examples/source-sink/postgres-to-mssql.yaml

The checked source file is examples/source-sink/postgres-to-mssql.yaml; CI compares its parsed YAML with this block.

If you change the strategy to full_refresh and empty output is invalid, row-count reconciliation is not enough: it can pass a 0 source / 0 target comparison. Add an explicit non-empty target gate:

quality:
  gates:
    - id: target_min_rows
      type: min_rows
      side: target
      threshold: 1
      severity: error

Supported load strategies

These rows describe public runtime contracts, not certification of this exact source, sink, transport, schema-evolution mode, and runtime combination.

Strategy Status Notes
full_refresh Supported Uses staging first, then applies the target-specific finalization plan.
incremental_append Supported Uses staging first, then applies the target-specific finalization plan.
incremental_merge Supported Default merge_policy: delete_insert; shadow_swap is available for DB targets.
replace Supported Uses staging first, then applies the target-specific finalization plan.
partition_replace Supported Replaces target partitions represented by staging partition.column; see Load strategies for native/fallback paths.
snapshot_diff Supported Requires a complete bounded snapshot and unique_key; applies the configured diff/delete policy.

See Load strategies for the detailed algorithm for each strategy. Postgres xmin boundaries and CDC are source capabilities, not load strategies. Select them explicitly through supported source configuration; their state advances only after sink success. Certify the exact CDC route and environment before enabling it.

Runtime algorithm

This sink does not currently implement StagedLoadPort, so this route records governance_finalization=legacy_post_finalize. Blocking gates run only after the sink has mutated or finalized the target. A failure prevents source-state advancement but cannot roll back that target mutation; inspect and repair or deduplicate the target before retrying. See Load governance.

flowchart TD
    A["Resolve manifest and registry entries"] --> B["Create Postgres source"]
    B --> C["Profile partition bounds when bounds=auto"]
    C --> D["Build Spark-like range partitions"]
    D --> E["COPY each partition TO STDOUT"]
    E --> F["Apply BulkTextCodec projection for text safety"]
    F --> G["Emit mssql-delimited file artifacts"]
    G --> H["Create MSSQL staging table"]
    H --> I["Load artifacts into staging with bcp"]
    I --> J["Finalize with delete_insert, shadow_swap, replace, or partition_replace"]
    J --> K["Run quality and reconciliation checks (legacy_post_finalize)"]
    K --> L["Commit state only after target success"]

Native fast path

The official dpone.batch.v1 schema exposes source.options.export_format as csv or binary; the executable example therefore uses csv. The optimized adapter may report wire_format: mssql-delimited in a generated transfer plan. That is an internal transport label, not a value to copy into the public batch manifest.

The preferred high-throughput path is:

  1. PostgreSQL builds a bounded SELECT for the configured strategy.
  2. If partitioning.bounds: auto, dpone runs MIN, MAX, and COUNT over that bounded query.
  3. RangePartitioner creates deterministic half-open ranges.
  4. Each partition is exported through PostgreSQL COPY (...) TO STDOUT.
  5. Text-like columns are projected through BulkTextCodec before COPY, so NULL, empty strings, tabs, newlines, and control characters remain distinguishable for SQL Server bcp.
  6. MSSQL sink loads each artifact into staging through bcp.
  7. Finalization is set-based and staging-first.

dpone plan --format json includes a native_transfer_plan.transport_contract section for this route. Treat it as the operator-facing safety contract for the fast path:

{
  "route": "postgres_to_mssql",
  "wire_format": "mssql-delimited",
  "source_encoding": "postgres_copy_to_stdout",
  "ingest_mode": "bcp",
  "null_policy": "empty_bcp_field_is_null",
  "empty_string_policy": "encoded_marker_roundtrip",
  "text_codec": "BulkTextCodec",
  "compression": "none",
  "lossless": true
}

If lossless is false, fix the warnings before using the native path for production data. The common causes are:

Warning Fix
The plan does not select the internal mssql-delimited wire format Keep the public source.options.export_format: csv, verify MSSQL bcp readiness, and inspect the generated transport plan; do not put the internal label in the batch manifest.
gzip export is enabled Set source.options.compress_export: false; SQL Server bcp cannot load gzip files directly.
sink bulk mode is not bcp Set sink.options.bulk.mode: bcp.

Lossless bulk text contract

Postgres COPY and SQL Server bcp are both extremely fast, but plain delimiter files are not safe enough by themselves. dpone uses a bulk text codec when the internal wire_format: mssql-delimited transport is selected:

Source value File representation Target final value
NULL empty bcp field NULL
empty string framework marker empty string
tab/newline/control char escaped framework marker sequence original text
normal text original text original text

The codec metadata is attached to the file artifact and carried into the MSSQL staging/finalization step. If a raw delimited artifact with text columns does not include codec metadata, the MSSQL sink fails closed unless allow_unsafe_raw_mssql_bulk_files: true is explicitly configured.

This is the important production guarantee: NULL and '' are never silently collapsed into the same value on the default Postgres -> MSSQL fast path.

Canonical tuning knobs:

Knob Path Meaning
Source export workers source.options.partitioning.export_workers Parallel PostgreSQL COPY workers.
Target load workers source.options.partitioning.load_workers Parallel artifact load workers used by the sink.
Partition size source.options.partitioning.target_rows_per_partition Auto-calculated partition count target.
MSSQL bulk mode sink.options.bulk.mode bcp for native SQL Server bulk load.
bcp batch size sink.options.bulk.bcp.batch_size Rows per bcp transaction batch.
bcp packet size sink.options.bulk.bcp.packet_size SQL Server bulk network packet size.
bcp error file sink.options.bulk.bcp.error_file Base error-file path. Partitioned loads automatically derive per-partition files such as bcp_errors_p3_abcdef12.err to avoid parallel writer collisions.

The runtime consumes the same canonical bulk.bcp.* settings that dpone plan shows. Legacy flat aliases are accepted only as migration aliases and are reported as warnings in plan output; keep new manifests on the canonical nested shape and use config aliases migration only when upgrading older automation.

Partition checkpoints and certification evidence

Partitioned Postgres -> MSSQL transfers attach deterministic metadata to every file artifact:

Field Purpose
partition_bounds The exact half-open source range exported into the file.
query_hash Detects whether the source boundary changed between retries.
schema_hash Detects schema drift between retries.
transfer_partition_id Stable SHA-256 partition identity used for resume and evidence.

When native transfer checkpointing is enabled, already committed partitions can be skipped on retry only when the query hash, schema hash, artifact checksum and partition identity still match. State advances only after staging load, finalization and quality gates succeed.

For release evidence, run the MSSQL benchmark/certification harnesses from Performance guide. The recommended local profiles are 10k, 1m and 10m rows with wide sparse data and text edge cases.

When running through GitHub Actions, dispatch .github/workflows/live-certification.yml with run_native_benchmark_suite=true. The workflow writes both machine-readable summary.json and human-readable postgres_mssql_native_benchmark_summary.md artifacts under test_artifacts/live_certification/benchmarks/.

For a route-level go/no-go report, attach this route's artifacts to dpone ops route-certification-pack, which generates readiness-compatible evidence and embeds dpone ops route-readiness. The critical readiness evidence domains for postgres -> mssql are lossless_transport_contract, benchmark_slo, resume_checkpoint, and type_matrix, plus the generic matrix, manifest, strategy, reconciliation, run artifact, and docs runbook domains.

Before a release tag, pass the refresh execution, route_refresh_snapshot_capture, exact route_refresh_verification, readiness, checklist, and evidence-chain artifacts to dpone ops route-certify. The resulting route_certification_bundle.json is the final route promotion artifact for this route.

Strategy behavior

  • full_refresh: extract the selected source boundary, load into staging, and replace the target according to the target's safe finalization path.
  • incremental_append: extract only the incremental boundary and append rows through staging or event production.
  • incremental_merge: load into staging, validate duplicates, then use delete_insert by default; shadow_swap is available where table swaps are supported.
  • replace: reload a bounded predicate window through staging and then atomically replace the matching target slice.
  • snapshot_diff: compare a complete current source snapshot with the target by unique_key, then apply the configured insert, update, and delete policy.
  • partition_replace: extract a complete partition slice, load it into staging, and replace only partitions represented by partition.column.

Snapshot reconciliation is separate from the load strategy. Runtime planning reports that capability as reconciliation.mode=snapshot; in the official dpone.batch.v1 authoring schema, enable it with reconciliation: true.

Copy/paste strategy snippets

Full refresh:

sink:
  strategy:
    mode: full_refresh

Incremental merge with the MSSQL default delete_insert finalizer:

sink:
  strategy:
    mode: incremental_merge
    unique_key: [id]
    merge_policy: delete_insert

Partition replace for complete partition slices:

sink:
  strategy:
    mode: partition_replace
    partition:
      column: business_date
      values_from_staging: true
      max_partitions_per_run: 64

Explicit Postgres XMin source strategy:

source:
  type: postgres
  options:
    incremental_strategy: xmin

CDC apply from a Postgres logical replication source:

sink:
  strategy:
    mode: cdc_apply
    unique_key: [id]

Failure/resume certification

Large native transfers are restartable only at safe boundaries. A partition may be skipped on retry only after a committed checkpoint with matching query hash, schema hash, partition bounds and artifact checksum. Exported-only and loaded-only partitions are retried.

Mandatory failure scenarios for this path:

Scenario Expected behavior
after_export Exported files are not treated as committed; source state does not advance.
during_bcp_load Partial staging loads do not create final duplicates after retry.
before_finalizer Finalizer and reconciliation can rerun; state advances only after commit.

Use the same evidence format as the native transfer resume certification suite: JSON/Markdown artifacts with partition checkpoint status, retry/skip decisions, row counts and quality results.

Type matrix certification

The Postgres -> MSSQL route is covered by the postgres_to_mssql_native_v2 certification suite. It validates runtime type decisions, explicit-contract-required source families, physical target type overrides, nullable policy and schema evolution explain diagnostics.

Certified source families:

PostgreSQL family Default MSSQL contract Certification notes
smallint, integer, bigint smallint, int, bigint Nullable sources remain nullable in target DDL.
numeric(p,s) / decimal(p,s) decimal(p,s) Precision and scale must be preserved.
boolean bit Exported as 0/1 for bcp.
uuid uniqueidentifier Native GUID contract.
bytea varbinary(max) Hex on character mssql-delimited BCP + CONVERT(..., 2) decode (wide live).
date, time, timestamp date, time(6), datetime2(6) Timezone-naive timestamps are not converted.
timestamptz datetimeoffset(6) Offset-aware timestamp contract.
json, jsonb nvarchar(max) JSON text via BulkTextCodec; use contracts for strict shape.
arrays, ranges, enums, domains/custom explicit policy required Marked incompatible_requires_policy; use schema_contract, physical override, quarantine, or documented JSON/text landing.

Generate the current matrix:

dpone schema type-matrix \
  --source postgres \
  --sink mssql \
  --format md

Run local contract certification:

uv run pytest -m type_matrix_certification tests/test_type_matrix_certification.py -q

Run the manual Docker-backed certification profile:

gh workflow run "Live certification" \
  -f profile=type_matrix_certification \
  -f row_count=10000

Expected manual artifacts are listed in Type mapping matrix.

Schema evolution and type mapping

Schema evolution is enabled by default and runs before the staging/final load path:

  1. Read source schema from ExtractResult.schema.
  2. Introspect the MSSQL target schema.
  3. Apply safe additions and widening operations.
  4. Fail breaking changes by default.
  5. If configured, route incompatible type changes to __dpone__nc__<column>.

Use Schema evolution and Type mapping matrix when adding columns or changing source types.

For exact source-to-target type decisions, see the PostgreSQL -> MSSQL detailed defaults section in Type mapping matrix. Important production notes:

  • uuid lands as SQL Server uniqueidentifier.
  • json/jsonb, arrays, ranges and custom types land as nvarchar(max) unless an explicit schema contract overrides them.
  • bytea lands via hex character BCP (not raw binary bytes in the delimited file). Prefer that path over allow_unsafe_raw_mssql_bulk_files.

Self-service golden path

Copy-paste CJM for the checked-in example (wide vendor-live certified route):

dpone doctor --profile local
pip install "dpone[mssql,postgres]"
dpone plan examples/source-sink/postgres-to-mssql.yaml --format md
dpone schema type-matrix --source postgres --sink mssql --format md
dpone run examples/source-sink/postgres-to-mssql.yaml

Landing convention (vault/GitOps-oriented): examples/batch/landing_postgres_to_mssql.batch.yaml.

See Route live wide certification for the maintainer vendor-live IT evidence path (SKIP ≠ PASS).

Runbook

  1. Start with dpone doctor --profile local and fix missing extras or native clients.
  2. Run dpone plan examples/source-sink/postgres-to-mssql.yaml --format md and review source boundary, staging path, schema evolution, state, and quality gates.
  3. Run a small bounded window first.
  4. Inspect the run artifact under .dpone/runs/postgres_to_mssql.
  5. For incremental jobs, verify state before enabling a schedule.
  6. For delete-aware jobs, run reconciliation in report-only mode before enabling physical deletes.
  7. Promote the manifest through GitOps after the plan and artifact are reviewed.

Troubleshooting

bcp error file has rejected rows

Inspect the configured sink.options.bulk.bcp.error_file, then compare the rejected column with Type mapping matrix. Most production failures are either precision/scale mismatches, unsafe binary values, or a raw third-party file that bypassed BulkTextCodec.

NULL and empty string look identical

Use source.options.export_format: mssql-delimited. dpone-generated artifacts encode empty strings with the framework marker and keep NULL as the empty bcp field. Raw TSV files cannot safely distinguish those values.

Target load/finalize is the bottleneck

If postgres_to_mssql.target_load_finalize dominates runtime, tune SQL Server first: bulk.bcp.batch_size, bulk.bcp.table_lock, transaction log throughput, staging indexes, finalizer policy, and post-load statistics.

Schema evolution reports false type changes

Compare canonical logical types, not raw strings. Example: Postgres integer and MSSQL int are expected-compatible. If a custom type lands as text, declare it in schema_contract.columns before enabling production auto-evolution.

Partitioned export skips or overlaps ranges

Prefer explicit partitioning.bounds for release loads. With bounds: auto, review the MIN/MAX/COUNT section in dpone plan and verify the partition column is monotonic and non-null for the selected source boundary.

SQL Server locks during finalizer

For bounded deltas keep merge_policy: delete_insert. If readers are sensitive to delete/insert locks, try merge_policy: shadow_swap, smaller partitions, or safe-window execution.

Type contracts and physical design

This flow supports the shared dpone type-governance stack:

  • Type inference for source metadata, sampled profiling, confidence, and empty string vs NULL behavior.
  • Schema contracts for explicit logical column types, enforcement modes, and __dpone__nc__* variant columns.
  • Physical design for target-specific DDL such as concrete SQL types, indexes, partitioning, compression, ClickHouse LowCardinality, and BigQuery clustering.

Use dpone schema infer --manifest ... and dpone schema physical-plan --manifest ... before enabling new table DDL in production.

CDC/replay reliability contract

For cdc_apply, dpone plan --explain-strategy exposes a replay contract in the native transfer plan. The contract is intentionally target-agnostic and answers four operational questions before a run starts:

  • Which state boundary is durable enough to resume from.
  • Which delete semantics are expected in MSSQL.
  • Whether idempotent replay is possible from the configured unique_key.
  • Which evidence artifacts should exist after the run.

Example:

source:
  type: postgres
  table: {schema: public, name: events}
  options:
    cdc:
      mode: logical_replication
      state_boundary: logical_lsn

sink:
  type: mssql
  table: {schema: dbo, name: events}
  strategy:
    mode: cdc_apply
    unique_key: [event_id]
  options:
    deletes:
      mode: soft_delete

Plan output includes:

native_transfer_replay: postgres_to_mssql lossless=True
native_transfer_state_boundary: logical_lsn
native_transfer_state_commit: after_target_finalize_and_quality
native_transfer_delete_mode: soft_delete
native_transfer_idempotency: unique_key

The state commit boundary is always after_target_finalize_and_quality: dpone must not advance CDC state after only exporting or staging rows. This follows the same production rule used by Airbyte/Fivetran-style connectors: source state moves only after the destination accepted the batch and quality/reconciliation checks passed.

Replay warnings and fixes

Warning Meaning Fix
unique_key is required for idempotent cdc_apply replay The same event could be replayed after retry and create duplicates. Configure sink.strategy.unique_key.
source.options.cdc.state_boundary is required for durable replay The plan cannot prove whether resume uses LSN, XMin, or another cursor. Set source.options.cdc.state_boundary, for example logical_lsn.
sink.options.deletes.mode is not set; defaulting to ignore Delete events will not be represented in the target contract. Set sink.options.deletes.mode to soft_delete or hard_delete where supported.

Expected evidence artifacts:

  • cdc_replay_plan.json
  • state_transition.json
  • typed_reconciliation.json

These artifacts are designed for release gates and incident runbooks: they show the exact replay boundary, state transition and typed reconciliation result for the batch.

Native transfer evidence contract

dpone plan --explain-strategy also emits native_transfer_plan.evidence_contract. This is the release-gate checklist for Postgres -> MSSQL: it tells CI, operators and incident runbooks which evidence files must exist before a run can be considered production-safe.

For partitioned CDC plans the contract includes:

native_transfer_evidence: artifacts=8 checks=4
native_transfer_partition_retry: True

Required artifacts:

  • native_transfer_plan.json
  • transfer_diagnostics.json
  • cdc_replay_plan.json
  • partition_checkpoints.json
  • partition_retry_plan.json
  • typed_reconciliation.json
  • quality_results.json
  • state_transition.json

Required checks:

  • partition_checkpoint_consistency
  • typed_reconciliation
  • quality_gate
  • state_transition_after_commit

For single-partition transfers, partition_retry.enabled is false and the partition checkpoint artifacts are not required. This avoids noisy fake evidence while keeping the same top-level contract shape for all native transfer routes.

Partition retry semantics

Each partition checkpoint is keyed by transfer_partition_id. The idempotent skip rule is:

matching_source_target_strategy_query_schema_and_bounds_hash

A retry can skip a partition only when the source route, target route, strategy, query hash, schema hash and partition bounds match the previously committed checkpoint. This prevents accidental reuse of stale artifacts after a schema, query or partition-boundary change.

Evidence artifact writer contract

Runtime code should materialize the evidence contract through NativeTransferEvidenceArtifactWriter. The writer is deliberately strict:

  • it writes only payloads provided by runtime or certification code;
  • it fails when any required_artifacts payload is missing;
  • it writes evidence_index.json and evidence_index.md with SHA-256 checksums;
  • it does not fabricate successful typed_reconciliation or quality_results payloads.

Example Python usage for certification helpers:

from dpone.strategy_intelligence.native_transfer_evidence_artifacts import (
    NativeTransferEvidenceArtifactWriter,
)

writer = NativeTransferEvidenceArtifactWriter("test_artifacts/native-transfer/postgres-mssql")
writer.write(
    run_id=run_id,
    evidence_contract=plan.evidence_contract,
    payloads={
        "native_transfer_plan.json": plan.to_dict(),
        "transfer_diagnostics.json": diagnostics,
        "cdc_replay_plan.json": replay_plan,
        "partition_checkpoints.json": checkpoint_payload,
        "partition_retry_plan.json": retry_payload,
        "typed_reconciliation.json": reconciliation_payload,
        "quality_results.json": quality_payload,
        "state_transition.json": state_transition_payload,
    },
)

If typed_reconciliation.json or another required artifact is absent, the writer raises before producing an incomplete evidence index.

Build the evidence bundle from CLI

After a run or certification job has produced the required payload JSON files, use the strategy command to build a checksumed evidence bundle:

dpone strategy native-transfer-evidence \
  --run-id 01J00000000000000000000000 \
  --plan-json test_artifacts/native-transfer/postgres-mssql/plan.json \
  --payload native_transfer_plan.json=test_artifacts/native-transfer/postgres-mssql/native_transfer_plan.json \
  --payload transfer_diagnostics.json=test_artifacts/native-transfer/postgres-mssql/transfer_diagnostics.json \
  --payload cdc_replay_plan.json=test_artifacts/native-transfer/postgres-mssql/cdc_replay_plan.json \
  --payload partition_checkpoints.json=test_artifacts/native-transfer/postgres-mssql/partition_checkpoints.json \
  --payload partition_retry_plan.json=test_artifacts/native-transfer/postgres-mssql/partition_retry_plan.json \
  --payload typed_reconciliation.json=test_artifacts/native-transfer/postgres-mssql/typed_reconciliation.json \
  --payload quality_results.json=test_artifacts/native-transfer/postgres-mssql/quality_results.json \
  --payload state_transition.json=test_artifacts/native-transfer/postgres-mssql/state_transition.json \
  --output-dir test_artifacts/native-transfer/postgres-mssql/evidence \
  --format json

The command accepts either --plan-json or --contract-json. --plan-json can be the full dpone plan --explain-strategy --format json payload or a smaller object containing native_transfer_plan.evidence_contract.

The command fails if any payload from required_artifacts is missing. This is intentional: incomplete evidence must not pass certification quietly.

Add evidence to the strategy certification bundle

After building evidence_index.json, include it in the strategy certification bundle:

dpone strategy certification-bundle \
  --bundle-id postgres_mssql_native_rc \
  --native-transfer-evidence test_artifacts/native-transfer/postgres-mssql/evidence/01J00000000000000000000000/evidence_index.json \
  --matrix-artifact test_artifacts/integration_matrix/certification_report.json \
  --docs-link docs/source-sink/postgres-to-mssql.md \
  --output-dir test_artifacts/strategy_certification/postgres_mssql \
  --format json

Use the resulting strategy_certification_bundle.json as an input to dpone ops release-evidence-pack or the manual live certification workflow.

Release gate for Postgres -> MSSQL native transfer

For releases that claim production-grade Postgres -> MSSQL native transfer, run the final release gate with the native transfer profile:

dpone ops release-evidence-pack \
  --release vX.Y.Z \
  --profile native_transfer \
  --artifact strategy_certification_bundle=test_artifacts/strategy_certification/postgres_mssql/strategy_certification_bundle.json

The profile requires strategy_certification_bundle, which should include the native transfer evidence_index.json generated for this route.

Postgres -> MSSQL refresh executor live certification

The route refresh executor has an opt-in Docker-live certification gate for the bounded native refresh path:

DPONE_RUN_INTEGRATION=1 \
DPONE_RUN_REFRESH_EXECUTOR_LIVE=1 \
uv run pytest tests/integration/mssql/test_postgres_mssql_refresh_executor_live_integration.py -q

The test builds a postgres -> mssql -> incremental_merge plan, runs route-refresh-execute through the postgres_mssql backend contract, and then replays the same plan. After replay it runs route-refresh-capture-snapshots through RouteRefreshSnapshotCaptureService and route-refresh-verify through RouteRefreshVerificationService to produce route_refresh_snapshot_capture.json, source_route_refresh_snapshot.json, sink_route_refresh_snapshot.json, and route_refresh_verification.json. The replay must leave exactly one copy of every source row in MSSQL. The gate uses 10,000 rows and 200 columns, covers physical-contract conversions, checks deterministic typed hash equality, per-chunk transfer checksums, Postgres COPY export evidence, MSSQL bounded prepare evidence, MSSQL bcp load evidence, and source/sink verification snapshots, then repeats execution, capture, and exact verification after additive schema evolution.

Release evidence is written under:

test_artifacts/live_certification/refresh-executor/postgres-mssql/

Important files:

File Meaning
plan/route_refresh_plan.json Matrix-backed bounded refresh plan.
executor-config.json Native Postgres COPY and MSSQL bcp config.
execute-first/route_refresh_execution.json First execution receipt.
execute-replay/route_refresh_execution.json Idempotency replay receipt.
capture/route_refresh_snapshot_capture.json Read-only snapshot capture receipt for replayed chunks.
capture/source_route_refresh_snapshot.json Postgres-side per-chunk typed hash snapshot artifact.
capture/sink_route_refresh_snapshot.json MSSQL-side per-chunk typed hash snapshot artifact.
verify/route_refresh_verification.json Post-load source/sink row-count, boundary, duplicate/null key, and typed hash verification receipt.
execute-replay/chunks/*.json Chunk-level route id, query hash, prepare command, export/load evidence, transfer checksum, row counts, and blockers.

Attach the replay route_refresh_execution.json, route_refresh_snapshot_capture.json, source_route_refresh_snapshot.json, sink_route_refresh_snapshot.json, and route_refresh_verification.json to route live certification and route release gates whenever a release claims production support for the bounded postgres_mssql refresh executor.