Skip to content

Land reviewed stack on main: CI foundations, Phase 1 front door, Phase 2.1-2.4 (#4-#7) - #16

Merged
Kiran01bm merged 28 commits into
mainfrom
kiran01bm/phase-2-1-2-2-diff
Aug 7, 2026
Merged

Land reviewed stack on main: CI foundations, Phase 1 front door, Phase 2.1-2.4 (#4-#7)#16
Kiran01bm merged 28 commits into
mainfrom
kiran01bm/phase-2-1-2-2-diff

Conversation

@Kiran01bm

Copy link
Copy Markdown
Collaborator

Summary

Lands the already-reviewed and already-merged stack of PRs #4#5#6#7 onto main. The stack merged top-down (each PR into its parent branch) after the parent had itself merged, so the work cascaded into stale stack branches and never propagated — main currently holds only #3.

What

The full content of, in stack order:

No new code: kiran01bm/phase-2-1-2-2-diff is the branch that received #7's merge and contains every commit of the stack (verified: classifier-router is an ancestor; the only commits the lower branches carry that this one doesn't are the GitHub merge commits themselves, plus two commits already on main via #3). The merge into main is conflict-free.

Why

Every change here was individually reviewed and approved on its own PR; this PR exists solely to move that content to main. Review it as a formality or spot-check the diff against the individual PRs.

Before / after

before                                  after
main ── #3                              main ── #3 ── #4 ── #5 ── #6 ── #7
         \                                       (this PR)
          #4 ─ #5 ─ #6 ─ #7  (stranded
          on stack branches)

References

#4, #5, #6, #7

Kiran01bm and others added 28 commits August 4, 2026 16:14
Compose-based local database mirrors the CI matrix (PG_DSN path in the
harness); docs-only PRs skip the heavy jobs behind a fail-open filter
with a single ci-ok required status; pre-commit/pre-push hooks give
fast local feedback and skip cleanly on Markdown-only changes. A
TLS-only server harness proves the verify-full CACertPath path live
(trusted CA encrypts, plaintext and untrusted CA fail closed) — the
one peer-CI pattern (pg-delta) applicable to Phase 0. docs/testing.md
records Phase 0 coverage, Phases 1-7 test obligations including the
topology patterns surveyed from peer-tool CIs, and the vanilla
PostgreSQL vs real-Aurora validation boundary. The lint config adopts
SchemaBot's proven linter set plus gofmt/goimports formatters, with a
staged-files lint-fix pre-commit flow ported from the same repo.
Compose-based local database mirrors the CI matrix (PG_DSN path in the
harness); docs-only PRs skip the heavy jobs behind a fail-open filter
with a single ci-ok required status; pre-commit/pre-push hooks give
fast local feedback and skip cleanly on Markdown-only changes. A
TLS-only server harness proves the verify-full CACertPath path live
(trusted CA encrypts, plaintext and untrusted CA fail closed) — the
one peer-CI pattern (pg-delta) applicable to Phase 0. docs/testing.md
records Phase 0 coverage, Phases 1-7 test obligations including the
topology patterns surveyed from peer-tool CIs, and the vanilla
PostgreSQL vs real-Aurora validation boundary. The lint config adopts
SchemaBot's proven linter set plus gofmt/goimports formatters, with a
staged-files lint-fix pre-commit flow ported from the same repo.
AGENTS.md stays canonical for agent guidance: CLAUDE.md, GEMINI.md,
.cursorrules, .goosehints, and copilot-instructions.md are symlinks to
it, and review-agent checks live in .agents/checks/review.md.
Make the testing bar explicit and binding: same-PR tests, regression-first
bug fixes, real-DB core validation, full-matrix CI as a merge gate, and a
coverage ratchet (numeric gate wired when Phase 1 lands core code).

Add eight phase-tagged test-methodology invariants (TM-1..TM-8) mined from
the pgroll / pg_repack / pg-delta suites: lifecycle fixtures, two-oracle
SQL tests, real fault injection asserting durable state, an adversarial
schema corpus, the convergence oracle for declarative diff,
mutation-direction coverage, correctness-asserting benchmarks, and a
compiled-binary e2e CI path — plus seeded generative DDL as the
beyond-peers goal.
…S.md

Doc comments on exported symbols, no init(), no package-level mutable
state, and no ctx-in-struct move to .golangci.yml (revive,
gochecknoinits, gochecknoglobals, containedctx) so prose stays short.
New maxims (panic policy, SQLSTATE error matching, goroutine lifetimes,
injected clock, comment hygiene, OSS hygiene) ported from schemabot's
AGENTS.md and Go community style canon, mirrored into the review checks.
…ute-and-introspect)

