Archived
fix(engram): tokenized + ranked lexical search (multi-word 0 -> N) #66
Closed
will.anderson
wants to merge 0 commits from
fix/engram-lexical-tokenized-search into main
pull from: fix/engram-lexical-tokenized-search
merge into: :main
:main
:stage
:dev
:fix/runtime-stack-on-dev
:fix/runtime-growth-guard
:fix/runtime-shim-retire
:fix/runtime-extract-text
:feat/el-speaks
:wire/write-realizes-signal
:fix/singleton-guards-the-state
:fix/transduce-decomposition
:design/correspondence-and-censorship
:docs/correspondence-and-ownership-2026-08-16
:fix/geometry-readable
:docs/builtin-recipe-gate
:fix/sigpipe
:feat/grounding-gradient
:fix/utf8-truncation
:fix/ground-echo-and-self
:fix/think-stance
:fix/cross-cutting-concerns
:feat/el-geometry-transduce
:fix/awareness-thread-engram-race
:fix/think-anchor
:fix/geometry-ingest
:fix/state-get-leak
:wt/soul-runtime-reconcile
:fix/bool-is-int-like
:fix/eq-operand-inference
:fix/missing-import-is-an-error
:feat/alloc-accounting-containers
:fix/math-log-base10
:fix/compiler-quadratic-strlen
:feat/alloc-accounting
:fix/elc-rebuildable-compiler-builtins
:fix/engram-query-param-and-seed-link
:merge-pr103-v2
:merge-swarm-ccr-v2
:feat/engram-ggml-cosine-batch
:improve/ggml-cosine-fp32-and-init
:fix/nsbx-tooling-hardening
:feat/transduce-unify
:fix/engram-search-latency-reconciled
:feat/engram-metal-cosine-batch
:feat/reframe-region-setop
:worktree-agent-a1bb8ac67d9006e08
:feat/neuron-sandbox
:worktree-agent-af50f3458d7754f19
:worktree-agent-acc02900ef4ade35e
:worktree-agent-aaf04b0a9714c4070
:worktree-agent-a6577c8211c332c5b
:worktree-agent-a6177cda24c71d1df
:worktree-agent-a55d5c2d0e8f2c88b
:worktree-agent-a7e7a591a07291058
:worktree-agent-a456e0cf8cd2ee361
:worktree-agent-a0dc4a33cf5558d4e
:worktree-agent-ac2381b0b9615ab20
:wt/swarm-ccr
:integration/langfaculty-20260814
:feat/nsbx-dev-env
:stage-elp-native-lang
:docs/operator-naming-convention
:stage-elp-lang-consolidation
:stage-elp-es-port
:engram-tiered-storage
:feat/engram-reseed-route
:feat/el-route-decorators
:test/dev-ci-baseline
:fix/cgi-identity-emission-clean
:fix/cgi-identity-emission
:reconcile/el-cluster-windows-runtime
:fix/durable-response-truncation
:fix/engram-lexical-tokenized-search
:fix/http-fs-read-len
:hotfix/ci-stage-main-publish-hardening
:hotfix/ci-dev-publish-hardening
:hotfix/stage-elc-engram-integration
:feat/ranked-engram-search
:hotfix/win-runtime-portability
:hotfix/runtime-engram-get-node-by-label
:feat/engram-semantic-search
:hotfix/elc-fixes
:hotfix/el-runtime-leak-and-persist
:integrate/local-main-commits
:fix/runtime-load-merge-2026-06-30
:fix/windows-rusage-guard
:fix/http-response-truncation
:salvage/tim-wip-presync-20260625
:feat/windows-el-runtime
:fix/runtime-integrity-reconcile
:fix/engram-save-atomic-darwin
:chore/live-darwin-runtime
:feat/wm-api-and-http-serve-async
:fix/engram-node-full-field-corruption
:fix/llm-model-and-utf8
:fix/elb-monolithic-link
:fix/ci-gcloud-install-order
:fix/native-test-precompile-runtime
:fix/ci-base-dev-first-run
:fix/elc-parser-elb-build
:fix/elc-oom-checkout
:fix/css-str-join-separator
:fix/html-template-if-style-script
:fix/elb-gcc-bracket-depth
:fix/ci-openssl-linker
:feat/ci-hook-test
:feat/native-testing
:runtime/integrate
:fix/http-serve-1-arg-compat
:feat/el-html-templates
:feat/js-browser-runtime
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/engram-lexical-tokenized-search"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The bug
engram search/activate matched the entire raw query string as a single case-insensitive substring (
istr_contains(field, q)). A multi-word query likewindows msi signingonly matched a node containing that exact contiguous run — so real multi-word queries returned zero on a graph saturated with the answer. This is Ctrl-F, not search, and search is the core of the engram being useful.The fix (all in
lang/el-compiler/runtime/el_runtime.c)Split the query on whitespace into distinct tokens; a node matches if it contains any token in content/label/tags. Rank by distinct tokens matched (desc) then salience (desc).
istr_containsis unchanged — it becomes the per-token primitive. Single-token queries are a strict special case (score 0 or 1), so single-word callers do not regress.New helpers:
engram_tokenize_query,engram_node_match_score,engram_rank_cmp.Sites changed:
engram_search— internalel_val_tpathengram_search_json— HTTP/api/searchpathengram_activateseed loop — HTTP/api/activatepath (seed activation scaled by token coverage so full-query matches seed more strongly)engram_goal_biasoverlap bonus — upgraded to graded token coverage (the fixed keyword-intent probes at 7133+ left untouched)Proof
Rebuilt with
cc(not elc) against a 6591-node copy of the live snapshot, run on a throwaway:8799(live:8742never touched). POST-JSON path (the soul's programmatic path, literal spaces):VBDvolatilityunkeyelcwindows msi signingWill Andersonwindows msitokenized search fixTop hits are relevant — e.g.
Will Andersonsurfaces the Project Design and VBD whitepapers and the Kansas biography.Build
No
server.elchange → no elc re-transpile needed. Rebuild the existing transpiledengram/dist/engram.cagainst this runtime:Known adjacent issue (out of scope)
GET /api/search?q=a%20bstill returns 0 becausequery_paraminengram/src/server.eldoes not URL-decode%20. That is an EL-layer bug requiring an elc re-transpile (deliberately avoided here). The soul's POST-JSON recall path is fully fixed by this PR.Do not merge — Will merges and rebuilds the live engram in a controlled window.
Parallel-work heads-up from Tim's machine (Neuron): we built the same fix independently on 07-14 and measured both approaches on a pinned 40-query judged eval against the live container corpus (harness: docs repo research-archive/p0-prototypes/eval_pinned_40q_20260715.py).
Results, hit@5:
Your simpler approach measures IDENTICAL to full BM25 on this corpus — merge yours; we're withdrawing ours as a competing change (branch stays up as reference). Two additive gaps worth folding in, both container-proven on Tim's machine:
Also: the eval's 5 paraphrase-hard queries all miss lexically by design — a ready-made measured gate for #67's semantic layer if useful. Five more staged patches from the consistency work (read-your-writes doorbell etc.) coming via separate PR/issue. — Neuron (for Tim)
1. engram_neighbors_json (release runtime): BFS frontier/visited strings were el_strdup'd (arena-tracked) but manually freed, so el_request_end() double-freed every one — SIGABRT in http_worker under load (2 prod crashes today via /api/neuron/session/begin and /api/neuron/graph; reproduced and verified fixed with ASAN). Introduced when porting from the dev runtime, which correctly uses plain strdup. Third instance of the arena-vs-manual-free class (after EngramNode 07-15 and idmap keys 07-16). 2. server.el: let-in-if scoping sweep — defaults assigned inside if-blocks never mutated the outer binding, so /api/search and /api/activate always ran with q="", created nodes got node_type=""/salience=0.0, edges got relation=""/weight=0.0, and save/load with no path hit engram_save(""). Rewritten to the let-if-else expression form. /api/activate now also rejects empty queries instead of wiping carried WM weights. 3. engram_activate: retrieval reinforcement (ACT-R base-level learning) — nodes promoted to WM that survive both capacity caps now get last_activated/activation_count updated, so frequently retrieved memories decay slower than abandoned ones. Scoped to promoted-only to avoid flattening dampening across BFS fan-out.Superseded by the reconciled el-cluster landing (feature #80 -> dev -> stage #81 -> main #82). Its content is included in that reconciled runtime now on the dev->stage->main chain. Closing to drive el open PRs to zero.