add make demo: runnable CLI tour and artifact smoke test - #39
Conversation
demo/tour.sh walks one statement per planner route and reason, the declarative diff, the offline commands, and real executions (safer sequences, structured refusal) against the seeded compose database. CHECK=1 asserts on --json fields and exit codes only; CI runs it as an artifact smoke test — Go tests cover the code, not the artifact, so this is the one check that exercises the built binary the way a user invokes it. AGENTS.md binds the expectation rows to planner/CLI contract changes so the tour cannot silently rot.
Add a disposition column to the dry-run expectation rows and drive the exit assertion from it: execute-disposition plans must exit 0, while plans that would not execute (unavailable, refuse) are accepted at 0 or the refusal code, so the tour passes on builds on either side of the dry-run exit-code contract. Tighten to exactly the refusal code once every supported build carries it.
3c6da45 to
5a4fe35
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
morgo
left a comment
There was a problem hiding this comment.
🤖 Approved on Morgan's behalf (agent review, liberal pg-sprite bar).
Verified:
- Hermetic by construction: the tour's DSN host is hardcoded
localhostin the Makefile and passed explicitly on the recipe line, so an exportedPG_DSNcan't leak in; the only destructive SQL (DROP TABLE ... CASCADEin demo/seed.sql) runs viadocker compose execstrictly inside the compose container; and if a real PostgreSQL already holds localhost:5432,db-up --waitfails to bind and make aborts before the seed or tour runs. Exec-section writes are additive only. - CI smoke job is least-privilege: inherits
permissions: contents: read,persist-credentials: false, checkout/setup-go SHAs byte-identical to the existing jobs, no new third-party actions, no secrets; docs-only-skip semantics of all-green preserved. - No startup race:
compose up --wait+ 1s healthcheck gates the seed; seed fixtures line up with every check-mode assertion (all 10k emails non-null so SET NOT NULL validates, both diff plans exactly 2 statements).
Non-blocking nits:
demo: build db-up demo-seedrelies on serial-make prerequisite ordering — undermake -j, demo-seed can race db-up, and standalonemake demo-seedfails if the DB isn't up. Ademo-seed: db-updependency fixes both. (CI runs serial, so unaffected.)- Individual tour sections assume the freshly seeded baseline — a second
execor standalonediffafter one pass fails its expectations.make demoalways reseeds, so just worth a line in demo/README.md. - In demo (non-check) mode the fmt step swallows a failure silently (empty output, no
(exit $?)echo like the other steps). Cosmetic. - The dry-run exit-code assertion deliberately accepts 0 or 2 (documented "tighten later") — fine for a smoke test, remembering it for when the exit-code contract firms up.
|
🤖 Adversarial correctness review, requested by @aparajon and performed by his agent. Reviewed at head Verdict: the job is the right idea and it works — but in check mode it cannot observe the one behaviour the product exists for. The tour asserts routes, reasons, dispositions and counts well. It does not assert a single substituted statement, so the safer-sequence machinery the PR body, Findings1. The smoke test cannot tell a safer substitution from no substitution at all. $ pg-sprite migrate --json --alter 'ALTER TABLE users ALTER COLUMN email SET NOT NULL'
{
"outcome": "executed-natively",
"executed_sql": [
"... ADD CONSTRAINT \"users_email_not_null\" CHECK (\"email\" IS NOT NULL) NOT VALID",
"... VALIDATE CONSTRAINT \"users_email_not_null\"",
"... ALTER COLUMN \"email\" SET NOT NULL",
"... DROP CONSTRAINT \"users_email_not_null\""
]
}A regression that dropped 2. The dry-run exit code is accepted as either answer for every refusal.
3. (verified: 4. The lint assertion is satisfied by any failure, including the binary not existing. $ CHECK=1 PGS=/nonexistent/pg-sprite ... # lint block only
status=127 failures=0
5. (nit) $ PGS=bin/pg-sprite PG_DSN=... demo/tour.sh offline
demo/tour.sh: line 172: bin/pg-sprite: No such file or directoryThe Makefile passes 6. (nit) Action items
Verified (tried to break, couldn't)The tour is genuinely rerunnable: One thing outside this diff, surfaced by reading the tour's real output: This review was generated by Claude Code (claude-opus-5). |
|
🤖 Second pass on Lens 1 — OSS adoptionShow the starting schema before the first statement. Right now the tour opens with And pg-sprite cannot currently do that to its own fixtures — which is the more interesting finding. The obvious implementation is $ pg-sprite fmt demo/seed.sql
pg-sprite: error: input contains comments, which formatting would discard # exit 1
$ pg-sprite fmt demo/desired/users_v2.sql
CREATE TABLE users (id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, email text, name varchar(50), status text DEFAULT 'active', bio text);Two things worth separating out of that:
Fixing both would let the demo open with The tour buries its headline and closes on a limitation. The single most persuasive fact about pg-sprite — you wrote The final impression of the tour is a feature that does not exist yet. That refusal is honest and belongs in the run — it already appears three times in the classification section — but it should not be the closing frame. Two cheap changes: lead with Roughly a third of the dry-run section is repeated chrome. The most persuasive demo is the one that is missing: lock contention. The zero-friction path is documented but not sequenced. Correcting myself here: the Smaller things from the live run. The Lens 2 — the seam an orchestrator consumesThis job is now the only thing in the repo that exercises the JSON contracts as a shipped artifact, which makes it the natural place to pin what the Go tests structurally cannot: that The This review was generated by Claude Code (claude-opus-5). |
aparajon
left a comment
There was a problem hiding this comment.
🤖 Approving on @aparajon's behalf. Adding an artifact smoke test to all-green is the right call and the wiring is correct — nothing here can reach a user's database, so the findings are coverage and adoption rather than gates.
The one I would not let slide past this PR is finding 1 in the adversarial comment: in check mode the tour asserts .outcome, and executed-natively is emitted whether or not a safer substitution happened — so the safer-sequence behaviour that AGENTS.md binds to this file is not actually observed by it. executed_sql is already in the JSON and is exactly the typed field the rules permit asserting on.
This review was generated by Claude Code (claude-opus-5).
Address the #39 reviews: check mode now observes the safer-sequence substitution itself (step count + fragment) and the report contract versions instead of accepting any green, pins the refusal exit and the lint gate exactly, and covers the rewrite-required disposition. The interactive tour closes on a summary frame rather than a refusal.
|
Review response from Kiran's (@Kiran01bm) code review assessment agent (Amp / Claude Opus 4.5) Summary: All four correctness findings and both nits are fixed in Adversarial correctness review (comment)
The "verified (tried to break, couldn't)" section — rerunnability, fail-closed jq gate, Adoption / orchestrator review (comment)
|
* origin/main: Version the progress contract and pin the TCB import boundary Address PR review: serialize pollers, unify clocks, cover WithProgress API suggest: make guidance total and safe to follow literally suggest: derive guidance for unnamed CHECK and FK constraints plan: carry typed guidance on rewrite-required statements (format v2) Add strategy-wide execution progress tracking
…demos # By kiran01bm # Via GitHub * origin/main: add make demo: runnable CLI tour and artifact smoke test (#39) # Conflicts: # Makefile
Adds
make demo: a runnable tour of the CLI that doubles as CI's artifact smoke test for the builtbin/pg-spritebinary.Why
The Go suite tests the code, not the artifact: nothing exercised the shipped binary the way a user invokes it — flag parsing, Kong wiring, exit-code mapping, JSON encoding on real stdout. There was also no low-friction way for a newcomer to see every planner route, the safer-sequence substitutions, and a structured refusal happen against a real database.
What
demo/tour.sh— four sections: one statement per planner route/reason (dry-run), declarative diff plans, the offline commands (lint/suggest/fmt), and real executions ending in abackend-unavailablerefusal (exit 2).CHECK=1turns it into a smoke test asserting on--jsonfields and exit codes only — never prose.make demo(build → compose DB up → reseed → tour),make demo-seed,make demo-check.make demo-check; added toall-green.AGENTS.mdbinds the expectation rows to planner/CLI contract changes so the tour cannot silently rot.