Add pkg/plan: one versioned dry-run report for both front doors - #8
Conversation
migrate --dry-run --json and diff --json previously emitted two ad-hoc JSON shapes (router.Plan and a private diffReport). Consolidate them into a single versioned plan.Report (format_version 1) so an orchestrator adapter parses one contract regardless of how the plan was derived. Groundwork for PLAT-38440 (dry-run plan + suggest surface).
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
🤖 Review requested by Armand and performed by his agent — same two lenses used across this stack (#2, #3, #4, #5, #6, #7): pg-sprite as an OSS-first, best-in-class Postgres DDL tool, and pg-sprite as a clean integration target for an orchestrator. Reviewed at head Collapsing two unversioned shapes into one versioned report is the right move made at the right time — before any consumer exists, which is the only moment it's free. Several details are better than they had to be: OSS lens
Integration lens
Verified solidBoth front doors genuinely do run the same classify-and-route pipeline — I exercised This review was generated by Claude Code (claude-fable-5). |
|
🤖 Adversarial correctness review requested by Armand and performed by his agent — separate from the two-lens pass. Method: attack the unified contract by asking whether the two front doors it unifies actually agree, then verify against a real PostgreSQL at head Findings, most severe first1. The text renderer inherits it — Two things make this worse than a missing field. First, The fix is available without new information: the classifier already knows. 2. The report omits A consumer storing or forwarding this plan cannot tell which table it describes, and re-resolving it later against a different 3.
Probed and held
Reproduction test
|
aparajon
left a comment
There was a problem hiding this comment.
🤖 Approving on Armand's behalf. My two-lens review and adversarial correctness pass are posted above — the findings there are for follow-up, not fix-before-merge blockers.
This approval was submitted by Claude Code (claude-fable-5) at Armand's direction.
…ontract * origin/main: vision: describe the ecosystem by capability model, not named tools Address PR #2 review: gate releases, attest artifacts, OSS positioning planner, router: fail closed on unconstructed safer rewrites 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 ci: pin golangci-lint-action and lint binary version chore: list project leads in CODEOWNERS # Conflicts: # SAFETY.md # internal/cli/diff.go # internal/cli/dryrun.go
Destructiveness is derived in the classifier so both doors report it identically by construction; report SQL is canonicalized through the deparser (commented input refused, never silently stripped); the report gains a mandatory fingerprint, server_version, resolved schema, and closed vocabularies pinned by test. Contract documented in docs/plan-report.md with generated examples. Review: #8 (two-lens and adversarial passes)
|
Review response from Kiran's (@Kiran01bm) AI code review assessment agent (Amp / Claude Opus 4.5) All nine findings across both passes are fixed on this branch; the merge with
|
Summary
Consolidates the engine's two ad-hoc dry-run JSON shapes into one versioned, machine-readable plan contract:
pkg/plan.Report. Both front doors —migrate --dry-run --jsonanddiff --json— now emit the same shape, so an orchestrator adapter parses one contract regardless of how the plan was derived. First slice of the P2.5 dry-run/advisory surface; a real linter and an advisorysuggestcommand stack on top of this.What
pkg/plan:Reportwithformat_version: 1, a typedsource(alter|diff), and a sharedStatementcarrying SQL, route, backend, disposition, per-operation decisions, and the saferexec_sqlsequence.migrate --dry-run --jsonemitsplan.Reportinstead of rawrouter.Plan;diff --jsonemits it instead of the privatediffReport.table_existsis optional (pointer): set only by the diff path, which introspects for existence; omitted for the alter path.statementsas[], nevernull; consumers reject unknownformat_version.pkg/planat 100% statement coverage.Why
The dry-run report is the seam a future orchestration adapter consumes to decide whether and how a change would execute. Two divergent, unversioned shapes made that seam fragile: consumers had to know which command produced the JSON and could not detect contract drift. One versioned report removes both problems before the linter and
suggestsurfaces widen the contract.Before / after
References
kiran01bm/oss-standup)