# Hybrid graph stream

In TnsAI 0.14.0 (`TnsAI@4b9aff80`), `HybridRAGStrategy` can
RRF-fuse a third knowledge-graph ranking with BM25 and vector. The strategy
name stays `hybrid`. The three-argument constructor and
`HybridGraphStream` are `@since 0.14.0`. They ship in Maven Central `0.14.1`.

A missing graph store does **not** collapse HYBRID into VECTOR-only. The
two lexical and semantic streams still fuse. The instance records
`HybridGraphStream.SKIPPED_NO_GRAPH_STORE`.

## Declarative

`@Retrieval(strategy = HYBRID)` is unchanged. `RoleRagBinding` tries to
resolve a `GraphStoreProvider` for the Role and source fence:

- one claiming provider → three-stream fuse (`HybridGraphStream.FUSED`)
- no claiming provider → two-stream BM25+vector
- two or more non-default claimants → configuration error, **above**
  `@Retrieval.onFailure`

## Programmatic

Two-stream construction is unchanged:

```java
RAGStrategy hybrid = new HybridRAGStrategy(bm25Index, vectorStore);
```

Three-stream construction ranks each source independently, then fuses with
unweighted RRF (`k = 60`):

```java
RAGStrategy hybrid = new HybridRAGStrategy(
    bm25Index, vectorStore, graphStrategy);
```

`graphStrategy` is a source-fenced `GraphRAGStrategy`. Scores are
normalized to `0.0..1.0` against the number of non-empty streams before
`RAGContext.minScore()` applies.

## Provenance

| Key | Values |
|---|---|
| `retrievalStreams` | `bm25`, `vector`, `graph` — streams that contributed to the hit |
| `graphStream` | `fused` or `skipped` (`HybridGraphStream.metadataValue()`) |

Graph hits also keep existing GraphRAG provenance.

## Not this page

- The GRAPH strategy itself and the KnowledgeTools backend
- The strategy inventory on [Strategies](strategies.md)
