pg-logical-repl 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. pg_logical_repl-0.2.0/.github/workflows/publish.yml +126 -0
  2. pg_logical_repl-0.2.0/IMPLEMENTATION_STATUS.md +207 -0
  3. pg_logical_repl-0.2.0/MANIFEST.in +15 -0
  4. pg_logical_repl-0.2.0/PKG-INFO +425 -0
  5. pg_logical_repl-0.2.0/README.md +406 -0
  6. pg_logical_repl-0.2.0/docs/DDL_IMPLEMENTATION.md +170 -0
  7. pg_logical_repl-0.2.0/docs/RELEASING.md +92 -0
  8. pg_logical_repl-0.2.0/docs/TESTING.md +142 -0
  9. pg_logical_repl-0.2.0/examples/local.yaml +55 -0
  10. pg_logical_repl-0.2.0/infra/benchmark_validation.py +143 -0
  11. pg_logical_repl-0.2.0/infra/build_pg16.py +24 -0
  12. pg_logical_repl-0.2.0/infra/checkpoint_local.py +35 -0
  13. pg_logical_repl-0.2.0/infra/pg15.yaml +75 -0
  14. pg_logical_repl-0.2.0/infra/pg16.yaml +76 -0
  15. pg_logical_repl-0.2.0/infra/pg17.yaml +75 -0
  16. pg_logical_repl-0.2.0/infra/pg18.yaml +75 -0
  17. pg_logical_repl-0.2.0/infra/quality.py +233 -0
  18. pg_logical_repl-0.2.0/infra/reconfigure_local_wal.py +63 -0
  19. pg_logical_repl-0.2.0/infra/release_report.py +162 -0
  20. pg_logical_repl-0.2.0/infra/test_matrix.py +190 -0
  21. pg_logical_repl-0.2.0/pyproject.toml +62 -0
  22. pg_logical_repl-0.2.0/setup.cfg +4 -0
  23. pg_logical_repl-0.2.0/src/pg_logical_repl/__init__.py +3 -0
  24. pg_logical_repl-0.2.0/src/pg_logical_repl/__main__.py +6 -0
  25. pg_logical_repl-0.2.0/src/pg_logical_repl/capabilities.py +136 -0
  26. pg_logical_repl-0.2.0/src/pg_logical_repl/catalog.py +320 -0
  27. pg_logical_repl-0.2.0/src/pg_logical_repl/cli.py +277 -0
  28. pg_logical_repl-0.2.0/src/pg_logical_repl/component.py +66 -0
  29. pg_logical_repl-0.2.0/src/pg_logical_repl/config.py +356 -0
  30. pg_logical_repl-0.2.0/src/pg_logical_repl/coverage.py +117 -0
  31. pg_logical_repl-0.2.0/src/pg_logical_repl/cutover.py +239 -0
  32. pg_logical_repl-0.2.0/src/pg_logical_repl/db.py +131 -0
  33. pg_logical_repl-0.2.0/src/pg_logical_repl/ddl.py +352 -0
  34. pg_logical_repl-0.2.0/src/pg_logical_repl/ddl_queue.py +461 -0
  35. pg_logical_repl-0.2.0/src/pg_logical_repl/emergency.py +296 -0
  36. pg_logical_repl-0.2.0/src/pg_logical_repl/errors.py +44 -0
  37. pg_logical_repl-0.2.0/src/pg_logical_repl/health.py +194 -0
  38. pg_logical_repl-0.2.0/src/pg_logical_repl/integrity.py +185 -0
  39. pg_logical_repl-0.2.0/src/pg_logical_repl/logging_config.py +45 -0
  40. pg_logical_repl-0.2.0/src/pg_logical_repl/monitoring.py +277 -0
  41. pg_logical_repl-0.2.0/src/pg_logical_repl/plans.py +167 -0
  42. pg_logical_repl-0.2.0/src/pg_logical_repl/preflight.py +290 -0
  43. pg_logical_repl-0.2.0/src/pg_logical_repl/process.py +150 -0
  44. pg_logical_repl-0.2.0/src/pg_logical_repl/recovery.py +188 -0
  45. pg_logical_repl-0.2.0/src/pg_logical_repl/resync.py +267 -0
  46. pg_logical_repl-0.2.0/src/pg_logical_repl/roles.py +123 -0
  47. pg_logical_repl-0.2.0/src/pg_logical_repl/schema.py +89 -0
  48. pg_logical_repl-0.2.0/src/pg_logical_repl/security.py +117 -0
  49. pg_logical_repl-0.2.0/src/pg_logical_repl/service.py +773 -0
  50. pg_logical_repl-0.2.0/src/pg_logical_repl/sql/base.sql +67 -0
  51. pg_logical_repl-0.2.0/src/pg_logical_repl/sql/capture.sql +215 -0
  52. pg_logical_repl-0.2.0/src/pg_logical_repl/sql/ddl_support.sql +109 -0
  53. pg_logical_repl-0.2.0/src/pg_logical_repl/sql/freeze.sql +117 -0
  54. pg_logical_repl-0.2.0/src/pg_logical_repl/sql/replay.sql +48 -0
  55. pg_logical_repl-0.2.0/src/pg_logical_repl/state.py +160 -0
  56. pg_logical_repl-0.2.0/src/pg_logical_repl/validation.py +353 -0
  57. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/PKG-INFO +425 -0
  58. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/SOURCES.txt +86 -0
  59. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/dependency_links.txt +1 -0
  60. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/entry_points.txt +2 -0
  61. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/requires.txt +11 -0
  62. pg_logical_repl-0.2.0/src/pg_logical_repl.egg-info/top_level.txt +1 -0
  63. pg_logical_repl-0.2.0/tests/check_distribution.py +107 -0
  64. pg_logical_repl-0.2.0/tests/fixtures/quality/recovery.json +13 -0
  65. pg_logical_repl-0.2.0/tests/integration/conftest.py +23 -0
  66. pg_logical_repl-0.2.0/tests/integration/spike_native_ddl.py +159 -0
  67. pg_logical_repl-0.2.0/tests/integration/test_ddl_expanded.py +463 -0
  68. pg_logical_repl-0.2.0/tests/integration/test_lifecycle.py +949 -0
  69. pg_logical_repl-0.2.0/tests/integration/test_p0_edges.py +268 -0
  70. pg_logical_repl-0.2.0/tests/integration/test_p0_recovery.py +323 -0
  71. pg_logical_repl-0.2.0/tests/integration/test_pg_play.py +497 -0
  72. pg_logical_repl-0.2.0/tests/integration/test_quality_cli.py +48 -0
  73. pg_logical_repl-0.2.0/tests/integration/test_quality_ddl_validation.py +118 -0
  74. pg_logical_repl-0.2.0/tests/integration/test_quality_generated.py +246 -0
  75. pg_logical_repl-0.2.0/tests/integration/test_quality_network.py +144 -0
  76. pg_logical_repl-0.2.0/tests/integration/test_quality_oracle.py +90 -0
  77. pg_logical_repl-0.2.0/tests/integration/test_quality_process.py +123 -0
  78. pg_logical_repl-0.2.0/tests/support/__init__.py +1 -0
  79. pg_logical_repl-0.2.0/tests/support/child.py +116 -0
  80. pg_logical_repl-0.2.0/tests/support/cli.py +113 -0
  81. pg_logical_repl-0.2.0/tests/support/network.py +36 -0
  82. pg_logical_repl-0.2.0/tests/support/oracle.py +229 -0
  83. pg_logical_repl-0.2.0/tests/support/wire.py +104 -0
  84. pg_logical_repl-0.2.0/tests/support/workload.py +248 -0
  85. pg_logical_repl-0.2.0/tests/test_component.py +118 -0
  86. pg_logical_repl-0.2.0/tests/test_foundations.py +155 -0
  87. pg_logical_repl-0.2.0/tests/test_p0.py +68 -0
  88. pg_logical_repl-0.2.0/tests/test_quality_stateio.py +77 -0
