feat: repair-oriented structured-output recovery (ADR-0031)#23
Merged
Conversation
Replace the blind byte-identical structured-output retry with a recovery
ladder: fence salvage -> classify -> repair-oriented retry -> degrade.
- Phase 0: ParseFindings unwraps a lone ```json fence pair before
json.Unmarshal, so fenced-valid JSON parses with zero retries. Non-fenced
input is byte-identical, so the cache key is unchanged and cached FormatJSON
fenced bodies render as findings on replay.
- Phase 1+2: ParseFindings returns a typed *ParseError{Kind}
(empty/prose/malformed-json/schema; message text unchanged so existing
substring assertions hold). tryStructuredReview classifies the failure and
sends a failure-mode-specific repair prompt instead of the identical request
-- a hard "JSON only" reset for prose/schema-ignored, or a "complete the
JSON" nudge (partial output embedded, max_tokens raised) for a truncated
attempt. The retry stays a fresh single-shot request; the markdown-fallback
terminal state and summed usage are unchanged.
- Observability: additive omitempty meta.retry_count / meta.degrade_reason
(schema stays 1) + two --verbose footer lines; live-call-only.
CLI plain-text providers, the degrade contract, and the cache key are
untouched.
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.
Closes #22.
Replaces the blind byte-identical structured-output retry with a recovery ladder: fence salvage → classify → repair-oriented retry → degrade.
Changes
internal/render/findings.go):ParseFindingsunwraps a lone```json … ```fence pair beforejson.Unmarshal. Non-fenced input is byte-identical, so the cache key is unchanged and cachedFormatJSONfenced bodies render as findings on replay.ParseFindingsreturns a typed*ParseError{Kind}(empty / prose / malformed-json / schema) with unchanged message text (existing substring assertions hold).tryStructuredReviewclassifies the failure and sends a failure-mode-specific repair prompt instead of the identical request — a hard "JSON only" reset for prose/schema-ignored, or a "complete the JSON" nudge (partial output embedded,max_tokensraised) for a truncated attempt. The retry stays a fresh single-shot request; themarkdown-fallbackterminal state and summed usage are unchanged.omitemptymeta.retry_count/meta.degrade_reason(schema stays1, ADR-0027 precedent) + two--verbosefooter lines. Live-call-only.CLI plain-text providers, the degrade contract, and the cache key are untouched.
Tests
findings_test.go: fence salvage across fence spellings + typed error-kind classification.structured_test.go: repair recovery (prose reset / truncated complete), degrade reason, cache-replay of fenced content, usage summing.render_test.go:retry_count/degrade_reasonJSON omit-when-zero / present-when-set + verbose footer; v1 golden confirms byte-stability.make checkgreen (fmt / vet / lint / test / release-check / i18n-check / spdx-check / gosec);make evalgreen.Docs (
.ssot+ wiki) synced separately: new ADR-0031, ADR-0014 §Update, json-schema-v1 §Update.