Repository navigation
feat: zero-download semantic fallback — algorithmic embeddings + code-aware FTS (#169, Phase B) - #181
Merged
Merged
Conversation
…#169) Phase B — reimplements #169 on the merged provider/lifecycle/factory seams. 1. Second provider: AlgorithmicEmbeddingProvider (embedding_fallback_provider.py) implements EmbeddingProvider via shared.algorithmic_embedding (TF + Random Indexing + co-occurrence bridging). The factory selects per ModelState — embedding_factory.use_fallback maps every non-LOADED state (PACKAGE_ABSENT, MODEL_FILES_ABSENT, LOAD_RAISED, UNINITIALIZED) to the fallback and LOADED to neural; the mapping is total (no state maps to nothing). The lifecycle no longer blocks or crashes: MODEL_FILES_ABSENT and LOAD_RAISED serve fallback this session and fetch in the background (embedding_downloads.py), upgrading next session. 2. Root-cause fix: SqliteMemoryStore stamps embedding_model UNCONDITIONALLY on write (outside the _has_vec branch) — 'fallback' even with sqlite-vec absent, never ''. 3. Loud: one WARNING when the fallback engages + get_telemetry embedding_mode. 4. Code-aware FTS on all recall paths: camelCase/snake_case sub-tokens at index time (augment_content) and query time (recall WRRF _signal_fts, entity MATCH, and recall_helpers.compute_vector_fts). memories_fts converted to self-content with a one-shot rebuild+reindex migration. 5. Scheduled upgrade: consolidation/embedding_upgrade.run_embedding_upgrade_cycle re-embeds fallback-stamped memories with neural once available and restamps them, wired into consolidate's compress phase; count in the response. 6/8. Mixed store never cross-ranks (query-space vec filter); genuine sentence-transformers absence + empty HF_HOME covered by a subprocess test. Co-Authored-By: Claude Fable 5 <[email protected]>
SQLite-specific harness (reuses the production harness's dataset + scoring) that compares no-vector / algorithmic fallback / sentence-transformers, since the PG harness has no such toggle. n=50 on this PR's code (commit 8347944): no-vector MRR 0.275 / R@10 46% → fallback 0.378 / 66% (+0.102 MRR, +20pp) → neural 0.609 / 94%. Fallback beats the no-vector baseline — adoption criterion met. Results + MANIFEST under benchmarks/results/semantic-fallback-169/. Co-Authored-By: Claude Fable 5 <[email protected]>
…additions The unconditional embedding_model stamp, select_fallback_embeddings, reembed_memory, and the FTS augment/migration shifted the SQLite heat writers (447/477/541 → 493/523/587). Pins updated per the test's own instructions; no new heat writer introduced. Co-Authored-By: Claude Fable 5 <[email protected]>
This was referenced Jul 25, 2026
Closed
Closed
github-actions Bot
pushed a commit
that referenced
this pull request
Nov 10, 2026
…et (ADR-1129) (#965) A pull request reviewed by the workflow that preceded the cap and the verdict line had its budget used by reviews that posted no verdict: the review was skipped on every new head and the merge was held for ever (ai-architect-mcp-spec #182, #184, #181; ai-architect-mcp-codebase #484, #481, #478, #476 on 2026-11-10). A run now counts only if it has the Claude review budget job. Claude-Session: https://claude.ai/code/session_018kyZYsWnKSjpX4oNV19PCF Signed-off-by: Claude <[email protected]> Co-authored-by: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase B — full #169 on the merged #173 seams
Reimplements the zero-download semantic fallback on the provider / lifecycle /
factory seams from PR #175, with no monolith and the root cause fixed.
Closes #1691. Fallback provider, selected by the factory per
ModelStateembedding_fallback_provider.AlgorithmicEmbeddingProvider— the SECONDEmbeddingProvider(the neuralEmbeddingEngineis the first). Deterministic,download-free, same
EMBEDDING_DIM; delegates toshared.algorithmic_embedding(TF + Random Indexing + within-document co-occurrence bridging; sources in the
module docstring).
embedding_factory.use_fallback(state)is the total state→provider map:LOADED→ neural;PACKAGE_ABSENT,MODEL_FILES_ABSENT,LOAD_RAISED,UNINITIALIZED→ fallback. No state maps to nothing (test asserts totality).MODEL_FILES_ABSENT/LOAD_RAISEDserve fallback this session and fetch in the background
(
embedding_downloads.py, honouringCORTEX_EMBEDDING_ZERO_DOWNLOAD), upgradingnext session.
2. Root-cause fix (the PR #172 empty-stamp bug)
SqliteMemoryStorestampsembedding_modelunconditionally on write, outsidethe
_has_vecbranch — so a store built withoutsqlite-vecstill records'fallback', never''. Regression test: sqlite-vec absent + sentence-transformersabsent → stamp
'fallback'.3. Loud engagement + telemetry
One
WARNINGwhen the fallback engages;get_telemetrysurfacesembedding_mode(
neural/fallback/unknown) viafactory.current_embedding_mode.4. Code-aware FTS on all recall paths
camelCase/snake_case sub-tokens at index time (
augment_content) and querytime — recall WRRF
_signal_fts, entityMATCH, andrecall_helpers.compute_vector_fts.memories_ftsconverted external→self-contentwith a one-shot rebuild+reindex migration. Test: a lowercase query recalls a
camelCase symbol memory through the
recall_helperspath.5. Scheduled upgrade
consolidation/embedding_upgrade.run_embedding_upgrade_cyclere-embedsfallback-stamped memories with the neural encoder and restamps them
'neural'oncethe model is available; wired into
consolidate's compress phase, count in theresponse. Test: fallback memories + model available + cycle → restamped neural.
6 & 8. Genuine absence + mixed-store invariant
sentence_transformersgenuinely absent (import hook raises,not monkeypatched) +
CORTEX_EMBEDDING_ZERO_DOWNLOAD→ remember + recallround-trip with zero network, stamp
'fallback',PACKAGE_ABSENT.filter) — a neural vector identical to a fallback query is excluded.
Benchmark — LongMemEval-S, SQLite three-way (n=50, this code)
Fallback vs no-vector: ΔMRR +0.102, ΔRecall@10 +20.0 pp → fallback beats the
no-vector baseline (adoption criterion met). Results + MANIFEST under
benchmarks/results/semantic-fallback-169/.Tests / gates
test_semantic_fallback_169.py(13 tests: provider/selection/stamp/mixedstore/upgrade/subprocess/migration),
test_algorithmic_embedding.py,test_code_tokenize.py. Existing embedding suite (56) passes unchanged.ruff check .+ruff format --checkclean. Full-suite tally reported on the PRthread once the run completes.
skipif(not sqlite-vec); they run on the[sqlite]CI legs (test-sqlite / test-windows) and skip on the no-
[sqlite]matrix.🤖 Generated with Claude Code