@@ -0,0 +1,126 @@
1
+ name: Test and publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: ["**"]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ tests:
15
+ name: Unit tests on Python ${{ matrix.python-version }}
16
+ runs-on: ubuntu-24.04
17
+ timeout-minutes: 15
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.11", "3.12"]
22
+ steps:
23
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
24
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ - name: Install test dependencies
28
+ run: python -m pip install -e '.[test]'
29
+ - name: Check code style
30
+ run: |
31
+ ruff check .
32
+ ruff format --check .
33
+ - name: Run tests without PostgreSQL endpoints
34
+ run: python -m pytest -q --ignore=tests/integration
35
+
36
+ build:
37
+ name: Build and verify distributions
38
+ needs: tests
39
+ runs-on: ubuntu-24.04
40
+ timeout-minutes: 15
41
+ steps:
42
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
43
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
44
+ with:
45
+ python-version: "3.11"
46
+ - name: Install build tools
47
+ run: python -m pip install 'build>=1.2,<2' 'twine>=6,<7'
48
+ - name: Verify package and tag versions
49
+ run: |
50
+ python - <<'PY'
51
+ import ast
52
+ import os
53
+ import pathlib
54
+ import tomllib
55
+
56
+ version = tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"]
57
+ module = ast.parse(pathlib.Path("src/pg_logical_repl/__init__.py").read_text())
58
+ runtime = next(
59
+ ast.literal_eval(node.value)
60
+ for node in module.body
61
+ if isinstance(node, ast.Assign)
62
+ and any(isinstance(target, ast.Name) and target.id == "__version__" for target in node.targets)
63
+ )
64
+ if runtime != version:
65
+ raise SystemExit(f"Runtime version {runtime} differs from package version {version}")
66
+ if os.environ.get("GITHUB_REF_TYPE") == "tag" and os.environ["GITHUB_REF_NAME"] != f"v{version}":
67
+ raise SystemExit(f"Release tag must be v{version}")
68
+ PY
69
+ - name: Build sdist and wheel from sdist
70
+ run: python -m build
71
+ - name: Validate metadata and packaged documentation
72
+ run: |
73
+ python -m twine check dist/*
74
+ python tests/check_distribution.py dist/*.whl dist/*.tar.gz
75
+ - name: Smoke-test installed wheel outside the checkout
76
+ run: |
77
+ python -m venv "${RUNNER_TEMP}/pg-logical-repl-wheel"
78
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/python" -m pip install dist/*.whl
79
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/python" -m pip check
80
+ cd "${RUNNER_TEMP}"
81
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/pg-logical-repl" --version
82
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/pg-logical-repl" --machine --capabilities
83
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/pg-logical-repl" --machine --component-capabilities
84
+ "${RUNNER_TEMP}/pg-logical-repl-wheel/bin/python" - <<'PY'
85
+ import pathlib
86
+ import sysconfig
87
+ from importlib.resources import files
88
+
89
+ docs = pathlib.Path(sysconfig.get_path("data")) / "share/doc/pg-logical-repl"
90
+ for name in (
91
+ "README.md", "IMPLEMENTATION_STATUS.md", "docs/DDL_IMPLEMENTATION.md",
92
+ "docs/TESTING.md", "docs/RELEASING.md", "examples/local.yaml",
93
+ ):
94
+ if not (docs / name).is_file():
95
+ raise SystemExit(f"Missing installed documentation: {name}")
96
+ if not files("pg_logical_repl").joinpath("sql/capture.sql").is_file():
97
+ raise SystemExit("Missing installed SQL resources")
98
+ print(f"Installed documentation: {docs}")
99
+ PY
100
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
101
+ with:
102
+ name: python-distributions
103
+ path: dist/
104
+ if-no-files-found: error
105
+ retention-days: 7
106
+
107
+ publish:
108
+ name: Publish to PyPI with OIDC
109
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository == 'O2eg/pg_logical_repl'
110
+ needs: build
111
+ runs-on: ubuntu-24.04
112
+ timeout-minutes: 15
113
+ concurrency:
114
+ group: pypi-publish
115
+ cancel-in-progress: false
116
+ environment:
117
+ name: pypi
118
+ url: https://pypi.org/p/pg-logical-repl
119
+ permissions:
120
+ id-token: write
121
+ steps:
122
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
123
+ with:
124
+ name: python-distributions
125
+ path: dist/
126
+ - uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
@@ -0,0 +1,207 @@
1
+ # Implementation status — 2026-11-11
2
+
3
+ The current `pg-logical-repl` package version is `0.2.0`.
4
+
5
+ The pip package and CLI were renamed on 2026-11-10; Python imports use
6
+ `pg_logical_repl`. Configuration, state, and JSON contract formats retain
7
+ `pg_logical_connector/*` identifiers for format compatibility.
8
+
9
+ **The production readiness criteria for version 1.0 have not yet been met.**
10
+
11
+ Tests run in local pg-stand environments. Cloud and managed PostgreSQL services
12
+ require separate qualification.
13
+
14
+ ## 0.2.0: pg_play integration and distribution
15
+
16
+ Version 0.2.0 adds an optional pg_play component transport, capability discovery
17
+ and credential-free configuration inspection. Native machine output, config/state
18
+ formats and database ownership rules remain compatible. Laboratory image names
19
+ and SQL diagnostic prefixes now use `pg-logical-repl`.
20
+
21
+ Wheels and source distributions include the public Markdown guides and example
22
+ configuration. The release workflow checks both archives, verifies installation
23
+ outside the checkout, and publishes versioned tags through the PyPI Trusted
24
+ Publisher. See [RELEASING.md](docs/RELEASING.md).
25
+
26
+ Cross-project tests are in `tests/integration/test_pg_play.py`. They require the
27
+ optional pg_play installation and an explicitly owned PostgreSQL stand. Test
28
+ artifacts remain under `.runtime/`; they are excluded from the source repository.
29
+
30
+ Native completion events include the operation's exact plan hash and resulting
31
+ state, allowing pg_play to reconcile a lost response without replaying a completed
32
+ stage. CLI logging releases only its own handlers and restores previous logger
33
+ settings, including when used repeatedly by an embedding application or tests.
34
+
35
+ ## 0.1.0a4: concurrent DDL and background validation
36
+
37
+ Background validation discards a chunk if captured DDL changes the schema between
38
+ reading the catalog and computing the aggregate. The cursor now includes the DDL
39
+ journal version, so a sequence of changes that restores the original schema also
40
+ invalidates the old result. Corruption confined to the target still moves the
41
+ migration to BLOCKED. Deterministic regressions cover column rename/drop, table
42
+ drop, changes at both aggregate computation boundaries, and restoration of the
43
+ original schema.
44
+
45
+ ## Extended testing
46
+
47
+ Added an independent exact oracle, actual CLI process interruptions at operation
48
+ boundaries, a TCP fault proxy on three paths, sustained CLI migration with DML/DDL,
49
+ and a Hypothesis state machine with replay of saved operations. The runner builds
50
+ and installs a clean wheel. Profiles, verified properties, and limitations are
51
+ documented in [TESTING.md](docs/TESTING.md). New run results are stored separately
52
+ in `.runtime/quality-runs/`, excluded through `.gitignore`.
53
+
54
+ ## P0 in 0.1.0a3
55
+
56
+ - Accepted settings have implemented behavior or a fixed supported profile.
57
+ `validate` rejects unsupported policies and parameters. Online validation,
58
+ drift and sequence intervals, textfile metrics, lag/queue/refresh alerts,
59
+ catchup stability, and ANALYZE at cutover are connected to runtime behavior.
60
+ - Continuous scans of primary key ranges persist the cursor, aggregate, and
61
+ awaited LSN. Confirmed mismatches block migration; source changes are
62
+ distinguished from mismatches. Waiting for apply does not stall the entire
63
+ daemon iteration.
64
+ - Checks cover supported schema/ACLs, the initial role state, verifiers and
65
+ membership, SQL resource identities and definitions, and DDL journal integrity.
66
+ The baseline is created during prepare; role changes on both sides are detected.
67
+ Verifiers are excluded from public reports. Pruning the acknowledged journal
68
+ preserves compact managed DDL receipts and resumes after a failure.
69
+ - Planned pause/resume/resolve operations include a WAL budget and pause deadline,
70
+ checks before leaving BLOCKED, whole-transaction skip by finish LSN, and
71
+ applied-manually resolution. Skipping without restoring the complete transaction
72
+ result leaves the migration BLOCKED.
73
+ - Resync of ordinary logged tables uses native tablesync and preserves incoming
74
+ foreign keys, validation flags, and comments. The original plan resumes an
75
+ interrupted step. Abort preserves partial data and restores removed foreign
76
+ keys as NOT VALID, explicitly listing them in state. This repair does not
77
+ support partitions or extension tables.
78
+ - Emergency abort and post-finalize commit with an unavailable source support
79
+ target-only detachment, ABORT_CLEANUP_PENDING/DETACH_CLEANUP_PENDING states, and
80
+ separate cleanup with ownership checks. The target is checked for changes and
81
+ finalize evidence for freshness. Unknown additional slots are not deleted
82
+ automatically.
83
+ - Partial status remains available when an endpoint is unavailable or the internal
84
+ schema is damaged. Schema/permission errors during a daemon iteration persist
85
+ a diagnosable BLOCKED state.
86
+
87
+ Commands, parameters, recovery, and limitations are documented in [README.md](README.md).
88
+ This version requires a new migration to record an integrity baseline. Automatic
89
+ adoption of old state, recovery from lost local state, takeover, and arbitrary
90
+ repair of damaged server resources are not implemented.
91
+
92
+ ## 0.1.0a4 validation
93
+
94
+ The local PostgreSQL 15–18 matrix completed **417 successful test executions**, with
95
+ no failures, errors, or skipped tests. Each version passed 93 integration scenarios;
96
+ PG18 also passed 45 unit tests.
97
+
98
+ A separate 30-minute CLI run used 10,000 initial rows and four writers, executing
99
+ 128,759 transactions and 892 DDL commands. It verified controller SIGKILL/SIGTERM,
100
+ a replication connection interruption, exact data and metadata comparisons,
101
+ finalize/commit, and independent writes on the target.
102
+
103
+ Ruff, formatting, wheel installation in a separate environment, both CLI entry
104
+ points, and SQL resources were checked. Instructions and the scope of these
105
+ results are documented in [TESTING.md](docs/TESTING.md). Machine reports, dumps,
106
+ credentials, and logs from individual runs remain local and are not included in
107
+ the repository.
108
+
109
+ ## Implemented and verified in the test environment
110
+
111
+ - CLI and asynchronous service API; JSON `pg_logical_connector/result-v2`,
112
+ capabilities, request ID, JSON events to stderr/file, private files, and redaction.
113
+ - Validation of configuration, identities, major versions, locale/collation,
114
+ target emptiness, roles/verifiers, extensions, replica identity, and slot/disk
115
+ capacity.
116
+ - Conservative preflight rejection of unsupported FDW, RLS, rules, extended
117
+ statistics, custom collations/types/operators/casts/aggregates, text search,
118
+ tablespaces, and security labels; a partial coverage manifest excludes external
119
+ mapping secrets. Fingerprints include partition bounds/parents, column
120
+ storage/collation, and sequence definitions. Unknown classes require further
121
+ qualification.
122
+ - Basic health controller: identities, publication options/membership, subscription,
123
+ slot, and WAL retention; BLOCKED on drift and repeated apply/sync errors within
124
+ a 300-second window. These checks also run before finalize/commit. Conflicting
125
+ data is not skipped automatically, and slots are not automatically deleted.
126
+ - RFC 8785/SHA-256 plans bound to configuration and catalogs; HMAC for verifiers.
127
+ - Server validation using count + MD5 sum, chunks based on single/composite primary
128
+ keys, waiting for confirmed_flush_lsn, retries of changing chunks, concurrency
129
+ and pause limits, identical GUC settings, and table/level selection. Python
130
+ receives only aggregates and key boundaries. Large objects are checked using
131
+ server page aggregates. Tables without primary keys require a full scan with a
132
+ warning; cold chunk caching is not yet implemented.
133
+ - Transfer of roles, passwords, membership/options, settings, owners, ACLs, and the
134
+ database comment. Existing roles that differ are not overwritten.
135
+ - Schema-only pg_dump/pg_restore with matching major versions, pre-data/indexes
136
+ before loading, post-data after tablesync, and transactional step completion
137
+ receipts.
138
+ - Native publication/slot/subscription, tablesync and DML, initial partitions,
139
+ TOAST, RI FULL for tested types; a target → source connection probe without
140
+ creating a slot.
141
+ - Extended DDL in captured/managed_only modes: new tables/partitions/CTAS, columns,
142
+ types, DEFAULT, constraints, views/functions/procedures/triggers, sequences,
143
+ enum/domain, owners, ACLs/default privileges, and comments. See the
144
+ [matrix and limitations](docs/DDL_IMPLEMENTATION.md). Replica identity checks,
145
+ rewrite/SET NOT NULL limits, and safe session context requirements remain enforced.
146
+ - New tables: publication changes in the source transaction, REFRESH with
147
+ copy_data=true, native tablesync, and READY tracking; source data written before
148
+ refresh is preserved.
149
+ - Durable sequential DDL queue: CONCURRENTLY, NOT VALID → VALIDATE, UNIQUE/PK via
150
+ indexes, partitioned index trees, intents/OIDs, retries, and skip with a plan
151
+ hash and evidence. An unfinished queue blocks cutover; skips are recorded as
152
+ interventions and do not disable schema validation.
153
+ - Recovery of source CONCURRENTLY operations from the catalog and saved intent
154
+ after loss of the final journal record or response. Further source DDL must wait
155
+ for the queue to finish (receiving an explicit rejection/retry); DML continues.
156
+ - Finalize: external fence, SHARE locks, barrier, exact last_value/is_called,
157
+ unlogged tables, large objects with OID/owner/ACL, materialized views in dependency
158
+ order, and data validation.
159
+ - Commit rechecks the fence and changes since finalize, leaving an independent
160
+ target. Cutover abort returns to replication before the irreversible boundary.
161
+ - Abort preserves application data and transferred roles while removing owned
162
+ resources.
163
+ - Retrying prepare after a lost restore response, start after a lost CREATE
164
+ SUBSCRIPTION response, and ddl exec after a lost acknowledgment.
165
+
166
+ ## Remaining readiness gaps
167
+
168
+ 1. The rest of the full DDL matrix: synthesis of supported DO/compound statements,
169
+ exhaustive sql_drop metadata, qualification of volatility/casts, temporary and
170
+ unlogged objects, and all SPEC variants. See DDL_IMPLEMENTATION.md for exact
171
+ limitations.
172
+ 2. Full object and dependency coverage: FDW/user mappings, extension configuration
173
+ data, application event triggers, ALWAYS/REPLICA triggers, security labels,
174
+ nonstandard types/casts/aggregates/tablespaces, and exhaustive comparison.
175
+ Preflight blocks these known unsupported categories; a comprehensive object
176
+ manifest and qualification of all properties remain incomplete. Full support
177
+ for arbitrary databases is not claimed.
178
+ 3. Cold chunk caching, incremental cutover, lag history, lease/takeover, extended
179
+ observability, and operational qualification of the daemon.
180
+ 4. Resync of partition trees; reconciliation of arbitrary partial states, unknown
181
+ tablesync slots, lost state, and disk exhaustion.
182
+ 5. Qualification of TLS/mTLS, RLS, complex grantor graphs, large transactions,
183
+ parallel apply, failover, and SQL resource upgrades.
184
+ 6. Not all SPEC options are implemented, including waivers and reconciliation of
185
+ existing roles. Configuration validation rejects unsupported values; a full
186
+ acceptance matrix covering every setting remains outstanding.
187
+ 7. Qualification at production scale and with extended overnight profiles has not
188
+ been completed. The local 30-minute run checks correctness on small datasets
189
+ and does not replace testing with the intended production workload.
190
+
191
+ Next priorities: complete the object manifest, incremental validation, and remaining
192
+ DDL variants. Passing the current matrix does not mean the requirements above
193
+ have been met.
194
+
195
+ ## Environment and artifacts
196
+
197
+ - The `infra/pg15.yaml` … `infra/pg18.yaml` environments run sequentially; PG18
198
+ remains active after the matrix.
199
+ - Credentials are stored in `.pg_stand/`, results in `.runtime/`, and builds in
200
+ `dist/`. These directories are excluded through `.gitignore`.
201
+ - Tests normalize bootstrap role verifiers only in their own environment; the
202
+ utility does not change verifiers of existing roles on arbitrary targets.
203
+ - Matching major versions of `pg_dump`/`pg_restore` are required. PG16 has a helper
204
+ image build script, `infra/build_pg16.py`.
205
+ - Tested environment: Python 3.12, Linux ARM64. A separate Python 3.11 run has not
206
+ yet been completed.
207
+ - Guide: [README.md](README.md); example: [examples/local.yaml](examples/local.yaml).
@@ -0,0 +1,15 @@
1
+ include pyproject.toml MANIFEST.in
2
+ include README.md IMPLEMENTATION_STATUS.md
3
+ include docs/DDL_IMPLEMENTATION.md docs/TESTING.md docs/RELEASING.md
4
+ include examples/local.yaml
5
+ include .github/workflows/publish.yml
6
+ recursive-include tests *.py
7
+ include tests/fixtures/quality/recovery.json
8
+ recursive-include infra *.py *.yaml
9
+ exclude todo.md docs/SPEC.md docs/SPEC_REVIEW.md docs/OPEN_SOURCE_REVIEW.md
10
+ prune .runtime
11
+ prune .pg_stand
12
+ prune .venv
13
+ prune build
14
+ prune dist
15
+ global-exclude __pycache__ *.py[cod] *.log *.pid *.pgpass *.key *.pem