Skip to content

epic: embedding deepening (review 2026-10-22) #1543

Open

Description

@ajianaz

Deepening of the embedding area of the core and of how the three binaries reach it. Source: the architecture review of 2026-10-22 on the embedding area (direction given by the owner), with the findings re-checked against the code and, for the two user-visible ones, reproduced with the real binaries and a mock embeddings endpoint. Follows the round-2 epic (#1523); related: #1535 (MCP gap), #1355, #1515.

Items, in the order to do them

  1. bug(core): the embedding cache is keyed by the embedder's name, so it serves vectors of another model #1536 cache keyed by the embedder's identity (bug; reproduced: model-b served the model-a vector): fix(core): key the embedding cache by the embedder's identity, not its name (#1536) #1544, merged.
  2. test(core): let tests supply an embedder through the public open path #1542 tests can supply an embedder through the public open path. Makes the next items testable in CI without ONNX.
  3. refactor(core): one way to ask for an embedding (lazy init, lock, retry, failure policy) #1538 one way to ask for an embedding (10 call sites, 5 expects, retry on writes only).
  4. refactor(core,cli,server): resolve the embedding backend once, behind core (CLI sent the ONNX model name to OpenAI) #1537 step 1: resolve the backend once for the CLI and the server (fixes the CLI sending embeddinggemma-q4 to an OpenAI endpoint; reproduced). No MCP change.
  5. refactor(core): separate constructing an embedder from using it (ensure_embedder is 204 lines) #1539 construction of an embedder separate from its lazy use (ensure_embedder, 204 lines).
  6. refactor(core): decide and check the embedding dimensions once, at open #1540 dimensions decided and checked once, at open (decided: refuse, with UTEKE_ALLOW_DIM_MISMATCH as the escape hatch).
  7. refactor(core,cli,server): resolve the embedding backend once, behind core (CLI sent the ONNX model name to OpenAI) #1537 step 2: MCP uses the same resolution, closes bug(mcp): uteke-mcp ignores [embedding] and [vector] of uteke.toml and UTEKE_EMBEDDING_* (always ONNX) #1535 (CORE note: uteke-cloud#254, held until answered).
  8. refactor(core): one request-and-validate module for the openai and ollama embedders #1541 closed on the owner's decision (no third remote backend planned).

How each item is done (the gate, repeated every time)

  1. Branch from develop; one PR per item, about 400 lines (the CI reviewer needs about a second per changed line against a 30 minute limit); split an item that is larger.
  2. cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace, cargo run -p docgen with no diff.
  3. Proof, not only tests: build the CLI, the server and MCP from develop (a git worktree with its own CARGO_TARGET_DIR) and from the branch, run both on the same configs, and compare. For embedding items use the mock embeddings endpoint (records model, input, request count) and, for the ONNX path, the real model (ORT_LIB_PATH, models symlinked into a throwaway UTEKE_HOME). A "no behaviour change" item must give identical results; a behaviour change must be exactly the documented one.
  4. Before every push: local review with the Cora MCP (cora.review_prepare, judged by the agent against the diff, then cora.review_finalize); fix what it finds or record why not in the PR.
  5. PR with ## What, ## Why, ## Testing, a changelog line, then wait for CI: all 15 checks on the head SHA and a real Cora verdict (a missing comment or "could not complete" means re-run, not merge); check inline comments, reviews, issue comments and code-scanning alerts.
  6. Squash merge with --author-email 12648688+ajianaz@users.noreply.github.com, tick the box here, then the next item. One item at a time, the next starts after the previous is merged.
  7. Items marked CORE note open as a draft and wait for the cloud answer (AGENTS.md: contract issue first).

Notes on the order

Decisions for the owner

(all decided 2026-10-22: #1540 refuse, #1536 purge the old cache rows once, #1541 closed)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions