Skip to content

feat(s032): complete slice 032 (semantic memory and hybrid retrieval) - #45

Merged
HackTuah merged 24 commits into
mainfrom
slice/032-semantic-memory
Sep 21, 2026
Merged

HackTuah merged 24 commits into
mainfrom
slice/032-semantic-memory

Conversation

@HackTuah

Copy link
Copy Markdown
Member

Slice 032: local embeddings (all-MiniLM-L6-v2 through Bumblebee and EXLA; an explicit download, never a hosted fallback: the owner's G0 decisions), the vector on the memories row with the embedder that produced it, brute-force search on SQLite (an EXLA product when the NIF is loaded) and pgvector's HNSW on Postgres, the observer that fills the semantic tier after each turn with a 0.92 dedupe, the retriever (reciprocal rank fusion of vector and full-text hits, recency decay, a cosine floor), the "Relevant memories" block in the volatile tier under its own cap, the recall tool, and the memory page's Semantic tab with the download action.

Evidence: slices/032-semantic-memory/PROOF.md (AC1 to AC8; the AC6 GIF under proof/), NOTES.md (thirteen findings, four follow-ups), docs/perf.md (new).

Outside the slice's scope, each red-then-fix because this slice's runs met them: fix(s012) a whitespace-only assistant row was lost; fix(s011) req_llm's tool-call encoding failed every live turn after a tool call; fix(s024) the signer alarm never cleared. Two test flakes closed at their source.

The packaged binary: the vector search passes in all three bundles; EXLA's NIF loads in the macOS bundle and not in the Linux one (Burrito's musl ERTS), so exla is started on demand and the Linux bundle boots with the tier off and says why (NOTES finding 2, a follow-up for a Linux backend); a Windows host does not declare exla.

Gate on the final commit: run 35607474111, all four legs green.

Manual queue for G4: AC2 (the real embedder's numbers; TRINITY_LOCAL_MODEL_CACHE=<cache> mix test --only local_model) and AC6 (proof/ac6-recall.gif).

Signed-off-by: Ayla Croft aylacroft@proton.me

… store measured, the G1 plan, and the slice opens

ROADMAP row 032 to in_progress. NOTES.md records the decisions (brute
force and pgvector, no sqlite_vec; local first, hosted only by
configuration and never a fallback; the tier off when local cannot
run; the embedder recorded per vector; no text to a hosted embed API
without opt-in), the measurements (local 86 ms and 0.858/0.062 on the
thresholds, 463 MB of XLA, no Windows target; hosted 208 ms and
0.71/0.752; pure Elixir 23 s), the deps, the eight-line plan, the
two-item manual queue, four deviations. mix.exs and mix.lock carry
nx, exla, bumblebee and pgvector; scripts/embed_bench.exs is the
measurement.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…d retriever, recall tool, memory page tab

The embedder behaviour with the local Bumblebee serving (explicit download, never a
hosted fallback), the hosted alternative behind configuration, and the fake for the suite;
the vector on the memories row with the model that produced it, searched brute force on
SQLite and through pgvector on Postgres (Postgrex types defined for that build); the
observer after each turn under the memory task supervisor with the 0.92 dedupe; the
retriever fusing vector and full-text hits by reciprocal rank with recency decay and a
cosine floor; the recall block in the volatile tier under its own cap with the 030
receipt; the recall tool; the memory page's Semantic tab with status, search, provenance,
delete, pin and the download action. VERSIONS rows for nx, exla, bumblebee, pgvector,
hnswlib; sqlite_vec recorded as not used. docs/01, 02, 05 amended.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…y, and the tier's status; exla declared on Linux and macOS hosts only

AC7's fallback clause: no loadable extension, so the packaged binary proves the vector
store in force with three fake vectors rolled back (binding, exit 4), and records whether
the EXLA NIF loaded and what the semantic tier's status is in the bundle (informative).
xla ships no Windows archive, so a Windows host does not declare exla and the tier is off
there by design.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…oses the assistant row

Found by slice 032's AC6 run on nvidia:nemotron: the model streamed one newline and then
its tool calls; validate_required counts whitespace as blank and the row was refused.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
References the red test in the previous commit: String.trim before the (no text)
substitution, so a turn that is only tool calls after a newline keeps its assistant row.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
The turn after a tool result raised invalid tool_call inside req_llm 1.24.0 on the first
live run of slice 032's recall; context/1 made public (@doc false) so the red can name it.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…and arguments

References the red test in the previous commit. Every live turn after a tool result had
failed with invalid tool_call since 011; the fake provider builds no context, so only a
live run could see it.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…er the tree, EXLA scoring in the brute store

Package run 35600216451: on Linux the EXLA NIF does not load in Burrito's musl ERTS
(__libc_single_threaded: symbol not found) and exla's application start took the release
down; the release now loads exla without starting it and Bumblebee.exla/0 starts it on
demand, remembering a failure as the tier's reason. On macOS the NIF loaded (EXLA=ok).
The vector check ran before the Repo on every OS; it is now a probe child before the
endpoint. Brute.search scores 10,000 rows as one EXLA product (72 ms p50, was 531 ms in
Elixir); the Elixir path stays for machines without the backend, held to the same numbers
by a test.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…shots

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…d where the model is on disk (local_model tag)

Signed-off-by: Ayla Croft <aylacroft@proton.me>
Signed-off-by: Ayla Croft <aylacroft@proton.me>
The fake provider's failures and objects no longer outlive the test that set them (llm_test
and SessionCase clear on exit), and the test helper waits for the boot receipt's Task
before the sandbox goes manual, so the boot-receipt tests no longer depend on a runner's
speed.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…in :load mode

Mix refuses exla: :load while trinity's applications list depends on it (package run
35603384655). Out of the applications list, exla is on the code path, started on demand by
Bumblebee.exla/0 in every environment, and the release loads it without starting it.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…w it is carried

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…d query is never short

The postgres job returned two of three rows (run 35604770525): ef_search's 40 candidates
were other entries and dead tuples, and the WHERE clause came after. SET LOCAL
hnsw.iterative_scan = strict_order inside the search's transaction.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
… store does

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ef; package sizes in docs/perf.md

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…again

Alarm's doc says clear/0 runs once a signer signs again; nothing calls it. The fips leg's
receipts test met an alarm an earlier test left set (run 35606884798).

Signed-off-by: Ayla Croft <aylacroft@proton.me>
References the red test in the previous commit: sign_if_needed/2 and sign_checkpoint/1 clear
the alarm on a successful signature when it is set, which Alarm's doc has promised since 024.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
PROOF.md with every criterion's evidence, the coverage row (79.01 at 732238c), NOTES
findings 12 and 13, and the ROADMAP row to done.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…has no argument to mistake for a file

Package run 35608084951, macOS: 'No file named --smoke', exit 1, between the fourth line
and the fifth. The workflow sets the variable; --smoke still works where the race is won.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…tests

Every turn now runs the retriever, and the postgres job's 100-session and 20-writer tests
refused checkouts on the sandbox's one shared connection (runs 35610164189 and 35610171809):
queue_target 5 s and queue_interval 30 s on the test pools. NOTES findings 14 and 15.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…erage row at 193800e

Signed-off-by: Ayla Croft <aylacroft@proton.me>
… as a follow-up

Signed-off-by: Ayla Croft <aylacroft@proton.me>
@HackTuah
HackTuah merged commit 9c6acff into main Sep 21, 2026
8 checks passed
@HackTuah
HackTuah deleted the slice/032-semantic-memory branch September 21, 2026 15:07
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.

1 participant