{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://kb.local/wire/v1/search_response.schema.json",
  "title": "SearchResponse v1",
  "description": "Top-level wrapper for `kebab search --json` output. Replaces the bare `search_hit.v1[]` array — wraps it with pagination + truncation metadata. Token counts are approximate (chars/4 estimate, no tokenizer dep). On `truncated: true`, caller may either widen `--max-tokens` or follow `next_cursor` for the next page. Stale `next_cursor` (corpus_revision changed since issued) returns `error.v1.code = stale_cursor`.",
  "type": "object",
  "required": ["schema_version", "hits", "next_cursor", "truncated"],
  "properties": {
    "schema_version": { "const": "search_response.v1" },
    "hits":           { "type": "array", "description": "search_hit.v1[]" },
    "next_cursor":    { "type": ["string", "null"], "description": "Opaque base64 cursor for next page; null when no more hits." },
    "truncated":      { "type": "boolean", "description": "True when budget forced snippet shortening or k reduction. Independent of `next_cursor`: caller may widen `max_tokens` (re-issue same query) or follow `next_cursor` (advance through more hits) or both." },
    "trace": {
      "type": "object",
      "description": "p9-fb-37: present iff caller passed --trace / SearchOpts.trace=true. Lex/vec pre-fusion lists + RRF union + per-stage timing.",
      "required": ["lexical", "vector", "rrf_inputs", "timing"],
      "properties": {
        "lexical":   { "type": "array", "items": { "type": "object" } },
        "vector":    { "type": "array", "items": { "type": "object" } },
        "rrf_inputs":{ "type": "array", "items": { "type": "object" } },
        "timing": {
          "type": "object",
          "required": ["lexical_ms", "vector_ms", "fusion_ms", "total_ms"],
          "properties": {
            "lexical_ms": { "type": "integer", "minimum": 0 },
            "vector_ms":  { "type": "integer", "minimum": 0 },
            "fusion_ms":  { "type": "integer", "minimum": 0 },
            "total_ms":   { "type": "integer", "minimum": 0 }
          }
        }
      }
    },
    "hint": {
      "type": "string",
      "description": "Reserved for advisory strings on `search_response.v1`. v0.17.0 (V007 trigram) 시절 3자 미만 query 안내용 helper 였으나, v0.20.1 (V009 morphological tokenizer) 에서 한국어 2자 query 가 hit 가능해져 helper 가 제거됨 (`short_query_hint` retired). 본 field 는 forward-compat 차원에서 schema 에 보존되어 항상 omit. 향후 advisory 가 다시 필요해지면 동일 shape 으로 reuse 가능."
    }
  }
}
