fix(verify): stop re-compaction poison from fail-closing the verification gate - #73
Merged
Merged
Conversation
…tion gate (#72) The deterministic extraction re-mined the prior compaction's embedded summary text and this extension's own error prose as live constraints. One stale constraint contradicting the factually correct new state cost the full 20 points, and inconsistency gaps are not deterministically patchable — so a second compaction cycle could never pass the gate. Three layers, mirroring the issue's poison classes: - Extraction: isNonLiveConstraintText filters own gate/notify prose, [x] completion records, and compaction status lines out of constraint mining and state sanitization. - Retirement: retireSupersededConstraints marks a constraint superseded when a later user message releases it. Deferral rules ("do not push yet") accept a terse release via anchor polarity flip; standing rules ("never commit directly to main") still require the full rich contradiction check, so a terse imperative sharing one verb cannot silently drop a live rule. The replacement is kept as critical context, not as a rule. - Wiring: the extract step computes the overrides once; both the post-synthesis and post-state gates consume them via VerificationEvidence.factOverrides, and buildState persists them so applyContinuityOverrides drops the stale rule from the merged state and the continuity capsule cannot re-poison the next generation. 19 regression tests cover the poison classes, retirement semantics (terse/verbose release, standing-rule conservatism, restatement, index guard, upsert), the exact gate signature from the issue, and persistence through buildState.
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.
Fixes #72
Root cause (confirmed in code)
Three poison classes fed the verification gate stale/self-referential "constraints":
VerificationGateErrorback into the session; the next run mines "do not bypass verification" as a prohibition. Retrying adds evidence the next retry is checked against.[x]completion records — the prior summary's Done items are records, not rules.semantic-contradiction= −20,gaps.length > 0→80/100→ permanent fail-closed (inconsistency gaps are not deterministically patchable).Fix — three layers
isNonLiveConstraintTextfilters own gate/notify prose,[x]items, and compaction status lines from constraint mining + state sanitizationretireSupersededConstraintsmarks a constraint superseded when a later user message releases it. Deferral rules ("do not push yet") accept a terse release ("ok push it now") via anchor polarity flip; standing rules ("never commit directly to main") keep the strict rich-contradiction check — a terse imperative sharing one verb cannot silently drop a live rule. The replacement is kept as critical contextrc.factOverrides); post-synthesis and post-state gates consume them viaVerificationEvidence.factOverrides;buildStatepersists them soapplyContinuityOverridesdrops the stale rule from the merged state and the continuity capsule cannot re-poison the next generationVerified
inconsistencygap,ok: false. With retirement →100/100, zero gaps.bun run typecheck(4 tsconfigs) andbun run buildclean.Notes for the reporter
compact-extraction-<session>.jsoncaches replay old constraints, but the gate-sideisNonLiveConstraintText+ retirement filters apply to cache-derived constraints too, so an in-place upgrade self-heals without clearing caches.