# m6p5 — Query Composition + SUGGEST Autocomplete (✅ COMPLETE 2026-02-23) Phase spec and acceptance criteria: [ROADMAP · Milestone 6 · Phase 5](../ROADMAP.md). Milestone index: [README.md](README.md). Backfilled record. ## What shipped 1. **`WithinScope` on SEARCH** (`tidal/src/query/search/types.rs:33-44`) — five variants, exactly as specified: | Variant | Candidate set | |---------|---------------| | `Trending { window_hours }` | items above the velocity threshold in the window, from the global ledger | | `CohortTrending { cohort, window_hours }` | same, scoped to a defined cohort (m6p1) | | `Following` | items from creators the querying user follows; requires `for_user` | | `Category { name }` | items matching the category metadata value | | `Collection { id }` | items in the collection's bitmap (m6p4) | The scope resolves to a `RoaringBitmap` applied *before* candidate scoring, so it reaches both retrieval arms: a post-filter for Tantivy BM25 and a predicate callback for the USearch ANN search. Scoping before scoring is the point — scoping after would rank the wrong universe and then discard the answer. 2. **`db.suggest()`** (`tidal/src/query/suggest.rs`, `tidal/src/db/query_ops.rs`). Prefix autocomplete over terms extracted from item titles at write time, updated incrementally on `write_item_with_metadata`; an empty prefix returns trending search terms by recent query frequency, counted on each `db.search()` call. ## Evidence - `tidal/tests/m6p5_scope.rs` — 13 `#[test]` functions: each `WithinScope` variant independently, the composition case (search within cohort trending), and SUGGEST with both a prefix and an empty prefix. - `tidal/src/query/search/types/tests.rs` — `WithinScope` unit coverage. ## Dependencies this phase actually had `CohortTrending` needs m6p1's cohort ledger and `Collection` needs m6p4's collection bitmap, so despite the ROADMAP DAG showing phases 1–4 as broadly parallel, m6p5 was genuinely gated on both. ## Note on the "< 50 ms SEARCH / < 20 ms SUGGEST" criteria Marked `[x]` with no recorded measurement in `docs/`. Functional behaviour is proven by `m6p5_scope.rs`; the two latency figures are not evidenced.