capabilities: add the pg-sprite capabilities command - #99
Conversation
… tables docs/capabilities.md was hand-edited Markdown, so its tiers, marks, and owner vocabulary could drift from the verdict reasons the engine emits and from the contract in docs/capabilities-contract.md, and no machine consumer could read it. pkg/capabilities embeds capabilities.yaml (53 rows across 7 areas) and exposes it as typed rows behind a small API. Loading validates the closed vocabularies (tier, mark, backend, owner) and the cross-field rules against the real verdict.Reasons(), so a row cannot name a reason the engine does not have or carry an owner outside the tier that allows one. A renderer emits the marked matrix tables and the summary counts between markers in docs/capabilities.md; `make gen-capabilities` regenerates them and a unit test fails when the checked-in document is stale or a marker is malformed. Regeneration against the current document is a no-op and the table cell text is unchanged. This completes step 1 of the capabilities contract; the contract doc, SAFETY.md periphery table, and go.mod (yaml.v3 promoted to a direct dependency) are updated to match.
The support matrix is embedded in each binary, but users and automation could only read its generated Markdown form. That left tools to scrape prose and gave operators no quick terminal view of the binary's exact support claims. Add an offline capabilities command with a compact text table and stable JSON that pairs the typed rows with the release-stamped binary version. The command uses the package row types directly, so its fields and enum values stay tied to the validated YAML contract. Cover the JSON query cases and text rows in unit tests, exercise the packaged binary in the demo check, and document the new output and contract status.
… check The truncated `capabilities --json | head` example escaped the docs guard because its command line does not end in `--json`, so the one block that shows the new command could drift with every test green. Give it its own section and TOC entry on the examples page, and add a guard that compares the published lines byte for byte with what the command prints first. The contract doc's example row promised `"diff": "not_applicable"` for `refresh-materialized-view`; the registry says `refused` and nothing can emit the other value. Correct the example and add a test that marshals the named row and compares it with the printed object, so the promise stays checkable. The tour's version assertion accepted the literal string "null" that jq prints for a missing key. Compare the JSON version with `--version` instead, which is the claim the docs make. 🤖 Generated with Amp (Claude Opus 4.6)
…ities-subcommand * origin/main: capabilities: make the embedded YAML matrix the source of the support tables (#98) verdict: classify every refusal with a typed class and owner (#97) fix(dbconn): strip explicit pg_catalog from pooled search_path (#93) # Conflicts: # Makefile # docs/capabilities-contract.md # docs/capabilities.md # pkg/capabilities/capabilities.go # pkg/capabilities/capabilities.yaml # pkg/capabilities/capabilities_test.go
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
🤖 Reviewed Verified rather than taken from the description:
1. Nothing pins that the binary's real version reaches the JSON — three layers all default to
|
|
🤖 2/2 — tests, docs, and one comment placement. Correctness is in 1/2. Credit first, because it is the best thing in the PR. 4. The new test was inserted between an existing comment and the function it documents
// A pipe inside a cell is escaped so GFM keeps it in that cell; every
// other column stays in place and the escaped source renders as the pipe.
// The contract doc promises that one named row marshals to the JSON object
// it prints. Consumers copy that object's field values into jq filters, so
// the example must be the row's actual encoding, not a paraphrase of it.
func TestContractDocExampleRowMatchesRegistry(t *testing.T) {The first two lines belong to 5.
|
aparajon
left a comment
There was a problem hiding this comment.
🤖 Approving. Clean addition, and the strongest part is the one that wasn't the feature: TestContractDocExampleRowMatchesRegistry caught real pre-existing drift in the contract doc's example row, and all three of that doc's "must support" jq recipes check out against the real output. The JSON path is well pinned — a renamed version key and an unindented encoder both die on the captured-output test.
Six findings in the two comments above, none blocking. A 14-mutant harness came back 4 killed / 7 survived / 3 compile-skipped, and the split is informative: everything on the JSON path is covered, everything on the text path and the version wiring is not.
The one worth taking before merge is finding 1 — New(version ...string) makes cli.New() legal, so main.go dropping the version is a silent regression rather than a compile error, and each of the three checks that appear to cover it reads "dev" on both sides. Changing the signature to New(version string) turns that mutant into a build failure.
This stamp was left by Claude Code (claude-opus-5).
…content Address the review of the capabilities command: - New takes the binary version as a plain parameter; a caller can no longer build the command tree and silently leave the capabilities output reporting a default. A test pins the version through New. - The status mark is a double-width glyph, so it moves to an unpadded trailing STATUS column and the padded columns hold only single-width runes; the header now lines up with every row in a terminal. - clip measures and slices the same string, so it can no longer read past the value and emit NUL bytes for a leading-space cell. - The text test derives its expectations from the registry instead of the renderer's own clip: one line per row, a short operation verbatim, the mark in the same column on every line, the em dash for an empty owner. doorLabel and clip get direct table tests, including clip's boundary and leading-space cases. - The pipe-escaping test gets its comment back; the contract-doc example test carries only its own. - The published `capabilities --json | head` block shows the ten lines head prints. - The contract doc marks completion per step, so parallel step PRs edit their own line instead of rewriting one shared status sentence. 🤖 Generated with Amp (Claude Opus 4.6)
…b.com/block/pg-sprite into kiran01bm/cm3-capabilities-subcommand * 'kiran01bm/cm3-capabilities-subcommand' of https://github.com/block/pg-sprite: docs: decide the lock-budgeted passthrough contract (#102)
|
🤖 Adversarial review response — created by Kiran's code review agent (Amp, Claude Opus 4.6) — block/pg-sprite pull/99, follow-up commit Verdict: all six findings and the minor note were accurate and are fixed;
The credit paragraph on Source: #99, review comments 5624989278 and 5624990165 and review 5171940472 at head |
…ities-ci-gate * origin/main: fix(dbconn): keep the execution bounds where a pooler would drop them (#81) capabilities: add the pg-sprite capabilities command (#99) replay: assert the engine-emitted refusal class (#101) docs: decide the lock-budgeted passthrough contract (#102) # Conflicts: # docs/capabilities-contract.md
Add an offline
pg-sprite capabilitiescommand for human and machine access to the binary's embedded support matrix.Why
The generated support page is easy to read, but automation should not scrape Markdown and operators need to know which matrix their binary contains.
What
pkg/capabilities.Before / after
Refs: docs/capabilities-contract.md