The DDL-understanding trade-off is decided: classification parses via
wasilibs/go-pgquery (Wasm libpg_query; cgo pg_query_go is the
API-compatible escape hatch), shadow-table DDL and checkpoint
fingerprints come from execute-and-introspect on an engine-owned
scratch database (pg_sprite_scratch pre-provisioned, or CREATEDB to
self-provision — verified in preflight), and refusals use both layers.
Updates CO-7/ST-2/ST-6, the TCB dependency list, and the low-level
design; supersedes the pg_query_go + AST-surgery assumption.
migrate gates statements through go-pgquery (ALTER TABLE only; index
maintenance is pointed at CONCURRENTLY), size-guards the table via
pg_table_size over the partition tree, attempts the change under SET
LOCAL lock/statement budgets, and ends in a structured verdict —
executed-natively, or refused with a typed reason and exit code 2.
The verdict seam is what Phase 11 maps to ExecutionModeBlocked.
Closes the two behavioral coverage gaps from the Phase 1 coverage review:
the status command's live-session output (pid/state/query fields against a
held pg-sprite session) and the lock-budget refusal wording, which were
previously untested paths.
…flag

Establishes the observability posture early: stdout carries only command
output, diagnostics go through log/slog to stderr, errors are logged once
at the entry point, and credentials are never logged. sloglint/forbidigo
enforce the mechanical half; --debug wires the previously unreachable pgx
statement tracing in pkg/dbconn plus migrate lifecycle events.
Log text and human-facing prose are no longer a test surface (rule added
to AGENTS.md, aligned with SchemaBot's observability guidance). The
lock-vs-statement budget distinction was only visible in prose, so the
verdict gains a typed machine-readable cause field, and status gains
--json so its tests can assert structured session fields.
Admit a declarative desired-state file (one CREATE TABLE plus its
CREATE INDEXes) through the real grammar, materialize it in an
always-rolled-back transaction-scoped scratch schema on the target,
and introspect both live and desired state into one canonical model
from server catalogs — semantic truth comes from PostgreSQL, never
from AST transformation, per the layered DDL-understanding decision.
Diff live vs desired canonical models into dependency-ordered SQL
changes with a destructive marker and typed refusals for unsupported
identity/generation changes. `diff` emits an executable text plan or
a JSON report; `fmt` canonicalizes offline via the parser/deparser.
The unpinned lint action installed a v1 binary built with an older
Go than the module targets, so it could not load the v2 config.
Matrix jobs now render as "test (PostgreSQL NN)" in the checks UI.
Checks now render as CI / lint, CI / test (PostgreSQL NN), and
CI / all-green instead of the ci / ci-ok stutter. "all-green" is
the context to require once branch protection is wired.
Semgrep and zizmor code-scanning gates require third-party actions
pinned to a full commit SHA, matching the existing paths-filter pin.
Extend the parse boundary with ParseOps — one typed shape descriptor
per operation (default constancy, generated/identity, NOT VALID,
USING INDEX, CONCURRENTLY, renames) — plus two syntactic advisory
rewriters: Concurrently and AddNotValid. These are the classifier's
inputs; no semantics are derived from the AST.
pkg/planner maps each operation to a route with a typed reason,
golden-tested against every row of the online-DDL reference. Risky
literals get the safer native sequence (CONCURRENTLY, NOT VALID +
VALIDATE, USING INDEX attach, the four-step SET NOT NULL pattern).
Conservative by construction: unproven defaults are volatile, type
changes without live column facts are rewrites, unknown operations
are refused.
pkg/router is the policy layer between the classifier and the executors:
every classified statement gets a backend (native / copy-and-swap) and a
typed disposition; copy-and-swap routes come back unavailable until that
executor exists, instead of pretending to run. diff and the new
migrate --dry-run share the identical classify-and-route pipeline, with
live column types feeding the classifier. Refs PLAT-38439.
The action's default binary is built with an older Go than the module
targets and cannot load the v2 config; SHA-pinning also satisfies the
semgrep and zizmor unpinned-action checks.
The action's default binary is built with an older Go than the module
targets and cannot load the v2 config; SHA-pinning also satisfies the
semgrep and zizmor unpinned-action checks.
Addresses the scoped agent review on PR #4: git/PR workflow section,
identifier-quoting and DSN-handling rules, schema-change terminology,
flake-verification script, and TM-9 (operation must outlive the
observer).
…iran01bm/phase-1-front-door

* origin/kiran01bm/ci-foundations:
  docs: port reviewed SchemaBot AGENTS.md conventions
  ci: pin golangci-lint-action and lint binary version

Amp-Thread-ID: https://ampcode.com/threads/T-019fcb83-1db5-74dd-8aa5-b27a21407b7f
Co-authored-by: Amp <amp@ampcode.com>

# Conflicts:
#	.agents/checks/review.md
#	AGENTS.md
Every PR, design, and review is judged as (a) an OSS-first standalone
Postgres online-DDL tool and (b) a clean SchemaBot engine integration;
trading one off against the other needs an explicit decision.
Addresses the two-lens and adversarial review findings:
- ST-7: the executor accepts only a ParseOne-constructed Statement whose
  target matches the preflight proof, so multi-statement SQL and
  cross-table smuggling are unrepresentable
- size guard measures pg_total_relation_size (heap, indexes, TOAST) —
  the rewrite it fears rebuilds every index under the same lock
- sub-millisecond budgets are rejected (they truncate to 0ms, which
  disables the PostgreSQL limit)
- table-targeted RENAME / SET SCHEMA route through the front door
  instead of being refused as non-ALTER TABLE
- status coalesces pg_stat_activity fields nulled for other roles
- already-concurrent index forms no longer get circular safer-idiom
  advice; verdict reasons are flat kebab-case tokens; byte-size parsing
  rejects int64 overflow; CI builds with CGO_ENABLED=0
…to kiran01bm/phase-2-1-2-2-diff

* origin/kiran01bm/phase-1-front-door:
  Harden the front door per PR #5 reviews
  Add the two project lenses to AGENTS.md and review checks
  docs: port reviewed SchemaBot AGENTS.md conventions
  ci: pin golangci-lint-action and lint binary version
  ci: pin golangci-lint-action and lint binary version

Amp-Thread-ID: https://ampcode.com/threads/T-019fcb83-1db5-74dd-8aa5-b27a21407b7f
Co-authored-by: Amp <amp@ampcode.com>

# Conflicts:
#	SAFETY.md
#	internal/cli/migrate.go
#	pkg/statement/statement.go
#	pkg/statement/statement_test.go
…comments

Fixes from the two-lens and adversarial reviews at 14c9dee:
- refuse REFERENCES at desired-file admission (typed ErrForeignKey) —
  the scratch transaction cannot faithfully bind an unqualified FK
- refuse serial/sequence-backed default adoption (ErrUnsupportedChange)
  via pg_depend-backed Column.SequenceDefault — the plan would name a
  sequence that only existed in the rolled-back scratch transaction
- classify every Change with a typed Kind; mark DROP INDEX destructive
- annotate lock-hazardous statements in the text plan and point the
  header at migrate as the executing front door
- fmt fails closed on commented input (ErrCommentLoss) instead of
  silently discarding comments
- document column-order-by-name convergence and the two-canon boundary
…to kiran01bm/phase-2-3-2-4-classifier-router

* origin/kiran01bm/phase-2-1-2-2-diff:
  Address PR #6 review: FK refusal, serial adoption, change kinds, fmt comments
  Harden the front door per PR #5 reviews
  Add the two project lenses to AGENTS.md and review checks
  docs: port reviewed SchemaBot AGENTS.md conventions
  ci: pin golangci-lint-action and lint binary version
  ci: pin golangci-lint-action and lint binary version

# Conflicts:
#	SAFETY.md
#	internal/cli/cli.go
#	internal/cli/diff.go
#	internal/cli/diff_integration_test.go
Address PR #7 review findings: inline ADD COLUMN constraints and
CREATE TABLE ... PARTITION OF are now classified as the work they do,
and routing refuses (rewrite-required) any statement whose submitted
form blocks when no complete online rewrite was constructed — partial
rewrites of multi-operation statements can no longer execute the
original SQL. Generated scaffold names fit PostgreSQL's 63-byte
identifier limit deterministically.
…outer

Phase 2.3-2.4: classifier and router seam
@Kiran01bm
Kiran01bm marked this pull request as ready for review August 7, 2026 00:52
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Kiran01bm
Kiran01bm merged commit 1173b78 into main Aug 7, 2026
12 checks passed
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