# 搜尋結果

說明 KuraDB 如何分組 keyword 與 semantic 命中結果、哪些 field 保持私有，以及每筆結果的一致性保證。

## 分組

兩個 flat result set 都依首次出現的 source 分組，group 內維持排名順序。External representation 為：

```json
[
  {
    "source": "/path/to/document.md",
    "matches": [
      {"chunk": 1, "content": "..."},
      {"chunk": 2, "content": "..."}
    ]
  }
]
```

REST 中已選 branch 無結果時表示為 `[]`；MCP 的 `search_rag` 輸出則省略空 branch。

## 私有 ranking data

內部 field 在 serialization 前即被捨棄；對外的 `Group` 與 `Match` 型別只帶四個契約 field：

| 內部 field | 保持私有的原因 |
|---|---|
| Row ID | Storage implementation detail |
| Semantic score | Threshold 與 ranking 可能調整 |
| Keyword hit count | 內部 ranking signal |
| Chunk total | 不屬於 consumer contract |
| Overall total | API 不提供 pagination metadata |

Consumer 應只依賴 `source`、`matches`、`chunk` 與 `content`。

## 一致性行為

- Keyword SQL 一律過濾 dismissed row。
- Semantic hydration 一律過濾 dismissed row。
- 維度與 query 不同的 vector 會被忽略。
- Query cache 以完整 query text 為 key，不做 normalization。
- Keyword 與 semantic result array 維持獨立；KuraDB 不會混合其 score。
- 只有 daemon 或 `kura mcp` process 啟動時載入的 database 可供搜尋。
