π«π· Version franΓ§aise
See also: ADR-002 β Tool abstractions shared kernel Β· ADR-003 β Secondary shared kernels Β· ADR-004 β Scripting naming twins Β· Back to the index
ADR-006 β RAG subsystem: Rag.Abstractions shared kernel and Rag DI wiring
Status: Accepted Β· Date: 2026-07 Β· Scope: Orkeon.Application β Orkeon.Rag.Abstractions; Orkeon.Infrastructure β Orkeon.Rag
Context
The RAG feature set is being promoted from Orkeon.Infrastructure/Knowledge +
Orkeon.Application/{Interfaces/Rag,Rag} to a first-rank subsystem src/rag/, on the proven
model of src/analysis/ (RaggableTree β see ADR-003):
src/rag/Orkeon.Rag.Abstractionsβ contracts, DTOs, and options (IChunkingStrategy,IDocumentLoader,IDocumentStore,IQueryTransformer,IReranker,IRetrievalEvaluator,IGroundednessChecker,IQueryComplexityClassifier,IIngestionPipeline,IRagPipeline,RagAnswerβ¦). Depends onOrkeon.Domainonly.src/rag/Orkeon.Ragβ implementations (chunkers, loaders, retrieval, reranking, ingestion, evaluation) and named-component factories.src/tools/Orkeon.Tools.Ragβ agent tools (rag_search,rag_ingest,rag_eval), in theTools.*family per ADR-004 (Orkeon.Tools.Rag, notOrkeon.Rag.Tools).
Two cross-onion couplings are needed for the subsystem to plug into the core, exactly as with RaggableTree. This ADR enacts them ahead of realization: the project skeleton and contracts land first (RAG-02 / C1-C2); the references below are added by the subsequent migration batches.
Orkeon.Application β Orkeon.Rag.Abstractionsβ the Application layer needs the RAG ports (e.g.IRagPipelinefor crew/agent knowledge injection) without seeing any implementation.Orkeon.Infrastructure β Orkeon.Rag(concrete, not just the abstractions) β exclusively as composition wiring confined to a single DI file (DependencyInjection/RagInfrastructureExtensions.cs, mirror ofRaggableTreeInfrastructureExtensions.cs), notably to wrap embedding calls inLlmLoggingDelegatingHandler.
Decision
Orkeon.Rag.Abstractionsis a secondary shared kernel (same status asTools.Abstractionsin ADR-002 andAnalysis.Abstractionsin ADR-003): an abstractions project depending only onDomain, hence consumable byApplicationwith no cycle and no inversion of the dependency direction.- The concrete
Infrastructure β Orkeon.Ragreference is accepted as composition wiring localized to a single DI extensions file; the Infrastructure assumes its composition-root role for the RAG subsystem.AddOrkeonRag()is an explicit opt-in (auto-sufficient,TryAdd*everywhere β the host wins), never called unconditionally fromAddOrkeonInfrastructure. - Plugin type identity:
Orkeon.Rag.Abstractionsis listed inOrkeonPluginsOptions.SharedAssemblyPrefixesso rerankers/chunkers/loaders contributed by plugins keep a single type identity acrossAssemblyLoadContextboundaries.
Consequences
- Positive: the RAG contracts get RaggableTree-grade visibility, a clean opt-in, and plugin extensibility; the couplings are traceable and challengeable instead of renegotiated at every review.
- Vigilance:
Orkeon.Rag.Abstractionsmust keep depending onOrkeon.Domainalone β enforced bytests/rag/Orkeon.Rag.Abstractions.Tests/ArchitectureTests.cs. Any extension of the concreteOrkeon.Ragusage in the Infrastructure beyond the single DI wiring file must reopen this ADR. - Break: the legacy namespaces (
Orkeon.Application.Interfaces.Rag.*,Orkeon.Application.Rag.*,Orkeon.Infrastructure.Knowledge.*) are removed without shims (assumed break, version0.9.x-beta; migration table inCHANGELOG.md). Done in RAG-02/C5 (2026-07-25) βrag_searchnow lives inOrkeon.Tools.Rag(RagSearchTool+AddOrkeonRagTools()), and the subsystem opt-in isAddOrkeonRag(configuration)inOrkeon.Rag.DependencyInjection.
Amendment β 2026-07-25 (RAG-02/C3)
The migration batch that ports the implementations into Orkeon.Rag adds two outbound
couplings of the concrete Orkeon.Rag project (never of Orkeon.Rag.Abstractions,
whose Domain-only rule is unchanged):
Orkeon.Rag β Orkeon.ApplicationβOrkeon.Ragis an outer-ring implementation project (same ring asOrkeon.Infrastructure) and consumes the Application ports directly:Orkeon.Application.Interfaces.Ports.IEmbeddingProvider(canonical embedding interface, plan Β§4.1) for the ingestion/query pipelines, and theOrkeon.Application.Interfaces.Securityvalidation contracts (IDataValidator,IProvenanceTracker,DataValidationResultβ¦) for the ingestion-path validation. This follows the onion direction (outer ring β Application) and creates no cycle:ApplicationreferencesRag.Abstractionsonly, neverOrkeon.Rag.Orkeon.Rag β Orkeon.Analysis.Abstractionsβ hostsAnalysisEmbeddingProviderAdapter(moved out ofOrkeon.Infrastructure/LLMs/Embeddings/), the bridge from the Analysis embedding abstraction to the Application port ("inOrkeon.Rag, which references both worlds", plan Β§4.1).
Vigilance note: besides the DI wiring file, Orkeon.Infrastructure currently also uses
Orkeon.Rag.Embeddings.AnalysisEmbeddingProviderAdapter from
LLMs/Embeddings/DefaultEmbeddingProviderResolver.cs β composition-time resolution logic
invoked by AddOrkeonInfrastructure. It is accepted as part of the composition-root role;
any use of Orkeon.Rag from Infrastructure runtime code (non-composition) still requires
reopening this ADR.
Amendment β 2026-07-26 (RAG-06)
The corrective phase layers four decisions on top of this ADR without touching its
dependency rules (Orkeon.Rag.Abstractions stays Domain-only β verified by
ArchitectureTests):
- CRAG on the Domain
StateGraph, not a bespoke loop.CorrectiveRagPipeline(src/rag/Orkeon.Rag/Corrective/) is built onStateGraph<RagGraphState>(Orkeon.Domain.Graph) β the same Graph orchestration mode crews use β with conditional edges on the retrieval verdict (Correct|Incorrect|Ambiguous) and a double bound:Orkeon:Rag:Corrective:MaxIterationsplus the graph's own circuit breaker derived from it. Exhaustion degrades to a best-effort answer; the graph never throws at the caller. - Web fallback split: policy vs transport. Two independent, off-by-default
switches:
Orkeon:Rag:Corrective:WebFallback(the policy β may the graph leave the local store; lives inOrkeon.Rag.Abstractions, Domain+BCL-only) andOrkeon:Rag:WebFallback(the transport βWebSearchRetrieverOptions, SearxNG endpoint; lives inOrkeon.Rag, sinceSuspiciousActionand HTTP concerns would violate the Abstractions dependency rule). Both must be enabled for theweb_fallbacknode to run, and every fetched page goes throughPromptInjectionDocumentValidatorbefore entering the working set. correctiveprofile without a linear rerank stage. The preset disables the ONNX cross-encoder and the linear groundedness stage on purpose: the graph corrects by looping (evaluate β rewrite/refine β re-retrieve) and has a nativecheck_groundednessnode instead. Theadaptiveprofile'sIterativeroute delegates tocorrective(the RAG-05 interim fallback toqualityis lifted).- No separate
rag-adr.md. The RAG-06 batch deliberately keeps the decision record here (single ADR, amended per phase) instead of adding thedocs/architecture/rag-adr.mdpage the task sheet sketched β a second decision document would duplicate this one and widen the FR-parity debt. The narrative architecture guide isdocs/architecture/rag-pipeline.md.