Verification, Repair, and Rejection
Chapter 12 gave the system a control plane.
It can now say:
commitment = HOLD
next_action = VERIFY
or:
commitment = HOLD
next_action = RETRIEVE
or:
commitment = HOLD
next_action = REFINE
or:
commitment = DENY
response_mode = REJECTION
Those are policy decisions.
They are not yet recovery implementations.
The obvious implementation is dangerously tempting:
The answer failed a check.
Ask the model to fix it.
But the model that produced the first unsupported statement can produce a second unsupported statement while “correcting” it.
A fluent repair is not evidence that the repair is correct.
A more confident repair is not evidence that the repair is correct.
A longer explanation of the repair is not evidence that the repair is correct.
The system needs a stricter loop:
graph TD
CS[candidate state] --> V[verification]
V --> FR[localized failure record]
FR --> RC[repair contract]
RC --> RA[repair action]
RA --> NCS[NEW CANDIDATE STATE]
NCS --> IM[invalidate affected measurements]
IM --> RM[re-measure]
RM --> RAUTH[re-authorize]
Repair changes the candidate state, so the system must invalidate affected measurements and require authorization again.
The central invariant is:
A repaired claim is still a claim.
Where we are
The book now has:
GENERATOR
β
CANDIDATE
β
MEASUREMENTS
β
RELIABILITY RECORD
β
POLICY
β
COMMITMENT + NEXT ACTION
Chapter 13 implements several of those next actions:
VERIFY
RETRIEVE
REFINE
REJECT_CANDIDATE
ABSTAIN
REVIEW
The engineering problem is not merely:
How do we improve a bad answer?
It is:
How do we improve a bad answer without silently discarding the reliability guarantees we just built?
That requires six disciplines:
1. verify with evidence-bearing signals
2. localize the failure at the right granularity
3. choose a repair whose dependency boundary is understood
4. treat the result as a new candidate state
5. revalidate every affected dependency
6. stop when recovery no longer makes structural progress
1. Start with the failure, not the repair
Consider:
CANDIDATE cand_v1
c1 Q2 revenue was $43.8 million.
c2 Second-half demand is expected to improve.
c3 Q3 revenue was approximately $46 million.
The admissible evidence contains:
Q2 revenue = $43.8 million
second-half outlook = improve
but no Q3 revenue value.
The correct verifier state is not:
c3 = FALSE
because the evidence does not establish that $46 million is false.
It is:
c3 = INSUFFICIENT_EVIDENCE
A deterministic reference controller used in this chapter produced:
cand_v1 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED',
'c3': 'INSUFFICIENT_EVIDENCE'
}
Two recovery strategies then behaved very differently.
Omission
cand_v1 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED',
'c3': 'INSUFFICIENT_EVIDENCE'
}
cand_v2 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED'
}
terminal=PERMIT
Hedging
cand_v1 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED',
'c3': 'INSUFFICIENT_EVIDENCE'
}
cand_v2 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED',
'c3': 'INSUFFICIENT_EVIDENCE'
}
cand_v3 {
'c1': 'SUPPORTED',
'c2': 'SUPPORTED',
'c3': 'INSUFFICIENT_EVIDENCE'
}
terminal=ABSTAIN reason=CYCLE_DETECTED
The second strategy changed the wording:
Q3 revenue was approximately $46 million.
into:
Q3 revenue may have been approximately $46 million.
The evidence state did not improve.
That is the first demonstration of the chapter’s main rule:
A successful edit is not a successful verification.
2. Verification is not self-confidence
Suppose we ask the generator:
Are you sure?
It may answer:
Yes. Based on the trend, approximately $46 million is reasonable.
Nothing has been verified.
We have sampled another output from the same generative process.
The useful distinction is:
SELF-ASSERTED CONFIDENCE
What does the model say about its own answer?
VERIFICATION
What external or mechanically grounded evidence
bears on the answer?
Strong verification signals can include:
authoritative retrieved evidence
database lookup
schema validation
compiler result
unit test
calculator
formal solver
runtime state
source provenance
human review
A second LLM judge may also contribute.
But it is not automatically independent merely because it has a different role name.
Useful questions include:
generator-independent?
model-family-independent?
source-lineage-independent?
mechanically checkable?
A 2024 critical survey of LLM self-correction found little general evidence for successful prompted intrinsic self-correction outside unusually favorable tasks, while reliable external feedback substantially improves the conditions under which correction works.[1]
So:
Do not confuse another generation with an external or mechanically grounded check.
3. Use a verification state model
Recovery becomes much safer when the verifier preserves why a claim did not pass.
A useful vocabulary is:
| State | Meaning |
|---|---|
SUPPORTED |
admissible evidence licenses the claim |
REFUTED |
admissible evidence contradicts the claim |
INSUFFICIENT_EVIDENCE |
current evidence cannot establish the claim |
CONFLICTING |
credible evidence disagrees |
UNRESOLVED |
verifier cannot determine the relation |
NOT_VERIFIABLE |
no available verification procedure can establish the claim |
This matters because the recovery action changes.
REFUTED
β correct or remove the proposition
INSUFFICIENT_EVIDENCE
β retrieve, narrow to supported content, omit, or abstain
CONFLICTING
β reconcile / verify sources
NOT_VERIFIABLE
β review / qualify / abstain according to policy
The Q3 case should therefore produce something like:
verification_record = {
"candidate_id": "cand_v1",
"claim_id": "c3",
"claim": "Q3 revenue was approximately $46 million.",
"state": "INSUFFICIENT_EVIDENCE",
"evidence_ids": ["filing_q1", "filing_q2"],
"missing_evidence": ["q3_revenue_value"],
"verification_method": "required_field_check",
"verifier_version": "financial-verifier-v4",
}
That is far more useful than:
BAD
because it constrains what a legitimate repair is allowed to do.
The recovery flow based on verification state is:
graph TD
V[Verification State] --> REF[REFUTED] --> COR[correct or remove the proposition]
V --> INS[INSUFFICIENT_EVIDENCE] --> RET[retrieve, narrow, omit, or abstain]
V --> CON[CONFLICTING] --> REC[reconcile / verify sources]
V --> UNV[NOT_VERIFIABLE] --> REV[review / qualify / abstain]
Repair is keyed to verification state because different epistemic failures require different recovery operations, not a single generic rewrite.
4. Verify the smallest unit that contains the failure β but no smaller
Claim-level verification is often ideal.
But not every failure is claim-local.
Consider:
c1: Drug X was associated with lower symptom scores.
c2: The study was observational.
c3: Therefore Drug X should be prescribed.
Each sentence can be individually grammatical and factual while the argument remains unjustified.
Or:
all individual claims = SUPPORTED
response-level omission = decisive adverse evidence absent
So the verification unit may be:
claim
claimβevidence edge
claim pair
argument
response
trajectory
The correct rule is:
Verify the smallest unit that contains the failureβbut no smaller.
The same principle determines whether a local repair is appropriate.
5. Choose the repair surface from demonstrated failure locality
Local repair is not inherently safer.
It is safer when:
failure is localized
dependencies are known
protected content remains valid
Then:
prefer local repair
But if the failure comes from:
false global premise
dense downstream dependence
broken argument structure
response-level omission
then a local sentence patch can preserve the real defect.
A practical decision rule is:
graph TD
LF[LOCAL FAILURE] --> KD[KNOWN DEPENDENCIES] --> LP[local patch / omission / rebind]
GF[GLOBAL PREMISE FAILURE] --> LR[larger-region rebuild / full regeneration / review]
UF[UNKNOWN DEPENDENCY BOUNDARY] --> LR
Repair scope should therefore be selected from the verified failure record, not from a general preference for small edits.
6. Measure both surface and dependency blast radius
The original repair-blast-radius idea remains useful:
claims
sentences
structured fields
code hunks
But textual change is not the whole risk.
Changing one token:
did
β
did not
may invalidate:
polarity
support
summary conclusion
recommendation
policy decision
So define a second quantity:
low surface blast radius
high dependency blast radius
or the reverse.
For reliability, the second often matters more.
7. Repair operations are different types
A recovery controller should distinguish at least:
| Repair type | What changes |
|---|---|
| Evidence repair | evidence snapshot |
| Candidate patch | localized proposition/text |
| Decomposition repair | claim granularity |
| Attribution repair | source binding |
| Structural repair | role, polarity, quantity, time |
| Scope repair | strength or domain of assertion |
| Omission | unsupported content removed |
| Full regeneration | whole candidate rebuilt |
REFINE is a policy route (Chapter 12). Repair is the operation that route executes. One route can map to several repair types.
The policy route provides a useful starting map:
RETRIEVE
β evidence repair
VERIFY
β resolve evidence / source / relation state
REFINE
β candidate / structure / scope repair
REJECT_CANDIDATE
β discard version
ABSTAIN
β stop asserting
But the recovery operator still needs a contract describing exactly what it may alter.
8. Retrieval changes the evidence snapshot, not truth
Suppose policy returns:
HOLD + RETRIEVE
The system retrieves a new document.
That does not repair the candidate automatically.
The new material must itself pass:
source admissibility
freshness
provenance
relevance
conflict checks
Then create:
evidence_snapshot_v2
and invalidate every measurement that depended on evidence_snapshot_v1.
That can include:
support checks
provenance checks
conflict checks
freshness checks
containment geometry
downstream policy decision
The safe sequence is:
graph LR
CV[candidate_v1] --> EG[evidence gap] --> RET[retrieve]
RET --> VE[validate evidence] --> ES[evidence_snapshot_v2]
ES --> IM[invalidate dependent measurements] --> RV[re-verify candidate_v1]
New evidence cannot simply be appended to the old verdict; it creates a new evidence snapshot that forces dependent measurements to be checked again.
New evidence can even make previously accepted claims less secure by revealing:
contradiction
newer information
source conflict
scope limitation
Corrective RAG is relevant here because it explicitly evaluates retrieval quality and triggers corrective retrieval behavior rather than treating initial retrieval as automatically adequate.[3]
9. Omission is a repair only if the remaining response stays sound
Sometimes the strongest repair is deletion.
If no evidence establishes Q3 revenue:
Q3 revenue may have been around $46 million.
is not a repair.
It is the same unsupported proposition under weaker rhetoric.
Qualification does not convert an unsupported fact into a supported fact.
But deletion can create another class of failure.
Consider:
Revenue grew.
However, margins shrank.
This was due to inflation. [REMOVE]
Therefore, we must cut costs.
Deleting the third sentence can leave:
Therefore
without a valid premise.
Likewise, removing a sentence may create:
dangling pronoun
broken causal link
missing caveat
misleading partial presentation
So omission requires a cohesion and salvage-integrity pass.
A partial answer is valid only if the retained content remains:
grammatically coherent
referentially closed
logically coherent
not materially misleading through omission
This may require a surface-realization edit after factual deletion.
That edit creates a new candidate state too.
10. Partial salvage needs dependency closure
Suppose the candidate contains claims:
every retained critical claim is authorized
response-level obligations remain satisfied
cohesion constraints hold
But claims may depend on each other.
Let:
Then the retained set must satisfy dependency closure.
This prevents a superficially factual partial answer from becoming misleading because a required premise, adverse caveat, or qualification was removed.
The objective is therefore not:
retain the most sentences
but:
maximize verified retained utility subject to authorization and coherence.
11. Repair contracts should contain executable invariants
A repair contract can be typed as:
repair_contract = {
"target_claim_ids": ["c3"],
"allowed_operations": [
"OMIT_CLAIM",
"REPLACE_WITH_EVIDENCE",
"NARROW_TO_SUPPORTED_SCOPE",
],
"protected_claim_ids": ["c1", "c2"],
"invariants": [
"company_id(child) == company_id(parent)",
"reporting_period(child) == reporting_period(parent)",
"currency(child) == currency(parent)",
"all_protected_claims_remain_supported(child)",
],
"must_not_add": [
"new_unverified_financial_values",
],
"max_surface_blast_radius": 0.33,
}
The phrase:
narrow scope
needs precision.
This is legitimate:
Q3 revenue was $46 million.
β
The supplied evidence establishes Q2 revenue at $43.8 million,
but does not establish Q3 revenue.
This is not:
Q3 revenue may have been $46 million.
The first reduces the assertion to what the evidence licenses.
The second merely hedges an unsupported proposition.
12. Every repair creates a new candidate state
This is the chapter’s canonical wording.
A deletion may shrink the assertion surface.
A citation correction may not introduce a new factual proposition.
A deterministic patch may change only one structured field.
Yet all create a new state:
cand_v1
β
cand_v2
and trust attaches to the versioned state, not to the lineage as a whole.
So:
A repair record should preserve provenance:
repair_record = {
"candidate_id": "cand_v2",
"parent_candidate_id": "cand_v1",
"parent_verification_record": "verify_1842",
"repair_action": "OMIT_CLAIM",
"changed_claim_ids": ["c3"],
"evidence_snapshot_uri": "cas://evidence/7f...",
"evidence_snapshot_hash": "sha256:...",
"repair_model": "generator-v17",
"repair_prompt_version": "repair-v5",
}
The hash proves integrity.
The immutable snapshot or content-addressed URI makes replay possible.
13. Dependency-aware remeasurement is an invalidation problem
A repair controller should think like an incremental build system.
Suppose:
dependencies = {
"c3": [
"polarity_check",
"support_check",
"summary_conclusion",
"response_cohesion",
"policy_decision",
],
}
Editing c3 invalidates those checks.
A cache key should conceptually include:
subject/candidate-component hash
evidence snapshot hash
detector version
detector configuration
calibration version where relevant
For example:
measurement_key = (
claim_hash,
evidence_hash,
verifier_version,
verifier_config,
)
A cached measurement may be reused only when all of its dependencies are unchanged.
Policy is always recomputed because the reliability record itself may have changed.
14. Repair-induced regression is the Whac-A-Mole failure
A repair can fix one problem and create another.
ORIGINAL
Company A acquired Company B in March 2024.
Suppose only the date is wrong.
A careless patch produces:
Company B acquired Company A in April 2024.
The date has improved.
The relation has regressed.
This is the familiar Whac-A-Mole pattern of generative repair.
Define the set of previously passing properties on candidate \(c_i\) as:
A malformed patch should not be mistaken for evidence about the same failure mechanism.
And do not use generic embedding similarity as the preservation oracle.
A relation reversal can remain semantically similar.
Protected-content checks should preserve:
claim identity
roles
polarity
quantities
time
scope
declared invariants
15. External feedback and critics are themselves fallible sensors
The correction loop has two hard tasks:
1. identify what is wrong
2. produce a better candidate
The first is often the bottleneck.
The TACL self-correction survey emphasizes the importance of reliable feedback.[1]
CRITIC demonstrates a tool-interactive pattern in which external tools provide feedback used for revision rather than relying only on introspection.[2]
RePAIR starts from a related problem: agentic RAG systems can rely on critic categories or correction plans that are themselves wrong, and it instead learns response-to-action mappings without requiring an explicit fine-grained taxonomy.[5]
The lesson is not:
typed failure states are useless.
It is:
A component does not become an oracle because we call it a critic.
Evaluate critics with:
failure-localization precision
failure-localization recall
false repair-trigger rate
correct recovery-action rate
Self-RAG provides another useful contrast: retrieval, generation, and learned reflection signals can be integrated into one trained model.[6]
That can improve behavior.
It does not remove the architectural question:
Which signal is allowed to authorize the repaired candidate?
Reflection remains evidence for a decision, not authorization by itself.
16. Full regeneration needs a taint boundary
Sometimes the entire argument is built on a false premise.
Then local repair is inappropriate.
Use:
repair_mode = FULL_REGENERATION
blast_radius = WHOLE_CANDIDATE
But do not feed the failed answer back as unquestioned factual context. Give it a typed record, the same shape Chapter 14 uses for memory, so the boundary travels with it:
tainted_context = {
"candidate_id": "cand_v3",
"origin": "FAILED_CANDIDATE",
"verification_state": "REFUTED", # or INSUFFICIENT_EVIDENCE
"allowed_uses": [
"FAILURE_LOCALIZATION",
"USER_INTENT_RECONSTRUCTION",
"STYLE_CONSTRAINT",
"PROTECTED_STRUCTURE",
],
"forbidden_uses": [
"FACTUAL_EVIDENCE",
"SOURCE_AUTHORITY",
"PROPOSITION_SEED",
],
"parent_verification_record": "verify_1842",
}
origin = FAILED_CANDIDATE is not an authoritative external source and not an authorized derived artifact β the lineage classes from Section 21. The regeneration step reads allowed_uses; a step that tries to consume the failed candidate as FACTUAL_EVIDENCE fails the same check a memory read would (Chapter 14).
A safer regeneration request is:
Generate a new answer from the verified evidence package.
The previous candidate is available only as a record of failures
and user-intent constraints.
Do not treat its factual assertions as evidence.
After regeneration:
new candidate
β full affected measurement bundle
β policy
No inherited trust.
17. A bounded recovery controller needs budgets, progress, and cycle detection
Attempt count is only one resource.
A real recovery budget may include:
max_repair_attempts
max_retrieval_queries
max_verifier_calls
max_critic_tokens
max_wall_clock_latency
max_monetary_cost
max_human_escalations
The controller should also detect repeated states.
For example, store:
candidate_hash
verification_state_vector
repair_action
and stop if the same candidate/failure state reappears.
Repeated state is evidence that the current recovery strategy has stopped learning anything.
The reference controller in this chapter detects exactly that.
The hedge repair repeatedly changes rhetoric without changing evidence status, producing:
terminal=ABSTAIN reason=CYCLE_DETECTED
Progress should not be one weighted “quality” score.
Use structural progress such as:
hard blockers decreased?
critical unresolved claims decreased?
repair regressions stayed zero?
evidence completeness increased?
policy state moved toward PERMIT?
verified retained utility increased?
One conceptual progress vector is:
The principle is not:
keep trying while score rises
but:
continue only while a declared reliability dimension is genuinely improving.
The recovery loop with budgets and cycle detection:
graph TD
START[start] --> VER[verify candidate]
VER --> ALL{all claims SUPPORTED?}
ALL -- yes --> PERMIT[PERMIT]
ALL -- no --> SIG[compute signature]
SIG --> SEEN{signature seen?}
SEEN -- yes --> ABSTAIN[ABSTAIN: CYCLE_DETECTED]
SEEN -- no --> BUDGET{repair budget left?}
BUDGET -- no --> ABSTAIN2[ABSTAIN: BUDGET_EXHAUSTED]
BUDGET -- yes --> REPAIR[apply repair operation]
REPAIR --> VER
The loop permits repair only while it can produce a new verification state; repeated signatures and exhausted budgets terminate in abstention instead of endless revision.
18. A small deterministic recovery controller
Reference environment
Environment: Python 3.13
Dependencies: Python standard library only
Canonical implementation: experiments/hallucination/recovery_demo.py
Run it with:
python experiments/hallucination/recovery_demo.py
The core controller is intentionally small:
from dataclasses import dataclass
from enum import Enum
import hashlib
class V(str, Enum):
SUPPORTED = "SUPPORTED"
INSUFFICIENT_EVIDENCE = "INSUFFICIENT_EVIDENCE"
@dataclass(frozen=True)
class Claim:
id: str
text: str
requirement: str
@dataclass
class Candidate:
id: str
parent: str | None
claims: list[Claim]
authorized: bool = False
def verify(candidate, evidence):
return {
c.id: (
V.SUPPORTED
if c.requirement in evidence
else V.INSUFFICIENT_EVIDENCE
)
for c in candidate.claims
}
def signature(candidate, states):
body = "|".join(f"{c.id}:{c.text}" for c in candidate.claims)
h = hashlib.sha256(body.encode()).hexdigest()[:12]
return h, tuple(sorted((k, v.value) for k, v in states.items()))
The loop then, in outline:
while True:
states = verify(current, evidence)
if all(v == V.SUPPORTED for v in states.values()):
current.authorized = True
return "PERMIT", current
sig = signature(current, states)
if sig in seen:
return "ABSTAIN:CYCLE_DETECTED", current
if repairs >= max_repairs:
return "ABSTAIN:REPAIR_BUDGET_EXHAUSTED", current
if verifier_calls >= max_verifier_calls:
return "REVIEW:CRITIC_BUDGET_EXHAUSTED", current
seen.add(sig)
current = REPAIRS[mode](current, states) # a new candidate; no inherited authorization
Two repair modes exercise the loop.
omission removes every claim the verifier could not support. The omission trace is:
cand_v1 {'c1': 'SUPPORTED', 'c2': 'SUPPORTED', 'c3': 'INSUFFICIENT_EVIDENCE'}
cand_v2 {'c1': 'SUPPORTED', 'c2': 'SUPPORTED'}
terminal=PERMIT
hedge softens the wording of the unsupported claim without adding evidence. The second hedge is idempotent, so the candidate and its verification state repeat, and cycle detection fires:
cand_v1 {'c1': 'SUPPORTED', 'c2': 'SUPPORTED', 'c3': 'INSUFFICIENT_EVIDENCE'}
cand_v2 {'c1': 'SUPPORTED', 'c2': 'SUPPORTED', 'c3': 'INSUFFICIENT_EVIDENCE'}
cand_v3 {'c1': 'SUPPORTED', 'c2': 'SUPPORTED', 'c3': 'INSUFFICIENT_EVIDENCE'}
terminal=ABSTAIN reason=CYCLE_DETECTED
The controller also rejects an undeclared repair mode before any repair runs:
--- mode=guess ---
ValueError: unknown repair mode: 'guess'
This demonstration proves controller invariants under a perfect structured oracle.
It does not establish the accuracy of a real-world verifier or repair model.
Those require separate evaluation.
19. Human review should receive the failed recovery path, not only the final text
When policy routes to:
REVIEW
the human reviewer should not receive only:
cand_v3
They need a review package:
original candidate
current candidate
diff
target failed claim
verification state
evidence used
repair attempts
new failures introduced
budget reason
policy reason
For example:
review_package = {
"candidate": "cand_v3",
"parent_chain": ["cand_v1", "cand_v2"],
"target_failure": "INSUFFICIENT_Q3_REVENUE",
"attempts": [
"HEDGE_CLAIM",
"HEDGE_CLAIM",
],
"terminal_reason": "CYCLE_DETECTED",
"evidence_snapshot": "cas://evidence/7f...",
}
The human is then resolving a diagnosed reliability problem rather than reconstructing the entire history manually.
20. The recovery benchmark should decompose the bottleneck
A minimum benchmark should report:
| Dimension | Metrics |
|---|---|
| Verification | localization precision/recall, false repair triggers |
| Repair | targeted fix rate, RIR, new unsupported claims |
| Preservation | protected invariants, dependency regressions, cohesion |
| Efficiency | surface/dependency blast radius, steps, budget exhaustion |
| Routing | correct recovery operation, unnecessary regeneration/review |
| System | final authorized coverage, latency, retrieval/verifier cost |
Add two critical baselines.
No-repair baseline
What happens if the system:
omits
abstains
or rejects
without running a generative repair stage?
Oracle-repair baseline
What would happen with:
perfect localization
perfect gold repair
These decompose:
verification bottleneck
vs
repair-generation bottleneck.
And preserve Chapter 7’s held-out discipline:
known repair regression suite
held-out same-mechanism suite
novel-failure recovery set
Once a repair case enters the regression suite, repeatedly fixing that exact case is not evidence of general recovery ability.
21. Repair candidates are ephemeral until authorized
This is the bridge to the next chapter and should already be an invariant here.
A candidate under repair must not be written into a persistent evidence store merely because it exists.
cand_v1 HOLD
cand_v2 HOLD
cand_v3 HOLD
are ephemeral working states.
Only an explicitly authorized artifact may cross the persistence boundary.
Otherwise the recovery system can manufacture its own future evidence:
unsupported candidate
β persisted
β indexed
β retrieved during repair
β appears independent
β "verifies" descendant candidate
That is circular contamination.
Evidence snapshots therefore need lineage that distinguishes:
authoritative external source
authorized derived artifact
unverified model output
and repair candidates must never silently cross between those classes.
22. Using AI: ask for a bounded patch, then distrust the patch
If an LLM acts as the repair operator, constrain its task.
A weak instruction is:
Improve this answer and make it more accurate.
A stronger contract is:
The verifier identified exactly one failed claim: c3.
Verification state:
INSUFFICIENT_EVIDENCE
Available evidence:
- c1 SUPPORTED by source_1
- c2 SUPPORTED by source_2
- no admissible Q3 revenue value exists
Allowed operations:
- omit c3
- replace c3 only if a supplied source directly supports replacement
Protected claims:
- c1
- c2
Forbidden:
- new financial values
- changes to company identity
- changes to reporting period
Return:
1. repaired answer
2. changed claim IDs
3. operation used
A characteristic bad repair would be:
Q3 revenue may have been approximately $45.8 million.
That may sound cautious.
The verifier should still return:
INSUFFICIENT_EVIDENCE
The surrounding system owns the truth conditions.
After the patch:
Run the verifier again rather than trusting the repair model’s declaration that it succeeded.
23. What you should now be able to answer
After this chapter, you should be able to explain:
- Why every repair creates a new candidate state even when the assertion surface shrinks.
- The difference between
REFUTEDandINSUFFICIENT_EVIDENCE. - Why external or mechanically grounded feedback is different from another model completion.
- Why repair granularity should match the smallest verified failure boundary.
- The difference between surface blast radius and dependency blast radius.
- Why omission requires cohesion and salvage-integrity checks.
- Why new retrieval invalidates all evidence-dependent measurements.
- Why a repaired candidate cannot inherit authorization.
- How repair-induced regression and cycle detection expose failed recovery loops.
- Why repair candidates must remain ephemeral until explicitly authorized.
Worked question β Why is deletion often safer than hedging?
Suppose the evidence does not contain Q3 revenue.
The original claim is:
Q3 revenue was $46 million.
Changing it to:
Q3 revenue may have been $46 million.
changes the rhetoric but does not add evidence for the underlying Q3 value.
If the verification contract requires an admissible source for reported revenue, both claims remain:
INSUFFICIENT_EVIDENCE.
Deletion removes the unsupported assertion.
But deletion is authorized only after the remaining response passes cohesion, dependency, and policy checks.
So the correct rule is not:
delete whenever uncertain.
It is:
remove unsupported material
when doing so preserves the obligations of the remaining response.
This is the deletion side of conformal factuality (Chapter 6 Β§9). Mohri and Hashimoto derive a guarantee by backing a generation off β removing or generalizing claims β until the surviving text clears a factuality bound.[7] Hedging a claim does not shrink the entailment set it commits to; deleting it does.
24. Exercises
Exercise 1 β Local versus global repair
Create a five-claim answer with one localized unsupported claim.
Compare:
local omission
local evidence-backed patch
whole-answer regeneration
Report:
surface blast radius
dependency blast radius
target repair success
new regressions
Exercise 2 β Distinguish evidence states
Create examples for:
REFUTED
INSUFFICIENT_EVIDENCE
CONFLICTING
UNRESOLVED
Specify the correct recovery route for each.
Exercise 3 β Repair-induced regression
Start with:
Company A acquired Company B in March 2024.
where only the date is wrong.
Repair the date and verify that:
subject
object
polarity
quantity
remain unchanged.
Compute candidate-level RSI.
Exercise 4 β Dependency invalidation
Create a dependency graph for:
claim
support
summary
recommendation
policy
Edit one claim and identify which cached measurements remain valid.
Exercise 5 β Cycle detection
Implement two repair operators that oscillate between two candidate states.
Confirm that:
(candidate_hash, verification_state)
cycle detection terminates the loop before the general attempt budget.
Exercise 6 β Partial salvage integrity
Create an answer where deleting one unsupported claim leaves a dangling:
therefore
however
this
it
Repair the cohesion without adding new factual assertions.
Re-run verification afterward.
25. The deeper lesson
The naive repair loop is:
model makes mistake
β tell model it made a mistake
β model says something else
β trust the new answer
That is not a reliability architecture.
A reliable recovery loop is:
graph TD
CS[candidate state] --> EB[evidence-bearing verification]
EB --> LD[localized diagnosis]
LD --> RC[repair contract]
RC --> BR[bounded repair]
BR --> NCS[new candidate state]
NCS --> DI[dependency invalidation]
DI --> RM[re-measurement]
RM --> REG[regression check]
REG --> POL[policy]
The system continues only while recovery makes real structural progress.
If it does not, the correct output may be:
omit
review
abstain
reject
That is not the system giving up.
It is the system refusing to turn repair effort into unjustified commitment.
A repaired claim is still a claim.
It still needs evidence.
It still needs structural fidelity.
It still needs provenance.
It still needs epistemic adequacy.
It still needs policy authorization.
And until it receives that authorization, it remains transient working stateβnot tomorrow’s evidence.
That final distinction leads directly to the next problem.
Research roots
-
Ryo Kamoi, Yusen Zhang, Nan Zhang, Jiawei Han and Rui Zhang, “When Can LLMs Actually Correct Their Own Mistakes? A Critical Survey of Self-Correction of LLMs,” Transactions of the Association for Computational Linguistics 12, 1417β1440, 2024. Finds weak general evidence for intrinsic prompted self-correction, identifies feedback generation as a major bottleneck, and reports stronger correction behavior when reliable external feedback is available. https://aclanthology.org/2024.tacl-1.78/
-
Zhibin Gou, Zhihong Shao, Yeyun Gong, Yelong Shen, Yujiu Yang, Nan Duan and Weizhu Chen, “CRITIC: Large Language Models Can Self-Correct with Tool-Interactive Critiquing,” ICLR 2024. Uses external tools to evaluate aspects of generated outputs and feeds tool results back into iterative revision. https://www.microsoft.com/en-us/research/publication/critic-large-language-models-can-self-correct-with-tool-interactive-critiquing/
-
Shi-Qi Yan, Jia-Chen Gu, Yun Zhu and Zhen-Hua Ling, “Corrective Retrieval Augmented Generation,” arXiv:2401.15884, 2024. Adds retrieval evaluation and corrective retrieval, including web search and decompose-then-recompose processing, rather than assuming the initial retrieved corpus is sufficient. https://arxiv.org/abs/2401.15884
-
Luyu Gao, Zhuyun Dai, Panupong Pasupat, Anthony Chen, Arun Tejasvi Chaganty, Yicheng Fan, Vincent Zhao, Ni Lao, Hongrae Lee, Da-Cheng Juan and Kelvin Guu, “RARR: Researching and Revising What Language Models Say, Using Language Models,” ACL 2023. Retrieves attribution for generated text and post-edits unsupported content while explicitly trying to preserve unaffected material. https://aclanthology.org/2023.acl-long.910/
-
Gongbo Zhang, Yifan Peng and Chunhua Weng, “Improving Retrieval-Augmented Generation without Taxonomy-based Error Categorization,” ACL 2026, pp. 155β165. Introduces RePAIR, motivated partly by unreliable critic categorization and ineffective correction, and learns response-to-action plans for flawed RAG outputs. https://aclanthology.org/2026.acl-short.14/
-
Akari Asai, Zeqiu Wu, Yizhong Wang, Avi Sil and Hannaneh Hajishirzi, “Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection,” ICLR 2024. Integrates adaptive retrieval, generation and learned reflection signals into one model, providing a useful contrast to externally separated verification architectures. https://proceedings.iclr.cc/paper_files/paper/2024/hash/25f7be9694d7b32d5cc670927b8091e1-Abstract-Conference.html
-
Christopher Mohri and Tatsunori Hashimoto, “Language Models with Conformal Factuality Guarantees,” ICML 2024. Derives a factuality guarantee by backing a generation off β removing or generalizing claims β until the surviving text clears a conformal bound. https://proceedings.mlr.press/v235/mohri24a.html
Next: The Memory Contamination Problem
Chapter 13 keeps untrusted repair states inside a bounded loop.
But production systems also write state.
They create:
conversation memory
user profiles
agent scratchpads
vector-store documents
summaries
knowledge-graph facts
database rows
tickets
reports
future prompts
training examples
Now imagine an unverified candidate crossing that persistence boundary.
On the next run, the system may retrieve its own output as evidence.
Then the failure changes form:
hallucination
β persistent assertion
β retrieved context
β apparent evidence
β reinforced hallucination
The next chapter asks:
How do we stop an unverified output from becoming tomorrow’s evidence?