# Frontend product retrieval execution plan

## Objective and non-negotiable gates

The frontend chat must keep the configured default LLM and improve speed by removing local retrieval, serialization, hydration, and orchestration waste. Product discovery must tolerate vague descriptions, inflection, transliteration, typos, multilingual wording, and a wrong product category without presenting a nearby semantic match as an exact factual match.

Release gates:

- Exact product ID, SKU, exact title, and exact model queries: 100% Recall@10.
- Curated vague/typo/transliteration/multilingual/attribute queries: at least 99% Recall@10 before a lossy dimension change is allowed.
- Exact material/category claims must come from indexed or live product facts, never from discovery aliases.
- A healthy index must complete the semantic lane before the assistant concludes that no product exists.
- True zero-result cases must not produce invented product matches.
- p95 retrieval, embedding, hydration, prompt-build, LLM, and total timings must be recorded separately.

## Wave 1 - correctness and the lossless performance foundation

### W1.1 Fix chunk scoring and complete semantic coverage

Owner: retrieval correctness workstream.

Deliverables:

- Aggregate vector similarity with `max(score)` for every chunk belonging to the same product.
- Remove hard row caps and score-based early exits that can hide products later in the index.
- Use stable pagination (`post_id`, then `doc_key`) or a cursor contract so equal `post_id` chunks cannot move between pages.
- Preserve filters and final product-level deduplication.

Verification:

- Regression with a relevant second chunk after a weak first chunk.
- Regression with the correct product beyond the old scan cap.
- Regression with multiple chunks sharing a `post_id` across a page boundary.

### W1.2 Store full-size embeddings as binary float32

Owner: binary storage workstream.

Deliverables:

- Add an explicitly versioned little-endian float32 binary representation plus dimension metadata.
- Keep the current full model dimensions; this task must not shorten vectors.
- New writes store binary and retain a compatibility path for existing JSON rows.
- Reads prefer a valid binary payload and fall back to JSON when binary is absent or invalid.
- Backfill is bounded, resumable, idempotent, and safe to rerun after interruption.
- Content changes invalidate both representations together.

Verification:

- JSON-to-binary-to-vector round trip within float32 precision.
- Invalid byte length, unsupported codec version, and dimension mismatch fall back safely.
- Mixed legacy/new rows rank identically within float32 tolerance.
- Schema and backfill can be applied repeatedly without data loss.

### W1.3 Batch embeddings and query variants

Owner: eval and orchestration workstream.

Deliverables:

- Send multiple independent texts through the embeddings array-input contract when they share model and settings.
- Preserve response ordering by the API `index` field.
- Deduplicate normalized query variants before embedding/search work.
- Reuse per-request query embeddings; never reduce the configured chat model or its reasoning settings.
- Fall back to the current single-query path if a batch response is incomplete or invalid.

Verification:

- One batch request returns vectors in caller order even when response items arrive out of order.
- Duplicate variants do not trigger duplicate work.
- Partial batch failure is observable and does not silently attach a vector to the wrong query.

### W1.4 Establish the catalog-specific eval baseline

Owner: eval and orchestration workstream, reviewed by root integration.

Inputs:

- Sanitized questions from `Niwa_AI_Frontend_Question_Log`; session IDs and answer text are not exported into fixtures.
- Synthetic cases only where real logs do not cover the required category.

Required categories:

- Exact ID, SKU, title, and model.
- Vague material or feature descriptions.
- Typos, grammatical forms, Cyrillic/Latin transliteration, and mixed-language queries.
- Long/chunked products.
- Correct attribute with the wrong category.
- Near alternatives that must be labelled as alternatives rather than exact matches.
- True zero-result queries.

Outputs:

- Recall@1/5/10, mean reciprocal rank, exact-query pass rate, false-exact rate, and zero-result precision.
- Per-query latency broken down by retrieval stage.
- Machine-readable report containing the index/model/codec/dimension version.

## Wave 2 - remove remaining local hot-path waste

### W2.1 Lean candidate evidence

- Split immutable discovery evidence from mutable commerce facts.
- Candidate retrieval returns IDs, compact facts, evidence snippets, lane scores, and provenance instead of full descriptions and large variation arrays.
- Enforce per-field and total evidence budgets before the LLM prompt is built.

