replay: assert the engine-emitted refusal class - #101
Draft
Kiran01bm wants to merge 3 commits into
Draft
Conversation
A refusal reason names the immediate cause but not the kind of boundary reached. unsupported-statement covers a data backfill, an imperative CREATE TABLE, a permanently refused CREATE INDEX IF NOT EXISTS, and a parse/route incoherence; unsupported-partitioned-parent spans three classes along its PartitionRefusalCause. Consumers rebuilt that split from reason strings. docs/refusal-classes.md decided the vocabulary; this change makes the engine emit it. pkg/verdict gains the Refusal proof type: NewRefusal(class, reason, owner) rejects a zero or unknown class, an unknown reason, and an owner outside no-online-safety-problem; the per-class constructors are total for valid inputs, so there is no panic path; Verdict.WithRefusal is the one place a verdict acquires outcome, reason, class, and owner together (RF-7). The classification registry has two halves keyed on the typed cause where one exists and on the refusal site where none does, never on the reason string. pkg/plan/refusal.go classifies plan-side keys (CreateShapeRefusal, PartitionRefusal, RouteRefusal); pkg/migrate/refusal_registry.go classifies statement kinds at the gate, both admission sentinel sets, and each imperative site. TestRefusalRegistryIsComplete derives its keys from the production closed sets and pins a sentinel subset so a broken deriver cannot pass on an empty set. statement.Kinds() is added and the kinds split so KindOther no longer absorbs provisioning, catalog-work, or data-change statements. Plan refusals fail closed. RefuseUnsupportedPartitionedParent now takes the causes and returns ErrInvariantViolation on a length mismatch or an unclassified cause; a plan statement refused without a class keeps its reason and is reported invariant-violation. JSON gains class and owner on verdicts, plan statements, and plan reports (additive, omitempty); the text renderer prints them on refusals; demo/tour.sh asserts the class beside reason and cause. Docs: RF-7 registered, refusal-classes.md rewritten from proposal to shipped behavior, limitations.md and README no longer claim every refusal is an online-safety gap, and the partitioned-parent NOT VALID FK matrix row corrected to agree with its environmental class. Exit codes and every existing reason string are unchanged.
Read refusal class and owner from each JSON verdict, require every refusal expectation to pin both reason and class, and bucket the replay summary from the engine output. Re-curate the Buzz assessment into the compound expectation grammar and document the engine contract as authoritative, including all five classes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make corpus replay assertions and summaries use the refusal class emitted by pg-sprite.
Why
The replay manifest maintained a separate classification column that could drift from the engine's routing contract and hide class regressions.
What
Before / after
Refs: docs/refusal-classes.md