---
schema_version: 1
id: RAC-KTXTGSJJSW5Y
type: roadmap
---
# RAC v0.10.3 — Search Quality

## Status

Planned

## Context

v0.10.0 made search a product surface: `search_artifacts` is the tool an
agent reaches for before implementing, and the grounding claim depends on
what it returns. Two recorded weaknesses remain. Substring matching
produces word-boundary false positives — a query for `lore` matches every
Explorer artifact, a collision that now involves the product name — and
metadata-only matching misses artifacts whose bodies, not titles, answer
the query, pushing agents back toward the grepping behaviour Guide
replaces.

ADR-037 and ADR-038 settle both: token-boundary matching, and a body-text
tier with snippets. This milestone implements the pair as one deliberate,
announced contract change to search semantics. It lands before the demo
recording, so the launch measurement runs once, against the improved
search.

## Outcomes

- A query matches on token boundaries: `lore` returns Lore artifacts and
  no Explorer artifacts; `relation` still finds `relationships`.
- Body and section-heading text participate in matching as the
  lowest-ranked tiers, and body/heading matches carry snippet fields an
  agent can triage without retrieving each candidate.
- `rac find` and `search_artifacts` return identical results from one
  Core implementation, re-pinned by goldens and contract tests.
- The grounding measurement re-runs against the new semantics and meets
  the eight-of-ten gate before the demo is recorded.

## Initiatives

### Initiative 1 — Token-Boundary Matching (ADR-037)

Replace substring matching in the Core search implementation with
tokenized matching: split identifiers, titles, paths, and headings on
non-alphanumeric boundaries and camelCase transitions; match query terms
case-insensitively as whole tokens or token prefixes; require every term
of a multi-term query to match. The ranking ladder and sorted-path
tiebreak are unchanged.

### Initiative 2 — Body-Text Tier with Snippets (ADR-038)

Extend matching to section headings and body text as the lowest tiers of
the ladder: identifier, title, path, heading, body. Source heading and
body text from the corpus snapshot the search path already consumes —
no second walk. Heading and body matches add additive snippet fields
(matching line text plus its section heading) to search responses,
following ADR-007's additive rules and truncating as whole items under
the response budget.

### Initiative 3 — Contract Re-Pinning

Re-pin golden output, CLI JSON, and the `mcp` battery's search contract
tests to the new semantics in the same change, with `lore` versus
`Explorer` as a named regression test. Revise the `guide-tool-surface`
design: the body-text open question is settled, and the search response
shape gains the snippet fields.

### Initiative 4 — Measurement Re-Run

Re-run the ten-run grounding measurement after the change lands
(ADR-037 requirement). The demo recording happens after this gate
passes, so launch assets reflect shipped behaviour.

## Constraints

- One matching implementation in Core serves CLI and Guide; the server
  layer gains no search logic (ADR-031).
- Matching stays deterministic and tiered; no embeddings, fuzzy
  matching, stemming, synonym expansion, or opaque scoring (ADR-038).
- Existing response shapes change only additively (ADR-007); the
  semantics change is announced in release notes as a behavior change.
- Guide tool descriptions are unchanged; description revisions, if the
  measurement demands them, follow the design's own protocol.
- One corpus walk per Guide tool call is preserved (v0.10.x precedent).

## Non-Goals

- Semantic, embedding, or RAG-based retrieval (ADR-038)
- Stemming, plural folding, or synonym normalization
- Search configuration flags or per-call ranking options
- Performance optimization beyond the existing corpus-snapshot seam
- Pagination or cursoring; the response budget remains the cap

## Implementation Contract

The following decisions are pinned for v0.10.3.

### Module Locations

- Tokenization and matching live with the existing search implementation
  in `src/rac/services/resolve.py` (`_match_rank`, `search_index`,
  `find_artifacts`); one implementation, no consumer-side variants.
- Heading and body text reach search through the corpus snapshot
  (`walk_corpus` / the index built from it); if the searchable entry
  model must grow fields, it grows in Core.

### Semantics

- Tokens split on non-alphanumeric boundaries and lowercase-to-uppercase
  transitions; comparison is casefolded.
- A term matches a token by equality or prefix.
- Multi-term queries: every term must match somewhere in the artifact's
  matchable fields; the artifact ranks by the best field any term hit.
- Ladder: identifier, title, path, heading, body; ties break by sorted
  path. Empty results remain a valid outcome.

### Response Shape

- Search match entries gain optional additive fields for heading/body
  matches: the matched section heading and the matching line's text.
  Field names are pinned in the revised `guide-tool-surface` design
  before implementation; identifier/title/path-matched entries are
  byte-identical to today's shape.

### Testing

- Boundary battery: `lore` excludes Explorer artifacts (named
  regression); prefix matching; camelCase splits; multi-term AND;
  heading and body tier ordering; snippet truncation under small
  budgets; CLI/Guide equivalence on the same fixture state.
- Goldens and `mcp` contract tests re-pinned in the same commit as the
  semantics change; every new test file joins exactly one battery
  (ADR-027).

## Success Measures

- `rac find lore rac/` returns only Lore-related artifacts on the
  dogfood corpus.
- A fixture decision whose body, but not title, contains the query term
  is found, with its snippet, by both `rac find` and `search_artifacts`.
- Tool and CLI search output remain byte-identical to each other for
  identical state and query.
- The ten-run grounding measurement passes at eight or better after the
  change, before the demo recording.

## Risks

- Re-pinned goldens mask unintended result changes. Mitigated by the
  named boundary cases and by reviewing golden diffs as product changes.
- Snippet fields push more responses into truncation. Mitigated by
  whole-item truncation and the existing budget contract tests.
- Tokenization edge cases (digits, unicode) accrete rules. Mitigated by
  keeping the rule set in one documented place with boundary tests.

## Assumptions

- The corpus snapshot's parsed model exposes section headings and body
  lines without re-reading files.
- Current corpus scale keeps in-memory body matching within interactive
  latency; the corpus-snapshot seam remains the optimization point.

## Related Decisions

- ADR-037
- ADR-038
- ADR-007
- ADR-027
- ADR-031
- ADR-033

## Related Designs

- guide-tool-surface

## Related Requirements

- rac-agent-context-guide

## Dependencies

- v0.10.0 server and tool surface
- v0.10.2 measurement protocol (the re-run gate)