Gate: no eval regression and lower prompt bytes/tokens on the same query corpus.

### W2.2 Hydrate only finalists

- Do not call `wc_get_product()` and build variation evidence for every initial candidate.
- Let the default LLM select grounded product IDs from compact candidates.
- Hydrate price, stock, URL, and only relevant variations for the final IDs.
- Revalidate that every returned card ID was present in retrieval evidence.

Gate: identical or better card correctness, with measured reduction in pre-LLM hydration time.

### W2.3 Cache immutable work with explicit version keys

- Request cache: query embeddings and normalized variants.
- Short-lived shared cache: candidate sets keyed by normalized query, filters, index version, embedding model, codec, and dimensions.
- Never cache price/stock as immutable evidence.
- Invalidate by atomic index-version change rather than broad time-only expiry.

Gate: repeated-query speedup without stale availability or cross-index contamination.

## Wave 3 - retrieval quality and calibrated ranking

### W3.1 Catalog-derived attribute vocabulary

- Build a vocabulary from actual categories, attributes, terms, brands, and variation attributes.
- Use it to expand spelling, inflection, transliteration, and discovered semantic neighbors.
- Store expansion provenance and never promote a neighbor to a factual product attribute.

### W3.2 Typo lane and discovery aliases

- Add a trigram/fuzzy lane for short misspellings and malformed keywords.
- Add optional curated/generated discovery aliases separate from factual index text.
- Evaluate each lane independently before fusion.

### W3.3 Rank fusion and confidence redesign

- Fuse exact, lexical, typo, and semantic ranks with reciprocal-rank fusion or another measured rank-level method.
- Keep raw lane scores and evidence flags.
- Compute confidence from factual match features and calibrated eval data; never treat the RRF score itself as probability.
- Classify results as `exact`, `close`, or `alternative` with explicit mismatch fields.

Gate: better Recall@10 with no increase in false-exact rate.

## Wave 4 - grounded LLM contract and frontend UX

### W4.1 Structured selection contract

- The configured default LLM returns selected product IDs, result class, matched evidence, mismatches, and answer text in a validated schema.
- Reject or repair IDs not present in the supplied candidate set.
- Preserve a safe textual fallback when structured output fails.

### W4.2 Progressive frontend delivery

- Instrument current time-to-first-status and total latency first.
- Add SSE only after retrieval and hydration changes, with AJAX fallback and reconnect/idempotency semantics.
- Stream status/answer text without exposing internal scores or unvalidated product cards.

## Wave 5 - operational scale options

### W5.1 Atomic reindex and observability

- Build a shadow index, validate counts/coverage/codec/model metadata, then atomically switch the active index version.
- Keep the last known-good index for rollback.
- Dashboard: index health, embedding coverage, fallback rate, zero-result rate, false-exact audit sample, Recall@K trend, and p50/p95 stage timings.

### W5.2 Optional vector backend adapter

- Detect actual database/vector capabilities instead of assuming them.
- Keep the local binary scanner as the correctness reference implementation.
- Add a native/external vector adapter only when catalog size and measured p95 justify the operational cost.
- Require parity against the reference eval before activation.

## Dimension decision procedure

1. Generate or load one full-dimension vector for every eval query and indexed document.
2. Evaluate 3072 as the baseline.
3. For 1024, 512, and 256, take the leading dimensions and L2-normalize both query and document vectors.
4. Compare Recall@K, rank changes, false-exact rate, zero-result precision, scan time, memory, and storage.
5. Change production dimensions only if all release gates pass on this catalog. Otherwise keep 3072.

## Release sequence for every completed wave

1. Run targeted regressions and the full available suite.
2. Run `php -l` on every changed PHP file and `node --check` on changed JavaScript.
3. Search for retired symbols, caps, schema names, and stale version metadata.
4. Review the complete dirty diff and separate pre-existing user changes from this wave.
5. Bump and synchronize the plugin patch version, add the changelog entry, rebuild the production ZIP, and validate its root shape.
6. Deploy or push only when explicitly requested, using the same validated production package.
