feat: add desktop document search and verified native CPU embeddings
Core CI / core (ubuntu-latest) (push) Failing after 1m22s
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 3m46s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
Core CI / core (ubuntu-latest) (push) Failing after 1m22s
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 3m46s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
This commit is contained in:
1 parent
f77112db97
commit
a9b6592330
46 files changed
+10794
-77
No files matched your search
@@ -33,6 +33,7 @@ enabled. Model downloads and release checks must be explicit operations.
|
||||
- Substring filename search scans the metadata table; the million-file target
|
||||
requires an additional substring index and measured query planning.
|
||||
- Initial indexing publishes after the root transaction finishes.
|
||||
- File extraction currently covers bounded UTF-8 text, not PDF/DOCX/media.
|
||||
- File extraction covers bounded UTF-8, PDF text and DOCX paragraphs. OCR and
|
||||
media extraction remain upcoming work; parser workers are not isolated yet.
|
||||
- No automatic watcher, persistent extraction queue or ANN index yet.
|
||||
- Native CI and signed package validation require actual platform runners.
|
||||
@@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
|
||||
```powershell
|
||||
cargo test --workspace --locked
|
||||
cd apps/desktop
|
||||
npm ci
|
||||
npm run build
|
||||
# Windows VM: all rendering and inference tests must use CPU.
|
||||
$env:WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS='--disable-gpu'
|
||||
npm run tauri -- dev
|
||||
```
|
||||
|
||||
The desktop is a standalone Cargo workspace; validate it separately:
|
||||
|
||||
```sh
|
||||
cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml --locked
|
||||
```
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
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.
|
||||
|
||||
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/.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||
+9
-2
@@ -10,14 +10,14 @@ Status: implementation started; no production release yet. Windows VM tests use
|
||||
- [x] Persistence and filesystem lifecycle integration tests (Windows CPU).
|
||||
|
||||
## 2. Document and semantic retrieval
|
||||
- [ ] Text, Markdown, code, PDF and DOCX extraction with fixtures.
|
||||
- [x] Text, Markdown, code, PDF and DOCX extraction with real fixtures (Windows CPU).
|
||||
- [ ] Validate actual embedding model artifacts, license, CPU runtime and quantization.
|
||||
- [ ] Versioned embeddings, ANN index, exact-match priority and hybrid fusion.
|
||||
- [ ] English/German relevance corpus and measured top-10 recall.
|
||||
- [ ] Atomic model/index replacement and resumable persistent work queues.
|
||||
|
||||
## 3. Desktop
|
||||
- [ ] Tauri shell, accessible keyboard search, progressive results and previews.
|
||||
- [ ] Tauri shell, accessible keyboard search, progressive results and previews (shell built; UI interaction verification pending).
|
||||
- [ ] Folder selection, exclusion controls, resource budgets and indexing status.
|
||||
- [ ] Global shortcut, opening/revealing source files, PDF page navigation.
|
||||
- [ ] Watchers and reconciliation across Windows, macOS and Linux.
|
||||
@@ -45,6 +45,13 @@ Completion requires recorded evidence; targets are not measured results.
|
||||
- Actual CLI process integration tests and independent-reader concurrency test.
|
||||
- TypeScript desktop frontend build and dependency audit passed; native validation underway.
|
||||
- Initial README commit pushed to Gitea main via protected Infisical injection.
|
||||
- Native desktop build and guarded opening tests passed on Windows.
|
||||
- Genuine multilingual CPU model proof: 5/6 top-1, 6/6 recall@3; quality gate remains open.
|
||||
- Native Rust CPU embedding adapter verifies pinned model/tokenizer assets;
|
||||
integration with the search index and platform runtime packaging remain open.
|
||||
- PDF page and DOCX paragraph matches persist; corrupt/encrypted/over-limit
|
||||
documents remain filename-searchable and report extraction errors.
|
||||
- CLI exposes folder/type/size/date filters and additional directory exclusions.
|
||||
|
||||
The partial features above do not close broader production milestones such as
|
||||
crash-resumable jobs, fuzzy retrieval, watcher reliability or performance targets.
|
||||
@@ -0,0 +1,155 @@
|
||||
# CPU semantic inference proof
|
||||
|
||||
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.
|
||||
|
||||
## Model and runtime decision
|
||||
|
||||
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.
|
||||
|
||||
Sources reviewed on 2026-10-12:
|
||||
|
||||
- [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)
|
||||
|
||||
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.
|
||||
|
||||
| Artifact | Bytes | SHA256 |
|
||||
| --- | ---: | --- |
|
||||
| `onnx/model_quantized.onnx` | 118,308,126 | `66fc00f5f29afcaff34092e1bdd20008ca3918265a82fb9695a551e510cc4ebc` |
|
||||
| `tokenizer.json` | 17,082,913 | `b60b6b43406a48bf3638526314f3d232d97058bc93472ff2de930d43686fa441` |
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Measured Windows VM result
|
||||
|
||||
`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**.
|
||||
|
||||
| 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%) |
|
||||
|
||||
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.
|
||||
|
||||
## Native integration contract
|
||||
|
||||
`searchi-semantic` exposes:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -9,6 +9,23 @@ Initial foundation checks (2026-10-12):
|
||||
- `cargo clippy --workspace --all-targets -- -D warnings`: passed.
|
||||
- Rust formatting applied; final formatting verification follows integration.
|
||||
- Desktop TypeScript/Vite build passed; npm audit reported zero vulnerabilities.
|
||||
- Initial Windows desktop native check, embedded app build, strict Clippy and
|
||||
two desktop tests passed (index gate recovery and guarded source opening).
|
||||
- Desktop launched with WebView2 `--disable-gpu`. UI automation could not capture
|
||||
the window: `GetCursorPos` access denied, then monitor capture error
|
||||
`0x80070057`. Visual layout and end-to-end UI interactions remain unverified.
|
||||
- Real Python CPU ONNX embedding proof completed on 8 documents / 6 queries:
|
||||
5/6 top-1 accuracy, 6/6 recall@3. The strict top-1 quality gate is not met.
|
||||
See `tools/semantic-proof/windows-cpu-result.json` for raw timings and rankings.
|
||||
This tiny fixture is not evidence of large-corpus performance.
|
||||
- Native Rust CPU embedding adapter compiled, passed its three unit tests and
|
||||
the explicit local-model smoke test. The smoke reproduced the same 5/6 top-1
|
||||
limitation. Default CI omits this asset-dependent test; it must be executed
|
||||
separately with provisioned local artifacts.
|
||||
- Integrated workspace validation: 19 default tests passed; 1 local-model test
|
||||
is opt-in. Rust formatting and strict Clippy passed after lockfile refresh.
|
||||
- PDF/DOCX fixture tests include matching source locations, corrupt replacement,
|
||||
encrypted PDF behavior and compressed-input limits.
|
||||
|
||||
Not yet established: production latency targets, semantic inference, desktop
|
||||
runtime behavior, Linux/macOS execution, installer signing or upgrades.
|
||||
|
||||
Reference in new issue
Block a user