feat: integrate Google semantic search and branded desktop launcher
Core CI / core (ubuntu-latest) (push) Failing after 3m27s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m45s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s

This commit is contained in:
karl committed 2026-10-12 17:44:56 +02:00
1 parent a90df15503
commit caf6a2f82e
80 files changed
+14971 -837

No files matched your search

+1
View File
@@ -26,6 +26,7 @@ Raycast: compact, keyboard-first search with a grouped result list on the left
and a readable passage preview on the right. Search is dominant; settings,
filters, and model details use progressive disclosure. Use native window chrome,
dialogs, theme behavior, and platform shortcut labels.
The selected screenshot is retained at [assets/design/search-reference.jpg](../assets/design/search-reference.jpg).
Apply brief selection/preview transitions without delaying retrieval or input.
Respect reduced motion and forced colors. Preserve focus, selection, and scroll
+98 -26
View File
@@ -1,46 +1,118 @@
# Build and release targets
Install stable Rust, Node 22+, and native Tauri development prerequisites.
On Windows install Visual Studio C++ build tools and WebView2. Linux needs
WebKitGTK 4.1 development libraries. macOS needs Xcode command-line tools.
See https://v2.tauri.app/start/prerequisites/ for platform details.
Use stable Rust, Node 24 LTS, Python 3.11+, Git, CMake, and a native C/C++
toolchain. Python provisions the pinned Google runtime and model; inference
runs in a native process. Default Rust tests do not download model assets.
Windows needs Visual Studio C++ build tools, a Windows SDK, and WebView2.
Linux desktop builds need WebKitGTK 4.1 development libraries; macOS needs
Xcode command-line tools. Follow the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/).
Headless Linux CLI/worker builds do not need WebKitGTK or a display server.
They still need a C/C++ compiler, linker, CMake, and Rust: SQLite, USearch,
NumKong, and the Google worker contain native code.
## Windows CPU development
Run from the repository root. Building the worker clones a pinned llama.cpp
revision and verifies/applies its memory patch. Model provisioning explicitly
uses the network and verifies both Google assets, approximately 865 MB total.
The Python CMake package is needed only when CMake is absent from PATH.
```powershell
python -m pip install cmake
python tools/embeddinggemma2/build_runtime.py --backend cpu --jobs 2
python tools/embeddinggemma2/stage_runtime.py --backend cpu
python tools/embeddinggemma2/download.py
$env:SEARCHI_FORCE_CPU = '1'
$env:SEARCHI_GEMMA_MODEL_DIR = (Resolve-Path .searchi/models/embeddinggemma2).Path
$env:SEARCHI_GEMMA_WORKER = (Resolve-Path .searchi/runtime/cpu/Release/searchi-gemma-worker.exe).Path
cargo fmt --all --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
cd apps/desktop
cargo test -p searchi-semantic --test gemma_cpu -- --ignored --nocapture
cargo test -p searchi-service --test google_cpu -- --ignored --nocapture
cargo test -p searchi-service --lib google_cpu_preserves -- --ignored --nocapture
```
The worker is statically linked with the MSVC CRT on Windows. Staging copies
it and the llama.cpp license into the desktop resources directory. Add
`--bundle-model` to staging for an offline model bundle after downloading;
otherwise desktop setup provisions verified models on first launch. Search
itself performs no network inference or downloads. Media weights are staged
for future integration; the current worker supports text only.
The desktop is a standalone Cargo workspace and needs separate validation:
```powershell
cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml --locked
Set-Location apps/desktop
npm ci
npm run format:check
npm test
npm run build
# Windows VM: all rendering and inference tests must use CPU.
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS='--disable-gpu'
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = '--disable-gpu'
npm run tauri -- dev
```
The desktop is a standalone Cargo workspace; validate it separately:
Every Windows VM inference/rendering test must stay CPU only. Production
supports `--backend auto|metal|vulkan|cuda` builds with CPU fallback; do not
exercise those acceleration backends in this VM. Their execution and failure
recovery require validation on the corresponding release hardware.
## Headless Linux Google search
These are the current script and CLI interfaces, not evidence of an executed
Linux release. On a native Linux build host, run from the repository root:
```sh
cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml --locked
python3 tools/embeddinggemma2/build_runtime.py --backend cpu --jobs 2
python3 tools/embeddinggemma2/download.py
export SEARCHI_FORCE_CPU=1
cargo build --release -p searchi-cli --locked
./target/release/searchi index --db searchi.sqlite --root /path/to/documents
./target/release/searchi embed --db searchi.sqlite --model-dir .searchi/models/embeddinggemma2 --embedding-worker .searchi/runtime/cpu/searchi-gemma-worker --cpu-threads 1
./target/release/searchi search --db searchi.sqlite 'supplier cancellation terms' --model-dir .searchi/models/embeddinggemma2 --embedding-worker .searchi/runtime/cpu/searchi-gemma-worker --cpu-threads 1
```
## Cross-compilation
`searchi setup --model-dir PATH` is an alternative verified model-provisioning
command. It provisions model assets, not the native worker. Package the worker
separately and pass its path to headless embedding/search. Each short-lived CLI
search starts a model process; the desktop retains a prewarmed query worker.
The Rust engine has no GUI dependency. Add the destination Rust target with
`rustup target add TARGET`, then use `cargo build -p searchi-cli --target TARGET`.
This requires the target linker, C toolchain and SDK because SQLite is compiled
from bundled C. Target installation alone is insufficient. Document each
verified host/target pair before treating it as supported.
## Cross-compilation and native release matrix
Desktop builds also need the platform webview libraries and packaging tools.
Use native runners for dependable release builds. macOS signing/notarization
needs Apple credentials and tooling. Windows installer cross-builds have
additional Tauri caveats: https://v2.tauri.app/distribute/windows-installer/.
The shared Rust engine/service has no GUI dependency. Install a destination
Rust target with `rustup target add TARGET`, then build using
`cargo build -p searchi-cli --target TARGET --locked`. This also requires the
target C/C++ toolchain, linker, and SDK for bundled SQLite and the vector index.
The separate native Google worker must be compiled for the same destination;
installing a Rust target does not cross-compile it. The current Python runtime
script configures the host toolchain; it does not expose a CMake cross-toolchain
file interface. Record each verified host/target pair before claiming support.
| Release host | Intended artifacts | Remaining validation |
| --- | --- | --- |
| Windows | Windows CLI, worker, desktop installer | Installer, upgrade, signing, GPU hardware |
| macOS | Apple Silicon/Intel CLI, worker, desktop bundle | Native builds, architecture parity, Metal, notarization |
| Linux | CLI, worker, desktop packages | Native builds, distribution ABI, webview, acceleration |
Use native runners for dependable desktop releases. Platform webviews,
packaging tools, SDKs, and signing impose additional constraints. macOS
signing/notarization requires Apple tooling and credentials. See the
[Tauri Windows installer cross-build caveats](https://v2.tauri.app/distribute/windows-installer/).
## CI and packaging gates
Both Gitea and GitHub workflow files are provided. Gitea needs registered runners
matching the configured OS labels; this repository does not provision runners.
No Linux/macOS checks are considered passed until actual job evidence exists.
GitHub and Gitea workflows define native OS matrices. Gitea requires registered
runners matching its configured labels. A workflow declaration does not prove
a platform was tested; Linux/macOS gates remain open until actual job evidence
exists. Current workflow checks do not certify the separately built Google
worker or execute downloaded-model tests automatically.
Current bundles are disabled during development. Enable installers only after
packaging icons, native smoke tests, CPU model distribution and license review,
upgrade/migration tests, signatures and rollback checks are ready. Do not place
private signing keys, repository tokens or model credentials in source control.
Desktop bundles remain disabled during development. Before enabling release
installers, stage the target worker, retain dependency/model notices, verify
clean-machine launch and setup, run native Google smoke tests, and complete
upgrade/migration, signatures, and rollback checks. Optional offline bundles
need both verified model files. See [semantic bounds and evidence](SEMANTIC.md)
for current text-only, corpus, and performance limitations. Keep signing keys,
repository tokens, and model credentials outside source control.
+18
View File
@@ -2,6 +2,21 @@
Status: implementation started; no production release yet. Windows VM tests use CPU only.
## Required product scope (user clarification)
- Desktop UI is primary; semantic setup/indexing/search must require no terminal.
- Google EmbeddingGemma 2 is the required production model, matching DigUp.
- Local document, image, audio and video search are required product milestones.
- A separate CLI-only build supports headless Linux without desktop dependencies.
- Production automatically uses available hardware acceleration with CPU fallback;
this Windows VM is tested in forced-CPU mode only.
- Installer ships the native worker. First launch automatically downloads/verifies
missing model files and manages indexing in the UI; no terminal setup is required.
- Earlier MiniLM proof is an experiment and does not satisfy the model requirement.
- First interaction must be responsive: prepare indexes and a real Google query
in the background, retain ready sessions, and show immediate keyword results.
Model download and initialization must have honest progress and retry states.
## 1. Search foundation
- [x] Rust workspace, reusable engine, CLI, versioned SQLite storage.
- [ ] Filename/path and ranked full-text retrieval with strict filters.
@@ -30,6 +45,9 @@ Status: implementation started; no production release yet. Windows VM tests use
- [ ] Formatting, lint, tests and security/dependency review.
- [ ] CPU benchmarks: filename p95 <50 ms/1M records; text <150 ms/100K documents; semantic <500 ms on declared hardware.
- [ ] Measure cold start, indexing throughput, RAM, disk and idle CPU.
- [ ] Record the very first foreground query and distinct unseen queries after
production background preparation; report initialization time separately.
Warm p95 alone does not satisfy the first-use requirement.
- [ ] Test migrations, interrupted work, invalid documents, inaccessible/offline roots and cloud placeholders.
- [ ] Automated native build matrix and documented supported cross-compilation paths.
- [ ] Execute Linux/macOS platform tests; create Windows/macOS/Linux installers.
+158 -134
View File
@@ -1,155 +1,179 @@
# CPU semantic inference proof
# Local semantic search
This milestone runs genuine neural embeddings locally. It does not yet connect
semantic vectors to the SQLite search index or desktop interface. Production
retrieval quality, large-corpus performance, and Linux/macOS runtime packaging
remain unverified.
Searchi uses **Google EmbeddingGemma 2**, with the pinned Q8 GGUF text encoder
and llama.cpp revision used by DigUp. Production has no MiniLM, simulated-vector,
or remote embedding fallback. The rejected ONNX experiment is retained only
under the opt-in minilm-proof feature and tools/semantic-proof/HISTORICAL.md.
## Model and runtime decision
## Model and runtime
The first working baseline is the quantized ONNX export of
`sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2`, published by
`Xenova`. The upstream model card describes 384-dimensional text embeddings,
attention-mask mean pooling, a 128-token maximum, and Apache-2.0 licensing.
It covers multiple languages. This is a text-only baseline; it does not claim
EmbeddingGemma 2's multimodal features or compatibility.
- Model: google/embeddinggemma-2, **768-dimensional** output.
- GGUF publisher: ggml-org/embeddinggemma-2-GGUF.
- Revision: bfcd298762cc34d0357ece5ebdd31791a3a374d8.
- llama.cpp: b11461, commit 4d756bc72bf00a4aacf410ae15a2d315f3db400d,
with DigUp's no-logits memory patch.
- Query prompt: task: search result | query: TEXT.
- Document prompt: title: TITLE_OR_none | text: TEXT.
- Noncausal encoder, mean pooling, finite L2-normalized vectors.
- Query/document token budgets: 512/2048.
Sources reviewed on 2026-10-12:
The persistent native helper uses bounded NDJSON over stdin/stdout. It has no
HTTP server or download code. Rust verifies the text model's length and SHA256
before starting it. Setup provisions assets; search never downloads them.
- [Original model card and pooling architecture](https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2)
- [ONNX export publisher](https://huggingface.co/Xenova/paraphrase-multilingual-MiniLM-L12-v2)
- [ONNX Runtime Python session API](https://onnxruntime.ai/docs/api/python/api_summary.html)
- [Rust ort dynamic-library initialization](https://docs.rs/ort/2.0.0-rc.13/ort/environment/fn.init_from.html)
- [Rust ort session configuration](https://docs.rs/ort/2.0.0-rc.13/ort/session/builder/struct.SessionBuilder.html)
Production device mode is auto, with available compiled acceleration and CPU
fallback. Model/context initialization and returned inference/nonfinite-output
failures retry on CPU once. A lost GPU worker can be restarted as CPU for one
retry of that request. WorkerInfo and responses report the actual device.
**Windows VM tests remain CPU only**, via SEARCHI_FORCE_CPU=1 and Device::Cpu.
GPU execution/failure recovery has not been exercised here.
Inference explicitly selects `CPUExecutionProvider`. Python uses the CPU
`onnxruntime` wheel, never `onnxruntime-gpu`. The native Rust crate disables ort
default features: there are no binary downloads, GPU provider features, or model
HTTP client features. It loads an explicitly supplied local runtime library and
disables runtime telemetry. Tokenization is sequential; ONNX sessions use
sequential graph execution with bounded intra-op threads and one inter-op thread.
## Reproduce on Windows
Run these commands from the repository root. Provisioning commands intentionally
use the network; the inference command does not provision anything.
```powershell
python -m venv tools/semantic-proof/.venv
& tools/semantic-proof/.venv/Scripts/python.exe -m pip install --only-binary=:all: -r tools/semantic-proof/requirements.txt
& tools/semantic-proof/.venv/Scripts/python.exe tools/semantic-proof/download.py
& tools/semantic-proof/.venv/Scripts/python.exe tools/semantic-proof/proof.py --threads 1 --output tools/semantic-proof/windows-cpu-result.json
```
On Linux/macOS, use `.venv/bin/python` instead of `.venv/Scripts/python.exe`.
These instructions have only been executed on Windows. Wheel availability and
native library distribution must be checked on other platforms.
`download.py` downloads exactly two revision-pinned artifacts, streams them to a
temporary file, rejects oversized downloads, checks byte length and SHA256, then
atomically replaces the local asset. Assets occupy approximately 136 MB in
decimal units and are ignored by Git. Inference validates both files again and
fails clearly when either is missing or damaged. It never contacts the model
hub. The Python proof sets offline environment flags and rejects Python socket
connect, name-resolution, and bind audit events throughout import and inference.
This guard checks Python socket activity; it is not an operating-system firewall
against arbitrary native libraries.
The proof intentionally exits nonzero if any fixture query misses top-1. Its
JSON report is written before the quality gate, preserving failures for review.
## Pinned artifacts and licensing
Revision: `2c4055b12046f11709e9df2c122e59ffbdc2f900`.
The manifest in `tools/semantic-proof/model-manifest.json` records the same
model contract and hashes used by the native adapter.
The Windows worker links a static MSVC CRT and static llama libraries, without
an external OpenMP runtime. Production CMake supports cpu, auto, metal, vulkan,
and cuda; CPU builds force GPU flags off. Runtime/provider parity and packaging
on other operating systems remain independent release checks.
| Artifact | Bytes | SHA256 |
| --- | ---: | --- |
| `onnx/model_quantized.onnx` | 118,308,126 | `66fc00f5f29afcaff34092e1bdd20008ca3918265a82fb9695a551e510cc4ebc` |
| `tokenizer.json` | 17,082,913 | `b60b6b43406a48bf3638526314f3d232d97058bc93472ff2de930d43686fa441` |
| embeddinggemma-2-Q8_0.gguf | 309,855,456 | 2188ac1deca4b77dffefd603c2776a9d76d9d74ec01841392982ebb840b09135 |
| mmproj-embeddinggemma-2-Q8_0.gguf | 554,821,024 | c4a8a52691ecef40618438928bdf9e68379b854e24166f292592353db0aab64f |
The base model card specifies Apache-2.0. The export card identifies that base
model but does not display its own license declaration. Before redistributing
the ONNX export in installers, confirm export licensing and preserve the base
license, attribution, and applicable notices. Current code explicitly downloads
user-local assets and does not ship model weights or runtime DLLs in Git.
ONNX Runtime uses MIT licensing; ort uses MIT or Apache-2.0 and tokenizers uses
Apache-2.0. Release packaging must retain third-party notices and validate
platform-specific runtime hashes independently; a model hash does not attest
to the runtime library.
Setup downloads both pinned files. **The current worker implements text**;
image/audio projection loading and image/audio/video embeddings remain required
work. Downloaded media weights do not establish functioning multimodal search.
The tested Windows ONNX Runtime 1.31.0 DLL is 19,288,888 bytes with SHA256
`90497e3d406c09f4d59d364c696a2f93dc02f6ef13741b3b89eec95bdb4a3806`.
The adapter currently trusts the explicitly supplied runtime path; it validates
model hashes, not runtime-library hashes. A release distribution must add a
platform runtime manifest before shipping. `requirements-lock-windows.txt`
captures the exact Python environment used for this proof.
Weights use Apache-2.0; llama.cpp and DigUp use MIT; USearch and NumKong use
Apache-2.0. Retain notices with distributions. Five DigUp text reference vectors
are copied under MIT in crates/searchi-semantic/tests/fixtures with the upstream
license and source commit alongside them.
## Measured Windows VM result
Primary sources:
`tools/semantic-proof/windows-cpu-result.json` contains the full measurement and
rankings. The run used Windows 11 AMD64, Python 3.14.8, ONNX Runtime 1.31.0,
four visible logical CPUs, and **one inference thread with only the CPU provider**.
- [Google developer guide](https://developers.googleblog.com/embeddinggemma-2-the-developer-guide/)
- [Model documentation](https://huggingface.co/docs/transformers/model_doc/embedding_gemma2)
- [Pinned GGUF publisher](https://huggingface.co/ggml-org/embeddinggemma-2-GGUF/tree/bfcd298762cc34d0357ece5ebdd31791a3a374d8)
- [Pinned DigUp reference](https://github.com/ARahim3/DigUp/tree/6faa29e4c315a3a591de1b41bd78751bdf39588d)
- [USearch HNSW and filtered retrieval](https://github.com/unum-cloud/USearch)
## Shared API and bounds
GemmaEmbedder owns actual tokenization, document/query prompts, and inference.
HybridSearch is the shared CLI/desktop service:
~~~rust
HybridSearch::open(db, model_dir, worker_executable, threads)
HybridSearch::embedding_status(db) // No model/runtime load or network
service.warmup() // Real query inference + ANN cache
service.index_embeddings()
service.search(query, limit, &SearchOptions)
service.search_semantic(query, limit, &SearchOptions) // Diagnostics
service.worker_info() // Actual model/runtime/device/threads
~~~
Threads are bounded to 1–8; VM tests use one. Document batches contain at most
eight windows. Request/response budgets are 2/4 MiB, startup has a 120-second
deadline, and each request has a 180-second deadline. Malformed or interrupted
IPC and invalid embeddings fail explicitly.
The service makes 64 KiB UTF-8 slices with 512-byte overlap before genuine model
token windows. It preserves global byte ranges and page/paragraph/line sources,
handles 2 MiB passages, caps each passage at 2048 windows, and bounds titles to
512 UTF-8 bytes. Generation fingerprints include this chunk policy as well as
model/runtime/prompts/token budgets/normalization.
Keep a prewarmed query service and a separate background builder. Readiness
requires actual inference, rather than merely finding verified model files.
## Persistence, ANN, and ranking
Semantic storage has an independent schema version within the shared SQLite
database. Chunks store generation, passage/path identity, original-source hash,
location, byte range, snippet, and vector. HNSW uses USearch 2.26.4, cosine/F32,
16 connections, construction expansion 128, and search expansion 64. NumKong
dispatches supported CPU SIMD kernels with portable fallback. The Cargo config
contains the Windows NK_DYNAMIC override required for static NumKong linkage.
Staging vectors and a real HNSW graph are persisted with an ANN blob SHA256.
Activation is atomic. Failed rebuilds preserve the active generation; the next
rebuild reclaims abandoned staging under a cross-process lock. Search uses a
consistent read snapshot.
Metadata filters and source hashes establish eligible keys before ANN top-k.
The cache is keyed by generation, corpus revision, and normalized filters.
Persistent dirty-path triggers invalidate affected files; unchanged warm
queries hash zero passages. Large change batches or expired history rebuild
eligibility. Default-filter prewarm includes that initial work.
Fusion uses reciprocal-rank fusion with k = 60. Exact filenames and literal
identifiers retain priority. Ordinary partial filenames receive lexical
weight 1.15 and can be outranked by keyword/semantic consensus. File results
retain source snippets and deterministic path tie breaks.
Current caps are 100,000 chunks and a 512 MiB serialized ANN blob per generation.
Full rebuilds still regenerate embeddings and the graph. Incremental reuse/jobs
and efficient ANN updates remain production work. One million filename records
does not imply one million semantic chunks under these defaults.
## Executed Windows CPU evidence
Actual Google CPU vectors match five pinned DigUp text references at cosine
**0.99979–0.99994**, exceeding the 0.999 gate. These cover English, Bengali,
Arabic, a short document, and a document beyond the sliding attention window.
Actual tests also cover English/German retrieval, persisted vectors, changed/
deleted-source suppression, verified long windows, and a tail **after 64 KiB**.
The immutable 20-document/24-query seed corpus produced:
| Lane | Top 1 | Recall at 3 |
| --- | ---: | ---: |
| Lexical | 5/24 | 5/24 |
| Google semantic | 24/24 | 24/24 |
| Hybrid HNSW | 24/24 | 24/24 |
With one CPU thread, fresh model/context startup took approximately **7 seconds
in the background**, actual query/ANN prewarm **128 ms**, and first foreground
natural-language search **99 ms** with the correct supplier document first.
Warm seed-corpus hybrid p50/p95 was **92/107 ms**. Model downloads are excluded.
A separate release-profile benchmark used 100,000 synthetic normalized 768-dimensional
vectors and 20 queries against exact nearest neighbors:
| Metric | Measurement |
| --- | ---: |
| Fixture documents / queries | 8 / 6 |
| Timed warm query runs | 60 |
| Artifact verification plus runtime/model load | approximately 3.4 seconds |
| Corpus batch embedding | approximately 145 ms |
| Warm query p50 / p95 | approximately 3.1 / 11.9 ms |
| Top-1 accuracy | 5/6 (83.3%) |
| Recall at 3 | 6/6 (100%) |
| Recall at 10 vs exact | 98.5% |
| HNSW query p95 | 1.37 ms |
| Warm service retrieval p95 | 6.40 ms |
| Warm passages rehashed | 0 |
| Initial eligibility work | 1.61 seconds |
| Graph construction/serialization | 57.95 seconds |
| Reported graph memory | 554 MB |
| Dispatched CPU kernel | skylake |
The corpus includes English and German documents, same-language semantic
queries, and cross-language queries. A question about a postponed product
release ranks the supplier contract above the expected meeting notes. That
failure remains in the fixture and blocks the strict top-1 quality gate.
This small demonstration supports the feasibility of CPU inference; it does
not establish large-corpus latency, robust multilingual quality, or production
readiness. Quantization and batch shape can affect similarity scores.
This is **index-only performance**, not neural quality across 100,000 documents.
The seed corpus and synthetic vectors do not certify production relevance.
Representative corpora, cold/selective-filter latency, concurrent indexing,
resource profiles, GPU parity/fallback, multimodal retrieval, and platform
releases remain validation gates.
## Native integration contract
## Reproduce
`searchi-semantic` exposes:
Run from the repository root. Provisioning uses the network explicitly:
```rust
CpuEmbedder::load(model_dir, runtime_library, threads) -> Result<CpuEmbedder>
CpuEmbedder::encode(&mut self, texts: &[&str]) -> Result<Vec<Vec<f32>>>
DIMENSIONS // 384
MODEL_FINGERPRINT // revision + quantization + pooling + normalization + token cap
```
~~~powershell
python tools/embeddinggemma2/download.py
python tools/embeddinggemma2/build_runtime.py --backend cpu
$env:SEARCHI_FORCE_CPU = '1'
$env:SEARCHI_GEMMA_MODEL_DIR = (Resolve-Path .searchi/models/embeddinggemma2).Path
$env:SEARCHI_GEMMA_WORKER = (Resolve-Path .searchi/runtime/cpu/Release/searchi-gemma-worker.exe).Path
cargo test -p searchi-semantic --test gemma_cpu -- --ignored --nocapture
cargo test -p searchi-service --test google_cpu -- --ignored --nocapture
cargo test -p searchi-service --lib google_cpu_preserves -- --ignored --nocapture
cargo run -p searchi-service --example evaluate -- .searchi/models/embeddinggemma2 .searchi/runtime/cpu/Release/searchi-gemma-worker.exe .searchi/google-relevance-ann.json
$env:SEARCHI_ANN_REPORT = (Join-Path (Get-Location) '.searchi/ann-100k.json')
cargo test --release -p searchi-service ann_100k -- --ignored --nocapture
~~~
Inputs are bounded to eight texts per batch, 64 KiB UTF-8 per text, and 128
tokens. Outputs are finite, normalized `f32` vectors. The runtime library is
process-global; adapter initialization rejects attempts to switch libraries or
silently accept an environment initialized outside the adapter. Supply a known,
trusted runtime before calling any other ort APIs in the process.
Default unit tests need no model or runtime. The real-artifact test is opt-in:
```powershell
$env:SEARCHI_MODEL_DIR = (Resolve-Path tools/semantic-proof/model).Path
$env:SEARCHI_ORT_LIBRARY = (Resolve-Path tools/semantic-proof/.venv/Lib/site-packages/onnxruntime/capi/onnxruntime.dll).Path
cargo test -p searchi-semantic --test cpu_model -- --ignored --nocapture
```
The smoke test checks actual local inference, vector normalization, English and
German retrieval, recall at three, and the measured five-of-six top-1 baseline.
It does not replace the strict production quality gate.
The native real-artifact smoke was executed successfully on the Windows VM,
using that CPU-only DLL. It reproduced five-of-six top-1 and six-of-six recall
at three. Three default unit tests passed; targeted Clippy passed with warnings
denied. Linux and macOS native checks have not been executed.
The next integration should read bounded `SearchIndex::passage_batch` rows,
split long passages into overlapping tokenizer windows, preserve source page or
paragraph locations, and persist each vector with a content fingerprint and
`MODEL_FINGERPRINT`. Passage IDs are not immutable content identities: changes
must invalidate stale vectors. Queries should combine lexical and semantic
retrieval while preserving exact filename priority. Model upgrades build a
separate vector generation before an atomic swap. Cancellation, persistent
embedding jobs, ANN retrieval, representative quality corpora, and signed
cross-platform runtime packaging are still required.
The ignored ANN test deliberately requires release mode. Default tests require
no model/network and cover protocol bounds, invalid vectors, UTF-8 coverage,
fusion, lifecycle, checksums, pre-top-k filtering, and dirty-path caching.
Linux/macOS and GPU checks are not inferred from this Windows CPU run.
+10 -1
View File
@@ -5,7 +5,7 @@ All local tests run on CPU; no GPU provider is configured.
## Current integration checkpoint (2026-10-12)
- `cargo test --workspace --locked`: 39 default tests passed. Four asset-dependent
- `cargo test --workspace --locked`: 41 default tests passed after final core integration. Four asset-dependent
or explicit benchmark tests remain opt-in; a default pass does not run them.
- Native desktop tests: 7 passed with SEARCHI_FORCE_CPU=1 and WebView2 GPU disabled.
- Frontend: 7 async-state tests passed, Prettier passed, TypeScript/Vite build passed.
@@ -18,6 +18,15 @@ All local tests run on CPU; no GPU provider is configured.
blocked because browser bootstrap and native screen capture are unavailable.
No visual match or complete UI interaction verification is claimed.
Final UI integration: the branded compact launcher, local Inter/Fluent assets,
themes and motion implementation passed frontend build, formatting, and seven
state tests. Native launch succeeded; accessibility text showed real controls
and a warmed Google CPU worker. UI input and screenshots remain blocked by
Windows access/capture errors, as recorded in design-qa.md. Workspace formatting
and strict all-target Clippy passed. The fixed full-corpus first-input report
is in crates/searchi-core/benchmarks/results/windows-cpu-full-candidate-first-final.json;
all 40 measured filename inputs were below 50 ms in that run.
The active parallel development branches of work may add tests or change counts
after this checkpoint. Run the documented checks again after integration.