The Result object
An answer comes back as a Result — the same shape whether it answered or
abstained. There is no scalar “confidence”; instead you get structured signals
you can branch on and audit.
Result is field-for-field identical in all three ports and serializes
byte-compatibly (conformance/cases/result_roundtrip.json pins it), so the same
reader works whichever language produced it. Python and JavaScript keep the wire
names as-is; Go uses Go casing with matching json tags.
from citenexus.answer.result import Result, Decision
result = rag.ask("What is the retention period?")
if result.evidence.decision is Decision.answered: print(result.answer, "→", result.answer_language) for src in result.sources: print(src.document, src.page, src.passage_language, src.passage) for claim in result.claims: print(claim.claim, claim.supported, claim.sources) # sources = Evidence-Unit idselse: # Decision.refused print("refused:", result.missing_evidence)import ( "fmt"
"github.com/muthuishere/citenexus/golang/answer" "github.com/muthuishere/citenexus/golang/result")
res := answer.Ask(corpus, "What is the retention period?", answer.DefaultTopK)
if res.Evidence.Decision == result.DecisionAnswered { fmt.Println(res.Answer, "→", res.AnswerLanguage) for _, src := range res.Sources { // Page is *int — nil when the format has no pages. fmt.Println(src.Document, src.PassageLanguage, src.Passage) } for _, c := range res.Claims { fmt.Println(c.Claim, c.Supported, c.Sources) // sources = Evidence-Unit ids }} else { // result.DecisionRefused fmt.Println("refused:", res.MissingEvidence)}import { ask, Decision } from "@muthuishere/citenexus";
const res = ask(corpus, "What is the retention period?", 5);
if (res.evidence.decision === Decision.answered) { console.log(res.answer, "→", res.answer_language); for (const src of res.sources) { console.log(src.document, src.page, src.passage_language, src.passage); } for (const claim of res.claims) { console.log(claim.claim, claim.supported, claim.sources); // sources = EU ids }} else { // Decision.refused console.log("refused:", res.missing_evidence);}Result
Section titled “Result”Import: from citenexus.answer.result import Result, EvidenceSignals, SourceRef, Claim, ProvenanceEntry, Decision
· Go github.com/muthuishere/citenexus/golang/result · JavaScript
import type { Result, EvidenceSignals, SourceRef, Claim, ProvenanceEntry } from "@muthuishere/citenexus"
| field | type | meaning |
|---|---|---|
answer |
str |
the grounded text, or the pinned refusal |
answer_language |
str |
the caller-stated answer language (see the chain below) — never the evidence’s language |
mode |
TrustMode |
the trust mode the answer was produced under |
evidence |
EvidenceSignals |
the structured retrieval + verification signals (below) |
claims |
tuple[Claim, …] |
per-claim verification |
sources |
tuple[SourceRef, …] |
the cited passages — strict answers cite exactly one; the conflict abstention cites both sides |
missing_evidence |
tuple[str, …] |
why it abstained, when it did |
conflicts |
tuple[str, …] |
surfaced multi-source disagreement — on an answer, normal mode only; also populated by the strict conflict abstention, see below |
provenance |
tuple[ProvenanceEntry, …] |
the full reproducibility chain |
The table above is the wire contract, so it reads the same in every port. Go
spells the fields Answer, AnswerLanguage, MissingEvidence, … with json
tags back to these names, and expresses “absent” as a nil pointer where Python
uses None and TypeScript uses null; list fields are always initialized, so
they serialize as [] and never as null.
Decision
Section titled “Decision”answered, refused, partial — Decision.answered in Python and JavaScript,
result.DecisionAnswered in Go.
EvidenceSignals
Section titled “EvidenceSignals”| field | type | meaning |
|---|---|---|
decision |
Decision |
answered / refused / partial |
supporting_sources |
int |
count of passages that supported the answer |
distinct_documents |
int |
how many distinct documents contributed |
retrieval_score_spread |
float |
spread across the retrieved scores |
all_claims_verified |
bool |
every claim passed the grounding gate |
unsupported_claims_removed |
int |
claims dropped for lacking support |
conflicts_detected |
int |
conflicting pairs found in the top-CONFLICT_TOP_K window (all modes) |
languages_in_evidence |
tuple[str, …] |
languages the evidence was written in |
unsupported_scripts |
tuple[str, …] |
scripts the tokenizer does not claim — a capability signal, not an evidence judgement |
authority_tier |
str |
the cited source’s tier name; "" on an unranked corpus |
authority_floor_applied |
bool |
whether the strict-mode authority floor was enforced on this call |
loop |
LoopSignals | None |
agentic loop signals; None on the strict flow |
SourceRef
Section titled “SourceRef”| field | type | meaning |
|---|---|---|
document |
str |
the source document id |
passage |
str |
the verbatim cited text, in its own language |
passage_language |
str |
the passage’s language |
page |
int | None |
page number, when the format has pages |
bbox |
BBox | None |
[x0, y0, x1, y1] region — always None today, see below |
source_uri |
str | None |
where the raw source lives |
translation |
str | None |
declared for additive translation — always None today, nothing sets it |
Evidence-Unit ids are not on SourceRef — they appear on Claim.sources and
ProvenanceEntry.evidence_unit.
Claim and ProvenanceEntry
Section titled “Claim and ProvenanceEntry”Claim: claim: str, supported: bool, sources: tuple[str, …] (EU ids).
ProvenanceEntry: claim, evidence_unit, document_id, s3_object,
checksum, page, bbox (always None, as on SourceRef), produced_by — the chain that lets you reproduce
exactly how a claim was grounded.
Conflict surfacing (shipped in 0.10.0)
Section titled “Conflict surfacing (shipped in 0.10.0)”Conflict detection runs over the grounded candidates before anything is generated (ADR-0007), and it reports rather than resolves — deciding which of two contradictory sources wins by rank or score is the defect this closes, not a feature. What each mode does with a detected conflict differs:
| mode | behaviour on a conflict touching the cited passage |
|---|---|
strict |
abstains, cites both sides, and lists the pair on Result.conflicts — the refusal names the disagreement |
normal |
answers, and populates Result.conflicts with a description of each pair |
exploratory |
answers; records conflicts_detected only, conflicts stays empty |
conflicts_detected is populated in all modes, so it is safe to monitor: a
non-zero count means the corpus contradicts itself in the window that was about
to be cited.