Summary
After restoring the Elasticsearch keyword path (see the index-name issue), BM25 finds the correct document, but its contribution does not reach the final ranking. The matched memory is returned last, with a score that is identical across completely different queries.
Observation
Query: PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION — a unique token present verbatim in exactly one memory.
Log:
[HybridSearch] ES keyword search: 1 results for "PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION"
[PgVector] Hybrid fusion: 9 vector + 1 text → 9 fused (weights: v=0.30, t=0.70)
Result: the matching memory is returned last, score 0.03473770491803279. Four unrelated memories rank above it with scores around 0.081.
Repeating with a different unique token (test-db-setup.ts, also present only in that same memory) produces the same ordering and — notably — the same score for that memory, 0.03473770491803279, to the last digit. A relevance score that does not change between unrelated queries suggests a constant fallback rather than a computed value.
The memory's embeddingStatus is COMPLETE, so this is not a missing-vector case. The fused count (9) equals the vector count, so the text hit was already present in the vector candidate set — it simply does not appear to contribute to the score.
Expected
With a text weight of 0.70, an exact match on a unique token should dominate the ranking.
Suggested investigation
Check whether the text score is normalised and applied for documents that appear in both candidate lists, and whether the constant 0.0347… is a default assigned before fusion and never overwritten.
Other observations (not filed above)
These are smaller and may be worth a discussion thread rather than issues:
-
GET /v1/stats returns synthetic data. On an instance created from an empty database on 2026-09-22, the apiRequests series reported 171–267 requests/day for 2026-09-17 through 2026-09-21, and ~210 for the current day against a few dozen actual requests. The fields sourced from the database (totalMemories, layer distribution, recentActivity) are accurate.
-
Auto-generated memories dominate recall on small corpora. Entity extraction writes records of the form "X is an organization known to <internal user id>", and temporal gap markers write "Temporal gap: N minutes elapsed…". On an 11-memory instance, 6 were auto-generated, and they consistently outranked the substantive ones. Temporal markers can be disabled with ENABLE_TEMPORAL_GAP_MARKERS=false; entity extraction appears to have no configuration flag. A flag for the latter, and using a human-readable subject instead of the raw internal id, would both help.
-
Broken repository link on the website. openengram.ai links to https://github.com/openengram/engram, which returns 404. The working repository is https://github.com/heybeaux/engram.
-
Undocumented requirements in the quickstart. The stack will not start without an LLM provider (No LLM provider configured), and OPENAI_API_KEY must be passed explicitly into the api service environment in docker-compose.yml — it is not picked up from .env alone. Neither is mentioned in the quickstart.
Summary
After restoring the Elasticsearch keyword path (see the index-name issue), BM25 finds the correct document, but its contribution does not reach the final ranking. The matched memory is returned last, with a score that is identical across completely different queries.
Observation
Query:
PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION— a unique token present verbatim in exactly one memory.Log:
Result: the matching memory is returned last, score
0.03473770491803279. Four unrelated memories rank above it with scores around0.081.Repeating with a different unique token (
test-db-setup.ts, also present only in that same memory) produces the same ordering and — notably — the same score for that memory,0.03473770491803279, to the last digit. A relevance score that does not change between unrelated queries suggests a constant fallback rather than a computed value.The memory's
embeddingStatusisCOMPLETE, so this is not a missing-vector case. The fused count (9) equals the vector count, so the text hit was already present in the vector candidate set — it simply does not appear to contribute to the score.Expected
With a text weight of 0.70, an exact match on a unique token should dominate the ranking.
Suggested investigation
Check whether the text score is normalised and applied for documents that appear in both candidate lists, and whether the constant
0.0347…is a default assigned before fusion and never overwritten.Other observations (not filed above)
These are smaller and may be worth a discussion thread rather than issues:
GET /v1/statsreturns synthetic data. On an instance created from an empty database on 2026-09-22, theapiRequestsseries reported 171–267 requests/day for 2026-09-17 through 2026-09-21, and ~210 for the current day against a few dozen actual requests. The fields sourced from the database (totalMemories, layer distribution,recentActivity) are accurate.Auto-generated memories dominate recall on small corpora. Entity extraction writes records of the form
"X is an organization known to <internal user id>", and temporal gap markers write"Temporal gap: N minutes elapsed…". On an 11-memory instance, 6 were auto-generated, and they consistently outranked the substantive ones. Temporal markers can be disabled withENABLE_TEMPORAL_GAP_MARKERS=false; entity extraction appears to have no configuration flag. A flag for the latter, and using a human-readable subject instead of the raw internal id, would both help.Broken repository link on the website. openengram.ai links to
https://github.com/openengram/engram, which returns 404. The working repository ishttps://github.com/heybeaux/engram.Undocumented requirements in the quickstart. The stack will not start without an LLM provider (
No LLM provider configured), andOPENAI_API_KEYmust be passed explicitly into theapiservice environment indocker-compose.yml— it is not picked up from.envalone. Neither is mentioned in the quickstart.