Plain `--json` preserves the legacy result array. `--performance --json` emits
`SearchResponse` with basic metrics; `--debug-performance --json` emits the
same envelope with detailed spans. Normal terminal output prints results and
reports elapsed time/count on stderr, including CLI index/session initialization.
Debug terminal mode also prints the detailed metrics on stderr. Legacy Vec
interfaces remain wrappers for compatibility. The desktop should use a compact ordinary summary and an optional
diagnostic view, without confusing score/similarity with elapsed time or confidence.
Both measured GUI commands start the native clock at command entry, include instrumented queue/lock waits, and finish before response serialization. UI timing separately captures input/debounce, lane/retry waits, invoke/round trip and synchronous DOM updates. Display latency ends at the DOM update; actual compositor paint and deferred media preview loading are not measured. Their overlapping boundaries must not be summed. Native metrics exclude frontend delays and post-return paint. A fast Rust request does not
prove a responsive first foreground interaction. Conversely, pending setup or
model loading must not be silently included in a warm-query claim.
## Reproducible performance validation
Automatic filesystem refreshes start a new frontend measurement at the refresh
event. `trigger: "filesystem_refresh"` distinguishes them from user searches;
`SHOWN` and `latest_displayed_ms` exclude time spent idle before that event.
`original_input` retains a fixed-size snapshot of the original debounce and
display timings. Refreshes do not replay previous attempts or append ancestor
traces. A refresh before the first response leaves that original response timing
null rather than inventing a first-input measurement.
Record build profile, CPU/device and thread budget, VM/host resources, corpus and
active generation, filters, cold/warm state, concurrent indexing and setup costs.
Use multiple queries and p50/p95 distributions; retain raw reports. Compare basic
and debug mode on the same corpus to quantify instrumentation overhead. Debug
traces guide investigation but are not a substitute for representative benchmarks.
Current recorded filename, actual Google seed and synthetic ANN evidence is in
[VALIDATION](VALIDATION.md) and [SEMANTIC](SEMANTIC.md). Media quality/timing is in
[MEDIA-QUALITY](MEDIA-QUALITY.md). Synthetic vectors measure index behavior only;
real Google inference remains required for product semantic search. Platform,
large-corpus, concurrent-indexing and GPU performance gates remain independent.
## Worker round-trip diagnostics
The retained hybrid service now keeps a bounded 32-query vector LRU. Debug
`semantic.query_embedding` spans report `query_cache_hit` and `query_cache_miss`.
A hit reuses an actual model vector and performs no neural inference; it must
not carry the previous worker's tokenization/inference counters. Filters, current
source eligibility, ANN retrieval and fusion still execute. Warmup performs an
actual neural probe and does not seed an unseen foreground-query result.
Compare fresh queries, repeats and filter changes separately. The current
[EmbeddingGemma 2 audit](EMBEDDINGGEMMA2-AUDIT.md) includes paired real-CPU
measurements, startup boundaries and remaining indexing/media costs.
Measured desktop failures return `{message, metrics}` and retain the trace for
the failed attempt. Busy retries are separate attempts. If an unexpected worker
task failure loses its collector, elapsed time is retained, the trace is null,
and a dropped-span marker makes the missing detail explicit. Error messages are
excluded from the exported timing report.
Embedding IPC spans expose named `*_us` integer counters for request encoding,
writing, worker wait/response decode, validation, and native tokenization, batch
preparation, inference and pooling/normalization when genuinely reported. They
also expose `worker_token_count` and the GPU-to-CPU restart count. Microsecond
counters are durations, not occurrence counts; their suffix records units.
The native worker clock is not aligned with Rust's collector origin. Native
stage values remain counters on the IPC span rather than invented positioned
child spans. Worker wait includes response-reader JSON parsing and scheduling;
it is not pure inference time. The encompassing round trip and its component
counters overlap. A fallback/restart may include setup outside the last worker's
reported neural pass; retain that distinction when diagnosing slow requests.
## Small instrumentation-overhead diagnostic
The deterministic example creates 1,000 local text files, builds/prewarms SQLite,
then alternates basic/debug order over 24 exact filename queries and 20 repeats.
Both modes must retrieve the correct file. It records 480 samples per mode,
outer-call p50/p95/mean and actual debug span counts, excluding fixture setup
and JSON serialization. It runs no model, media decoder or network.