Skip to content

feat(#53): real local neural embedder via node sidecar (supersedes onnxruntime-web approach) - #69

Merged
veltri-23 merged 19 commits into
task/vibebloat-mvpfrom
feat/local-embedder-node-sidecar
Jul 21, 2026
Merged

feat(#53): real local neural embedder via node sidecar (supersedes onnxruntime-web approach)#69
veltri-23 merged 19 commits into
task/vibebloat-mvpfrom
feat/local-embedder-node-sidecar

Conversation

@veltri-23

Copy link
Copy Markdown
Owner

Closes #53. Makes recall = local a real offline semantic embedder — verified against the live model, not a stub.

Root cause of the prior blocker (PR #54)

PR #54 forced onnxruntime-web in-process. Under Bun on Windows that registers zero execution providers (Unsupported device: "cpu"), and the transformers web build has no filesystem under Bun. The only combination that actually produces vectors is the transformers node build + onnxruntime-node under real Node. Reproduced both failures directly.

Approach

The Bun CLI shells out to a short-lived node sidecar (src/ingest/embed-worker.mjs) for embeddings and stays on its fast path. node is present wherever npx installs. Any failure degrades to no-recall — never throws into enforcement.

  • recall-local.ts rewritten to embed via the sidecar; the broken onnxruntime-web override is gone. Injectable Embedder for tests.
  • Per-backend warn threshold: cosine on short commands lands ~0.3, so the Jaccard-calibrated 0.5 never fires. localRecallWarnThreshold = 0.25 (documented calibration knob). Runtime uses adapter.warnThreshold ?? global.
  • Hook wired to async recallAdvisory on the allow path for local/embed, gated on config mode before any store I/O — the default lexical path opens no SQLite. Close is crash-proofed (a locked handle can't take down the hook).
  • @huggingface/transformersoptionalDependencies; redundant onnxruntime-web dep dropped.

Verification

  • tests/recall-local.test.ts ported to the Embedder API — 11 pass.
  • tests/recall-local-realmodel.test.ts (new) drives the REAL MiniLM: a genuinely reworded command with zero shared tokens recalls the incident above threshold where lexical scores exactly 0; stays silent on unrelated commands. Skips honestly (not green-stub) if the model can't load. 2 pass.
  • End-to-end through bun src/cli.ts hook: local mode + seeded incident + paraphrase prints the advisory (exit 0); unrelated + default-lexical stay silent.
  • Full suite: 776 pass, 0 fail.

Note on overlap

Supersedes the onnxruntime-web core of #54 / local-embedder-fixes; keeps their store embedding column, onboarding gate, and dims/degrade contract. Recommend landing this and closing #54.

🤖 Generated with Claude Code

veltri-23 and others added 4 commits July 21, 2026 00:01
recall = local now runs genuine offline semantic recall. Root cause of the
prior blocker (PR #54): forcing onnxruntime-web in-process gives Bun an empty
execution-provider list ("Unsupported device: cpu"), and the transformers web
build has no fs under Bun. Only the transformers *node* build + onnxruntime-node
under real Node produces vectors — so the Bun CLI shells out to a `node`
sidecar (embed-worker.mjs) for embeddings and stays on the fast path.

- embed-worker.mjs: node sidecar, stdin texts -> stdout MiniLM vectors, model
  cached under the guard home, offline after first pull.
- recall-local.ts: rewritten to embed via the sidecar; rips out the broken
  onnxruntime-web override. Degrades to [] / no-embedding on any failure.
- Per-backend warn threshold: cosine on short commands lands ~0.3, so the
  Jaccard-calibrated 0.5 never fires. localRecallWarnThreshold=0.25 (calibration
  knob documented). runtime uses adapter.warnThreshold ?? global.
- Hook wired to async recallAdvisory on the allow path for local/embed, so a
  paraphrase-level warning fires live where the sync lexical hot path can't.
- transformers moved to optionalDependencies; onnxruntime-web dep dropped.
- Tests: recall-local.test.ts ported to the Embedder injection API (11 pass);
  new recall-local-realmodel.test.ts drives the REAL model — a zero-shared-token
  paraphrase recalls the incident above threshold where lexical scores 0 (2
  pass), skips honestly if the model can't load.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Testing the real CLI hook surfaced two issues on the allow path:

1. Double-close crash: close() was called in both the try and the catch, and
   IncidentStore.close(true) throws on a locked handle — the second throw (from
   the catch) escaped and killed the hook with exit 1. Enforcement must never
   crash. Now closes exactly once in `finally` with a swallowed error.
2. Per-hook cost: every allow-path hook opened the incident store before
   checking the mode. Now gates on the config mode first (one existsSync +
   small TOML read); lexical/off/no-config returns before any SQLite I/O.

Verified end to end through `bun src/cli.ts hook`: local mode + a seeded
incident + a zero-shared-token paraphrase prints the recall advisory (exit 0);
unrelated commands and the default lexical path stay silent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@veltri-23

Copy link
Copy Markdown
Owner Author

PR #69 code remediation complete at 0e22f5525b3a0c558ef5b68a4aeb9c9f4e70c965.

Verified:

  • Local/embed recall uses async advisory only; lexical alone uses sync recall.
  • Hook regression proves exactly one local-mode warning and fails with 2 lines when duplicate routing is reintroduced.
  • Destructive-shape prefilter blocks benign same-family false positives before embedding while preserving the natural-language stash paraphrase.
  • Sidecar spawn, worker trust boundary, fail-open advisory containment, backend threshold plumbing, real-model gate, optional dependencies, GNU tar portability, and clean-checkout tests independently audited.
  • bun test: 804 pass, 0 fail.
  • Required live MiniLM: 3 pass, 0 fail.
  • Forced GNU tar 1.35 package smoke: 1 pass, 0 fail.
  • bun run build and git diff --check: clean.
  • Independent Claude [P0] Judge-proof init: scan must not dead-end on a stranger's machine #1 verdict: SHIP; no reproducible code bugs.

Merge blocker is external: GitHub Actions jobs never start because account payments failed or Actions spending limit must increase. Latest check annotation says exactly that. PR merge state is UNSTABLE, not conflicted. Do not merge until billing/spend limit is fixed and CI reruns green.

@veltri-23
veltri-23 merged commit 05dcf34 into task/vibebloat-mvp Jul 21, 2026
2 of 14 checks passed
@veltri-23
veltri-23 deleted the feat/local-embedder-node-sidecar branch July 21, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Real local neural embedder for recall = local (offline semantic recall, no API key)

1 participant