Skip to content

Latest commit

 

History

History
59 lines (31 loc) · 4.88 KB

File metadata and controls

59 lines (31 loc) · 4.88 KB

ADR 005: Evidence-first hybrid RAG

  • Status: Accepted
  • Date: 2026-07-21
  • Classification: COMPLEX

Context

Project knowledge answers must be grounded in tenant-scoped project documents. Gemini generation, model output, browser timing, hosted network latency, and quota behavior are FRAGILE, so the database must retrieve and preserve evidence before any synthesis occurs.

Decision

The pipeline is:

Authenticated query -> project and role authorization -> query normalization -> metadata filtering -> query embedding -> PostgreSQL full-text retrieval -> pgvector retrieval -> Reciprocal Rank Fusion -> overlap deduplication -> evidence selection -> Gemini claim generation -> claim-to-evidence validation -> deterministic confidence calculation -> response with citations -> immutable audit and productivity events.

Supabase PostgreSQL remains the only retrieval store. No external vector database or reranking service is introduced. PostgreSQL full-text search, pgvector, metadata filtering, and deterministic rank fusion are sufficient for the current hosted corpus and avoid another externally fragile dependency.

Retrieval formula

RRF is 1 / (rrfConstant + semanticRank) + 1 / (rrfConstant + lexicalRank). The default constant is 60.

Final score is:

rrf * 8 + semanticScore * 0.36 + lexicalScore * 0.26 + metadataScore + exactIdentifierScore * 0.28

Metadata boosts are deterministic and documented in src/domain/constants/rag.ts. Exact identifiers such as UPS-01, RFI-018, NCR-009, E-420, and 7.2.1 receive transparent weighting. Gemini never assigns retrieval scores.

Claim and citation validation

Gemini returns structured JSON only: summary, claims, assumptions, and human-review state. The server validates the schema, rejects evidence IDs outside the retrieved set, downgrades unsupported direct claims, assigns citation numbers deterministically, and builds citations from database document/chunk/page metadata. Model-supplied document names and page numbers are not trusted.

Confidence

Confidence is deterministic. Factors are top retrieval score, direct-claim coverage, citation coverage, independent document count, unsupported-claim penalty, ambiguous-evidence penalty, and degraded-index penalty. Bands are HIGH, MEDIUM, and LOW. The UI displays factors and never treats model confidence as authoritative.

Refusal and fallback

The Copilot refuses or limits answers when no evidence passes threshold, evidence is insufficient, conflict is material, or the request asks for unsupported or out-of-project information. If Gemini generation is missing, invalid, rate-limited, timed out, or unavailable, retrieval still runs and returns EVIDENCE_ONLY with citations and scores.

Prompt-injection protection

Retrieved text is wrapped as untrusted evidence. System rules forbid following document instructions, revealing prompts or secrets, crossing tenant boundaries, fabricating citations, or mutating project data from a knowledge query. Adversarial fixture text is included in controlled project knowledge records and covered by integration tests.

Cache and history

The cache key includes organisation, project, normalized query, filter hash, aggregate project index version, retrieval config version, prompt version, and model. Cached responses are ignored after relevant document updates because the aggregate index version is derived from indexed document update state. Query history, claims, citations, feedback, audit, and productivity events are persisted with RLS.

Performance observations

Focused hosted integration tests completed five RAG cases in 16.7 seconds after warm cache. The focused browser workflow completed in 50.1 seconds, including generated query, citation navigation, filtered query, unsupported query, feedback, 12-case Assurance Lab run, and controlled fallback. The persisted benchmark rerun on 17 August 2026 measured recall@1 at 0.917, recall@3 and recall@5 at 1.0, citation precision at 1.0, refusal correctness at 0.917, average retrieval latency at 548 ms, average generation latency at 492 ms, and total benchmark latency at 41.282 seconds. No cache hit occurred in that run, so cache-hit latency remains unreported. Hosted latency and Gemini generation latency remain FRAGILE and must be reported from actual runs rather than assumed.

Productivity calculation

The baseline is configurable and defaults to 30 minutes for traditional project-document search. Assisted duration is measured query latency plus optional user review time when available. Hours saved is max(0, baseline duration - assisted duration) / 60 and is stored in productivity_events.

Streaming

Streaming is classified as FRAGILE for the current runtime because response persistence must happen only after claim validation. Step 5 ships a reliable non-streaming path with retry and cache support; streaming can be added later without changing the database evidence contract.