77 lines
4.0 KiB
Markdown
77 lines
4.0 KiB
Markdown
# ADR-0016: Use feedback-aware module-requested retries
|
|
|
|
**Status:** Accepted
|
|
**Date:** 2026-08-28
|
|
|
|
## Context
|
|
|
|
An LLM-backed module can discover that a structurally valid model response is
|
|
unsafe while translating it into a typed candidate, before the ordinary
|
|
validator chain runs. Semantic registry reconciliation is the first such case:
|
|
the shared core can identify invalid duplicate-group proposals, and typed
|
|
application can reject a domain-incompatible group while preserving a safe
|
|
partial result. Repeating the original request without the rejected response or
|
|
corrective explanation gives the model no information with which to improve.
|
|
|
|
The existing feedback-aware validation mechanism already establishes the safe
|
|
correction protocol, but module-owned retry directives also carry internal
|
|
reason codes, operator messages, and fallback diagnostics. Those values are not
|
|
model instructions. Some module retry conditions, including exhausted
|
|
structured-output repair, also have no valid exact response to append.
|
|
|
|
## Decision
|
|
|
|
An LLM-backed normalizer may attach optional, bounded model-facing correction
|
|
guidance to a module-requested retry. Guidance is a separate contract field; the
|
|
framework never derives it from a reason code, operator message, diagnostic, or
|
|
error. A feedback-capable directive must include the exact model candidate that
|
|
controlled the safe fallback and must use `single_response_v1`.
|
|
|
|
The artifact-neutral producer-attempt state machine constructs the correction
|
|
from that exact latest response and the supplied guidance. The producer rebuilds
|
|
its complete ordinary request and appends the response as one assistant message
|
|
and the guidance as one user message. Earlier attempts do not accumulate, and
|
|
the attempt consumes the same configured stage retry budget as operational,
|
|
structural, validation, and feedback-free module retries.
|
|
|
|
A module retry without guidance remains valid and starts a fresh attempt. This
|
|
is the required behavior when no valid model candidate exists, including after
|
|
structured-output repair is exhausted. If feedback is supplied without a valid
|
|
supported candidate, the framework fails the module contract rather than
|
|
retrying blindly or inventing guidance.
|
|
|
|
After retry exhaustion, the normalizer's safe fallback continues through its
|
|
validator chain. Safe semantic groups may remain applied, unsafe groups remain
|
|
separate, and bounded fallback diagnostics may explain the process degradation.
|
|
Exact responses and correction text remain attempt-local and are excluded from
|
|
ordinary errors, warnings, manifests, receipts, caches, and checkpoints.
|
|
|
|
This decision extends, rather than supersedes,
|
|
[ADR-0014](0014-feedback-aware-validation-retries.md): both correction sources
|
|
use the same transport-neutral payload, replacement-request semantics, outer
|
|
retry budget, and sensitive-data boundary.
|
|
|
|
## Alternatives considered
|
|
|
|
- Continue blind module retries. This preserves a smaller contract but wastes
|
|
the module's deterministic diagnosis and commonly repeats the same defect.
|
|
- Convert module safety checks into validators. Typed reconciliation must apply
|
|
only safe proposal groups and retain a fallback before validation; moving
|
|
artifact-owned translation and application policy into validators would blur
|
|
stage ownership.
|
|
- Copy the retry reason or operator message into the model request. Those values
|
|
are written for provenance and humans, can contain opaque internal labels,
|
|
and do not reliably describe a correct replacement.
|
|
- Require feedback for every module retry. Structural failures may have no
|
|
valid exact candidate, so this would either prevent useful fresh retries or
|
|
fabricate prior-response material.
|
|
|
|
## Consequences
|
|
|
|
The normalize retry contract and generic producer-attempt directive gain an
|
|
optional correction-guidance field and candidate-pairing validation. Modules
|
|
that use it must provide semantically meaningful bounded prose and an exact
|
|
candidate. Registry reconciliation maintains separate operator and model
|
|
renderers, and policy fingerprints change so checkpoints created under blind
|
|
retry behavior are not reused.
|