docs: state that DROP TABLE is out of scope and who owns undeclared tables - #77
Conversation
…ables The support matrix had no DROP TABLE row, so a reader could not verify from pg-sprite's own docs that the engine never plans or executes one. The diff is single-table scoped, so a live table with no desired file is outside its view; that reconciliation is the whole-schema owner's job, and the integration guide now says so.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
🤖 Adversarial correctness review — The gap is real and worth closing: a matrix that lists The findings are about the second half — the who owns it claim, which is where the new prose makes assertions the code and the sibling repo don't support.
1 — the "only convergence" argument skips the step SchemaBot already took (med)Both new passages make the same move:
The premise is right; the conclusion doesn't follow from it. "The only convergence is a drop" and "so the orchestrator blocks" are two claims, and the orchestrator this doc is written for already implements the other branch. SchemaBot's MySQL declarative path diffs the whole database as one unit and plans the drop — its own error text says so, in the repo this doc names:
and it makes that safe rather than blocking it: That makes the Postgres proposal a deliberate cross-engine divergence, and this doc is the only place it would be recorded — but it's written as a deduction, so a reader (or an adapter author) takes it as the forced answer. Two things follow:
There's also a consequence of the rule as written that the doc doesn't scope: each undeclared table blocks. A schema being onboarded one table at a time is entirely undeclared tables, so the first PR declaring one table is blocked by the other N. Whether the declarative root is authoritative for the whole schema or only for what it declares is the actual design question underneath this bullet, and it's the one an adapter author will hit first. 2 — the instruction is in the wrong side's vocabulary, and hides that the row has to be invented (med)
Everywhere else this bullet list is scrupulous about which side owns which term — the sibling bullet spells it out: " Synthesizing raises the question the sentence skips: what goes in the row's
3 — the count the PR bumps is off by one, and a sibling count wasn't (low)Counting the matrix rows between The drift is pre-existing — Two smaller ones on the same page:
Verified — the claims that hold, and an attack that dissolvedEvery factual assertion in the three new passages checks out.
⭐ Attack that dissolved: the ⚪/🔵 marker looked wrong. The new row's safety column reads "No — owner tooling, through a reviewed process", and "owner tooling" sounded like the 🔵 gloss (a different tool class owns it), which would have moved a row between buckets without changing the total. It doesn't: across the whole matrix, plain "No — owner tooling" is the ⚪ convention — 5 of the 6 pre-existing ⚪ rows use that exact phrase (enum/domain creation, views, function bodies, triggers, extensions, standalone sequences) — while every 🔵 row names a specific competing tool class ("data-change runners", "convergence planners (pg-schema-diff, pgschema, pgdelta)", "pgroll/reshape", "provisioning / IaC"). The two new prose entries agree with each other, which is not automatic across three files: Nothing else in This review was generated by Claude Code (claude-opus-5). |
|
🤖 Two-lens product review — OSS adoption, then SchemaBot integration Separate from the correctness comment above: how this reads to someone who has never heard of SchemaBot, and how it holds up as the contract Lens 1 — OSS adoption easeThe matrix row is a clear win here. "Does it drop tables?" is a first-five-minutes question for anyone evaluating a schema tool, and answering it in the canonical matrix — with the reasoning, not just a ⚪ — is better than the silence it replaces. Two things work against that reader, though, and both are in the routing rather than the content: The standalone user is handed a SchemaBot doc. The rule has no recipe. "Enumerate the live tables itself" is the actionable half, and nothing in Smaller: the new limitations row is one 90-word sentence-plus-clause doing four jobs (what Lens 2 — SchemaBot integrationThe bullet assigns a job with no seam. Every other item in Adapter design notes for the
Each of those is a false positive that blocks, and blocking failures are the expensive kind: they stop a merge on a table nobody touched. An exported One thing the bullet does well and should keep: stating that the divergence must "show on the plan and the apply is refused rather than the table lingering unreported" pins the fail-closed direction, which is the property that matters and the one an adapter would otherwise get wrong by omission. That sentence is doing real work — it's the how underneath it that's missing. This review was generated by Claude Code (claude-opus-5). |
aparajon
left a comment
There was a problem hiding this comment.
🤖 Approving on Kiran's behalf after the adversarial correctness review above. The findings there are yours to pick up as follow-ups — flagging them, not gating on them.
This stamp was left by Claude Code (claude-opus-5).
… for undeclared tables Review of the drop-table docs found three gaps: "block" read as a forced deduction when it is a policy choice (SchemaBot's MySQL path quarantines instead), the adapter guidance used a verdict vocabulary pg-sprite has no type for, and a standalone user was routed to the SchemaBot doc for a task that is theirs. The operator-owned section now carries the catalog recipe (the same listing pull baselines from, verified against every exclusion), the integration doc states the divergence and its reason in SchemaBot's own types, and the README gains the short-form pointer. Matrix counts corrected.
|
🤖 Review response — created by Kiran's code review agent (Amp, Claude Opus 4.5) — pull/77, follow-up commit All three correctness findings and lens 1 are fixed in follow-up commit
Source: review comments 5550008208 and 5550008598 at head |
Adds the missing
DROP TABLErow to the support matrix and documents that reconciling live tables with no desired file is the whole-schema owner's job, not the per-table diff's — including how the owner enumerates those tables and why blocking rather than quarantining is a policy choice, not an engine deduction.Why
docs/capabilities.mdis the canonical matrix for every operation, but it listedDROP COLUMN,DROP CONSTRAINTandDROP INDEXwith no table-level drop, so an orchestrator author could not confirm from pg-sprite's docs that the engine never plans or executes one. The gap matters for anyone usingdiffper file over a directory: a live table that has no desired file is silently absent from every diff, and under a declarative model its only convergence is a drop — so whoever owns the whole schema has to enumerate live tables and surface the divergence rather than report the schema as up to date.Review of the first cut surfaced three more gaps: "block" read as forced by the model when an orchestrator may legitimately quarantine instead; the adapter guidance borrowed a verdict vocabulary pg-sprite has no type for (there is no
verdict.Verdictfor a table pg-sprite never saw); and a standalone user hitting this was routed to the SchemaBot doc for a job that is theirs.What
capabilities.md:DROP TABLErow (⚪ out of scope, owner tooling) under whole-table operations; matrix count and ⚪ legend corrected. New Deliberately operator-owned bullet, "Dropping a table nobody declares any more": the reasoning, the two remedies (pull/exporta file, or a reviewed drop), block-vs-quarantine as the owner's policy, onboarding (pullfirst, or scope owned schemas), and the catalog recipe with its exclusions —pg_catalog-qualified, relkindr/p, nopg_inheritschildren, no extension-owned relations — plus why the rolled-backpgsprite_scratch_<random>schema never appears in it.limitations.md: "Live tables with no desired file" row in the declarative boundaries, pointing at the operator-owned section.schemabot-integration.md: the fan-out bullet splits out "So is the set of tables", written in SchemaBot's own types — the adapter synthesizes anengine.TableChange(ExecutionModeBlocked,IsUnsafe,ModeReasonnaming the remedies;DDLmay carry the canonicalDROP TABLEfor display only;verdict.ReasonDestructiveChangenot reused) — and states the deliberate divergence from SchemaBot's MySQL path, which plans the drop and quarantines behind its unsafe acknowledgment: PostgreSQL gets the block because pg-sprite offers no whole-schema convergence and the drop is outside its statement set, so the orchestrator holds the only view of the table set; a PG quarantine (SET SCHEMA) would be the orchestrator's mechanism to add.README.md: "Dropping a table" bullet under What pg-sprite does not do yet, per the capability-statement rule.Docs only; the imperative-door refusal it describes is already pinned by the existing
Gate("DROP TABLE t")test. The catalog recipe was run against PostgreSQL 16 with a partition, anINHERITSchild, a view and an in-schema extension present — it lists exactly the declarable tables.Before / after