The first answer was fluent and wrong
K81R's polished mistake turned retrieval, evidence lineage, answerability, and refusal into core product behavior.
K81R's first impressive answer was wrong in complete sentences.
I asked which retry policy Z29C used for an adapter that offered neither idempotency nor a status query. The prototype searched the project archive, retrieved several passages, and answered that Z29C attempted three retries with exponential backoff before sending the workflow to manual review.
It cited a retry-strategy note and an adapter contract. The wording was specific. The structure was clean. The conclusion was conventional.
Z29C's current decision said the opposite. If a request could have been accepted and no evidence path existed, the workflow entered outcome-unknown. It did not retry automatically.
The model had combined a superseded early note, a generic retry passage, and its own common pattern into a coherent false description of my project.
Fluency had hidden a systems failure.
The prototype rewarded completion
K81R's first path was familiar:
- Split documents into fixed-size chunks.
- Embed the chunks.
- Retrieve the nearest few to a question.
- Put them in a prompt.
- Ask for an answer with citations.
- Stream the text into a chat transcript.
Every stage optimized for producing something. No stage decided whether the evidence was sufficient, current, mutually consistent, or permitted to support the requested claim.
The final prompt said to use only the context and admit uncertainty. That instruction was useful and unable to repair missing system structure.
I stopped changing the prompt and reconstructed the failure from ingestion onward.
The wrong answer had several causes
The answer was not one model hallucination isolated at the final step.
The fixed-size chunker separated the current decision's critical exception from the paragraph defining adapter capability. Vector retrieval ranked a semantically broad retry note above an exact state definition. The superseded note had no machine-readable status. The candidate limit excluded one relevant passage. The generator received contradictory fragments without their heading and date relationships. The citation renderer linked whichever source IDs the response named.
Any one improvement could make the demonstration pass and leave the architecture fragile.
I classified the failure chain:
- Ingestion: authored structure and relationships were lost.
- Retrieval: exact terms and current authority ranked poorly.
- Selection: the evidence set omitted a necessary premise.
- Answerability: the system never asked whether the set supported an answer.
- Generation: the model filled the gap with a plausible convention.
- Citation: source presence was mistaken for claim support.
- Interface: fluent text appeared before evidence could be inspected.
The answer made all seven failures look like one paragraph.
K81R indexed case-study drafts, decision records, release notes, incident evidence, and technical references. Their status differed.
I added document-level metadata:
- Stable document identity and immutable revision.
- Authored date and effective period.
- Current, draft, superseded, historical, or withdrawn status.
- Supersedes and amended-by relationships.
- Project and document type.
- Source collection and corpus revision.
- Access policy and retention class.
The old three-retry note remained searchable for historical questions. It could not silently support “What does Z29C do?” when a later current decision superseded it.
Authority was not reduced to recency. A newer brainstorming note did not outrank an older adopted contract. Status and relationships expressed how the archive governed the document.
Parsing preserved authored structure
The first chunker sliced a token window with overlap. It could begin inside a list, detach code from its explanation, or put a heading in the previous chunk.
I replaced it with a structure-aware parser. It recorded heading lineage, paragraphs, lists, tables, code blocks, callouts, and source offsets. Passage construction followed semantic units first and size limits second.
If a paragraph's meaning depended on the adjacent capability table, the retrieval unit referenced both or the evidence builder expanded to the enclosing section. Code blocks remained intact. Table headers accompanied selected rows. Long sections split at paragraph boundaries and retained the full heading path.
The current retry decision now arrived as:
Z29C
Recovery policy
Adapters without idempotency or status lookupThe context told the model and the reviewer what kind of claim the passage could support.
Vector search understood the conceptual relationship between timeouts and retries. It did not reliably preserve outcome-unknown, adapter_no_query_v2, or exact contract versions.
I added a field-aware lexical index for titles, headings, code, paths, identifiers, and body text. Exact and quoted queries retained punctuation where meaningful. Semantic retrieval remained valuable for paraphrases and vocabulary changes across years.
The two systems produced candidate ranks with different score semantics. I did not add raw scores. A later rank-fusion stage combined positions while retaining the retrieval reasons.
The authoritative state definition surfaced through exact heading and code matches. Related conceptual passages still broadened the result set.
A strong answer system needed both identity and meaning.
Before another generation attempt, I built a source-first result page.
Each result displayed document status, date, revision, heading lineage, exact passage, surrounding context, retrieval reason, and relationship to current decisions. A person could open the immutable source revision and inspect related documents.
This page answered many archive questions without generation. It also made retrieval failures obvious. If the current Z29C policy was absent, no polished answer could conceal that fact.
I created a retrieval evaluation set with literal identifiers, conceptual paraphrases, superseded distractors, structural tables, permission boundaries, and no-answer questions. Relevant evidence needed to appear within a scan-sized result set with enough context to judge it.
Answer quality no longer served as a proxy for search quality.
The evidence set became a product object
The original pipeline passed an invisible top-k list directly to the model. I made selection explicit.
An evidence set stored:
- Set identity and revision.
- Question and effective corpus scope.
- Selected source revisions and exact spans.
- Heading and structural context.
- Retrieval query and index generation.
- Selection reason and order.
- Contradictions or missing relationships noted during review.
The interface let me add, remove, expand, and compare passages. The set could be saved beside a decision or shared as a reading list without generating an answer.
Generation consumed one immutable evidence-set revision. Changing the sources created another revision; it did not silently change an existing answer.
The model's context window became a reviewable input artifact rather than an invisible bag.
The first prototype always answered. K81R needed a separate decision: does this evidence set entitle the system to answer this question?
I defined answerability dimensions:
- Coverage: Are the necessary entities, conditions, and requested time present?
- Authority: Are supporting documents current and appropriate to the claim?
- Agreement: Do sources conflict or describe different scopes?
- Specificity: Is the question narrower or broader than the evidence?
- Permission: Can every necessary source be used for this requester and output?
- Freshness: Does the index and evidence set cover the relevant corpus revision?
Some checks were deterministic. A current-policy question could not rely only on superseded documents. A required adapter capability absent from the evidence triggered insufficiency. Other judgments remained reviewable heuristics.
The answerability result listed evidence and gaps. It did not become a magic confidence number.
Refusal needed to preserve progress
“I don't know” would have been safer than the first answer and a poor research interface.
For the Z29C question, a useful refusal could say:
The selected passages establish that timeouts may produce an unknown outcome, but they do not identify whether this adapter supports idempotency or status lookup. I cannot determine the retry policy without that capability contract.
The page showed the supporting passage, missing relationship, and narrower searches for the adapter contract. A person could revise the evidence set and rerun answerability.
Other refusal shapes handled conflicting current documents, historical-only evidence, inaccessible required sources, and questions outside the corpus.
Refusal became a structured research result, not a conversational dead end.
Citations were attached too late
The prototype generated prose and then asked the model to associate source identifiers. The resulting citations were near the right topic and not necessarily supportive.
I changed the generation format to produce bounded claim objects:
claim_id
claim_text
evidence_unit_ids
claim_type
uncertaintyThe renderer accepted only evidence IDs present in the selected set. It validated source existence, revision, access, and span. Each claim appeared with its evidence rather than streaming as a sentence first and attaching links later.
This still did not prove entailment. A passage could mention exponential backoff in a different condition. Claim verification needed its own evaluation and, for consequential use, human review.
Citation validity became necessary and explicitly insufficient.
I wrote claim-support counterexamples
The evaluation included source pairs designed to fool topic matching:
- “Retry three times” for a safe idempotent adapter beside “do not retry” for an adapter without status lookup.
- A current P6X4 write-fence procedure beside a historical dual-write proposal.
- Search projection freshness beside document-authority freshness.
- A code sample using
workflow_callbeside a note discussing it conceptually. - A source saying a feature was considered beside one saying it was adopted.
A citation scorer that only checked shared terms passed these examples. Human reviewers did not.
I annotated whether a passage supported, contradicted, contextualized, or merely mentioned each claim. Automated checks could catch missing IDs and obvious contradictions; nuanced entailment remained a measured limitation.
The difficult cases became permanent fixtures rather than inconvenient exceptions.
Permissions applied before candidates existed
Filtering citations after generation was too late. Restricted passages could influence the answer without being named.
K81R constructed an authorized corpus scope before lexical or semantic retrieval. Facets, query suggestions, caches, and candidate generation used the same scope. A source passed through current access validation again when opened or selected.
The evaluation contained near-identical public and restricted fixtures. An unauthorized query could not see the restricted title, suggestion, result count, embedding neighbor, passage, or generated fact.
Evidence records stored the access decision revision that admitted each source. If policy changed, an old answer did not become newly authorized. The viewer revalidated access and could redact unavailable evidence while preserving the immutable record's existence.
The prompt was never the security boundary.
Changing parser, chunking, lexical analyzer, embedding model, or fusion method changed which passages a query produced.
Each active index generation recorded:
- Source corpus revision.
- Parser and structure-extraction version.
- Passage construction policy.
- Lexical analyzer and schema.
- Embedding model identifier and dimensions.
- Fusion and ranking configuration.
- Build time and failed-source inventory.
An answer linked to the generation that produced its candidate and evidence set. A later viewer could rerun the question against a newer generation and compare rather than rewriting history.
Provenance included the retrieval machine, not only the final documents.
The answer record was immutable
The chat transcript stored messages and whatever UI state happened to render them. K81R needed a record that could be inspected later.
An answer record included:
- Exact question and task classification.
- Corpus scope and index generation.
- Evidence-set revision.
- Answerability decision and reasons.
- Model, parameters, and prompt revision.
- Generated claim objects.
- Claim-verification results.
- Review status and accepted use, if any.
Corrections created a new answer or review annotation. They did not mutate the original response into something it had never said.
The wording might not be reproducible under stochastic generation. The inputs, evidence, configuration, and output remained inspectable.
The first interface displayed tokens as they arrived. A confident sentence appeared before its citation object and before the system knew whether the cited passage supported it.
I experimented with buffering at claim boundaries. The model could generate internally, but the interface revealed a claim only after it had parseable evidence references and passed deterministic validation. Unsupported claims went into a review state rather than flashing briefly as authoritative text.
This added latency to the first visible prose. The evidence set remained available immediately, so the page never looked empty. The result arrived in meaningful units instead of character theater.
The interface optimized time to inspectable claim, not time to first token.
One score concealed the failure chain
The original evaluation marked an answer correct or incorrect. The retry response was incorrect, but that label did not tell me what to repair.
I reported stages separately:
- Ingestion structure integrity.
- Retrieval recall and rank.
- Authority and permission filtering.
- Evidence selection coverage.
- Answerability and refusal decision.
- Claim generation accuracy.
- Citation validity and support.
- End-to-end reviewer usefulness.
A model change could improve wording while retrieval regressed. A chunking change could improve recall and break citation spans. A strict refusal rule could reduce false answers and make answerable cases frustrating.
The stage report preserved tradeoffs and failure location.
I did not claim a general question-answering system from one personal archive. The evaluation set focused on K81R's real traps:
- Historical versus current decisions.
- Exact technical identifiers.
- Conditions separated across structured content.
- Similar topics with different authorities.
- Questions requiring two evidence relationships.
- Missing answers.
- Permission-sensitive sources.
- Claims that should remain uncertain.
Each case included acceptable evidence, misleading distractors, required claims, prohibited claims, and useful refusal criteria. The set grew from observed failures and was reviewed for duplicated lessons.
The benchmark was a regression instrument for this product, not a universal intelligence score.
Human review was a state, not a disclaimer
Adding “AI can make mistakes” below the answer did not show whether this answer had been reviewed.
K81R displayed explicit states:
- Draft generated.
- Evidence checks passed.
- Claim support requires review.
- Reviewed with annotations.
- Accepted into a named decision or document revision.
- Superseded by a later answer.
Acceptance recorded reviewer action and destination. It did not convert the model into an author of authority. The maintained document or decision remained the source.
This state model made a reviewed answer visibly different from fresh generation.
The retry case passed only after the system could refuse
With the current Z29C decision and adapter contract selected, K81R could answer:
Z29C does not retry automatically when the adapter lacks both idempotency and reliable status lookup. A timeout enters
outcome-unknownbecause the external request may already have been accepted.
Each claim linked to the exact current passage. The older three-retry note appeared as superseded historical context.
When I removed the adapter contract from the evidence set, the system refused and named the missing capability. When I changed permission scope to exclude the current decision, it did not use the restricted fact. When I supplied conflicting current fixtures, it presented the disagreement.
Passing meant more than producing the expected sentence. It meant behaving coherently as evidence changed.
Better generation was not the main breakthrough
I could have tried another model or a more elaborate prompt and obtained the right answer on the original question. That would have made the demonstration better and the system no easier to trust.
K81R improved through surrounding structure:
- Authored parsing preserved meaning.
- Hybrid retrieval protected exact and conceptual search.
- Authority metadata distinguished current from historical.
- Evidence sets made context visible.
- Answerability made insufficiency actionable.
- Permission filtering constrained the corpus early.
- Claim records connected prose to sources.
- Evaluation isolated failure stages.
- Immutable records preserved what actually happened.
The model still mattered. It no longer carried responsibilities the product could enforce more reliably.
The first answer looked finished because prose hides seams. It concealed where the source ended, where inference began, which document was current, and which condition had never been retrieved.
The redesigned interface made those seams visible before asking anyone to trust the conclusion. A person could end at search results, save an evidence set, receive a useful refusal, or inspect claim support. Generation became one optional transformation within that workflow.
The wrong answer remained in the archive as a regression case. I did not correct it in place. It documented the moment I stopped treating retrieval-augmented generation as a prompt pattern and began treating it as a system of evidence and decisions.
Fluency remained useful. It stopped being evidence that the answer had earned its ending.
Model changes ran against frozen evidence
To understand generation separately from retrieval, I replayed model and prompt candidates against immutable evidence sets. The source passages, order, task, and answerability result stayed fixed. Outputs could then be compared for claim coverage, unsupported additions, refusal behavior, and citation use.
This did not make models interchangeable. Tokenization, context limits, instruction following, and output formats differed. The harness adapted the same semantic task to each supported interface and recorded the exact request. A parse failure was reported as its own failure rather than quietly falling back to unstructured prose.
Repeated runs estimated variability. One correct answer among five unstable runs did not replace the failure record. A consistently cautious refusal on an answerable set was also visible as a usability regression.
Freezing evidence turned “the new model feels better” into a bounded comparison without pretending the result generalized beyond K81R's corpus.
A visible evidence set could still be curated toward the answer I expected. If I selected only the current decision, the result looked clean and hid why a historical note conflicted.
For evaluation, the selector proposed required counterevidence classes: directly contradicting passages, superseded versions, neighboring scopes, and documents linked by amendment. A reviewer could remove them, but the action remained in the set history. The answerability view explained whether disagreement had been resolved by authority metadata or merely excluded.
I also compared automatic top-k selection with deliberate selection. Automatic selection was useful for a draft and never presented as neutral. Ranking, candidate limits, and structural expansion all shaped the context.
Making evidence visible did not eliminate bias. It made selection a stage that could be inspected and evaluated.
The user could challenge one claim
The first chat interface allowed only a follow-up message. “That is wrong” produced another paragraph and left the original claim's evidence relationship unclear.
I added a challenge action on each claim. It let a reviewer mark unsupported, contradicted, too broad, stale, or unclear; attach a source passage; and request a narrower regeneration. The challenge became an annotation linked to the immutable answer and fed a regression candidate queue.
The system did not train itself automatically from the correction or claim that one annotation established ground truth. A reviewed corpus change, evaluation case, or deterministic policy followed through separate workflows.
The feature changed correction from conversation into evidence work. It also exposed which generated claims repeatedly consumed review time.
Hybrid retrieval, structural expansion, answerability, generation, and verification each added time and computation. A trustworthy design could still become unusable if every simple query waited for the full pipeline.
K81R performed direct search first. Evidence inspection was immediately useful. Generation ran only after an evidence set and task existed. Deterministic validation happened before model-based or human claim review. Expensive checks were reserved for claims whose consequence justified them.
The evaluation recorded latency and resource use per stage beside quality. I did not optimize for first token, because early unvalidated prose had caused the original interface failure. I optimized for first inspectable source, first complete evidence set, and first validated claim.
This staged experience preserved usefulness when a model endpoint was slow or unavailable.
The postmortem had an explicit limit
K81R did not prove that every generated answer must use this exact architecture. The corpus was small, curated, and technical. The model interfaces and retrieval techniques available in 2023 were changing quickly. Some tasks, such as unconstrained brainstorming, did not need source-grounded claims.
The postmortem established a narrower rule: when a product presents generated language as an answer about a governed collection, authority, access, evidence sufficiency, claim support, and lifecycle are product responsibilities.
Those responsibilities remain even if models improve. Better generation can reduce failure frequency. It cannot decide which document is authoritative, who may see it, or whether the product should let one fluent sentence authorize an external action.