Files
kb/openspec/changes/archive/2026-04-02-fix-search-human-output/design.md
T
steve 2d179af557 Fix search human-mode output to match engine API response
The Go client struct expected a nested document object and top-level
page/section fields, but the engine returns flat results with metadata
in chunk_metadata. This caused empty display for title, type, tags,
page, and section in human output mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:17:35 +01:00

1.7 KiB

Context

The engine's /api/v1/search endpoint returns flat result objects:

{
  "chunk_id": 123,
  "score": 0.031,
  "text": "...",
  "chunk_index": 3,
  "chunk_metadata": {"page": 12, "section_header": "Installation"},
  "title": "Git Admin Guide",
  "doc_type": "pdf",
  "source_path": "/home/user/docs/git-admin.pdf",
  "created_at": "2026-03-15T10:30:00",
  "tags": ["git", "admin"]
}

The Go client's human-mode struct in client/cmd/search.go incorrectly expects a nested document object and top-level page/section fields. This causes all metadata to display as zero values.

Goals / Non-Goals

Goals:

  • Fix the search result struct to match the flat engine response
  • Extract page and section_header from chunk_metadata for human display
  • Maintain identical JSON output (already passes through raw response)

Non-Goals:

  • Changing the engine API response format
  • Adding new display fields beyond what was originally intended

Decisions

Flatten the struct to match API response. The result struct will have Title, DocType, Tags as top-level fields (matching title, doc_type, tags JSON keys). ChunkMetadata will be decoded as map[string]interface{} to extract page and section_header dynamically, since its contents vary by document type.

Why not a typed ChunkMetadata struct? The metadata keys depend on the ingestion pipeline (PDFs have page, markdown has section_header, code may have others in future). A map is more resilient to engine-side additions.

Risks / Trade-offs

  • [Minimal risk] If the engine adds new top-level fields, the Go struct silently ignores them — this is existing behavior and acceptable for human-mode display.