# PRD: Read Pipeline — Graph Signal Fix + Doc Gaps

> Generated via /vibeflow:discover on 2026-03-20

## Problem

O time de validação testou o read pipeline com 26 testes e encontrou 4 gaps:

1. **Graph signal retorna 0 em 100% dos testes** (Gap #21) — O graph retrieval está implementado (`read/graph_retrieval.py` — BFS 2-hop completo), mas nunca roda porque o retrieval agent (planner LLM) nunca retorna entities no seu JSON. O system prompt do retrieval agent não inclui `entities` no formato esperado nem nos exemplos. Resultado: `plan.entities` é sempre vazio → `if plan.entities:` nunca é true → graph task nunca é criada. Com 11 relations no banco, o pipeline reporta `graph_facts: 0, graph_edges_traversed: 0` em todas as queries.

2. **Reranker sobrescreve score_weights** (Gap #22) — Quando `enable_reranker=True` (default), o score final é determinado pelo reranker LLM (discreto: 0, 0.3, 0.5, 0.8, 1.0), não pela fórmula de `score_weights`. Os weights só afetam pré-ordenação antes do reranker. Doc não explica isso.

3. **`context_max_tokens` não é hard limit** (Gap #23) — Com 100 tokens configurados, o SDK gera ~240 tokens. É um budget proporcional, não um cap. Doc não esclarece.

4. **Score breakdown retorna 6 sinais, doc formula mostra 3** (Gap #24) — `ScoredFact.scores` retorna `semantic, keyword, recency, importance, confidence, reranker`, mas a fórmula documentada é `score = semantic × w_sem + recency × w_rec + importance × w_imp`. Faltam keyword, confidence e reranker.

## Target Audience

Desenvolvedores integrando o Arandu SDK que usam `memory.retrieve()` e `verbose=True` para entender o pipeline.

## Proposed Solution

1. **Fix do prompt do retrieval agent** — Adicionar campo `entities` no formato JSON esperado e nos exemplos do system prompt. O LLM deve extrair entity keys da query pra alimentar o graph retrieval.

2. **Doc fixes** — Adicionar callouts/disclaimers nos docs EN e PT-BR para os gaps #22, #23 e #24.

## Success Criteria

- Graph signal retorna > 0 facts quando existem relations relevantes no banco (verificável no trace com `graph_facts > 0`)
- Docs explicam interação reranker × score_weights
- Docs esclarecem que context_max_tokens é budget
- Docs mostram fórmula completa com 6 sinais

## Scope v0

1. Atualizar system prompt em `src/arandu/read/retrieval_agent.py` — adicionar `entities` no JSON format e exemplos
2. Teste unitário verificando que o planner retorna entities pra queries sobre entidades específicas
3. Doc updates (EN + PT-BR) pra gaps #22, #23, #24
4. Explicar importance (background job) e confidence (classificação do LLM) na doc

## Anti-scope

- Não mudar a implementação do graph retrieval (`graph_retrieval.py`) — já funciona
- Não mudar o pipeline (`read/pipeline.py`) — o gate `if plan.entities:` está correto
- Não mudar config defaults (spreading_activation_hops=2 está bom)
- Não implementar confidence variável — é comportamento do LLM, não bug
- Não implementar importance calculation no write — é background job, já existe
- Não mudar o reranker — comportamento está correto, só falta doc

## Technical Context

- `src/arandu/read/retrieval_agent.py` (linhas 141-188) — system prompt do planner
- `src/arandu/read/retrieval_agent.py` (linhas 272-280) — extração de entities do JSON
- `src/arandu/read/pipeline.py` (linhas 226-238) — gate `if plan.entities:`
- `src/arandu/read/graph_retrieval.py` — BFS 2-hop implementado e funcional
- `src/arandu/config.py` (linhas 65-69) — `spreading_activation_hops=2` (correto)
- Padrão fail-safe: se entities vazio, graph simplesmente não roda (não é erro)

## Open Questions

None.
