Search: revisit semantic ranking once the corpus outgrows the in-memory pass #163

Open
opened 2026-08-26 20:25:25 +00:00 by claude-bot · 0 comments
Collaborator

Issue #159 asked for a semantically aware search over an embedding model with the database made vector-like. What shipped in claude/issue-159 is lexical: the same word looked for in five places at once (title, tags, the people on the card, the board and column, description) with fuzzy matching, which covers most of "find it by its context" for short Kanban text. The embedding half was deliberately left out and the reasoning is written down in docs/search.md — this issue is the tracker for the decision, not a restatement of the feature.

Why it was not built now

  • Every searchable column is AES-256-GCM encrypted with non-deterministic ciphertext, so there is nothing for pgvector to index. A vector column would have to be either plaintext beside a ciphertext column — an embedding is close enough to the content that this quietly undoes the encryption for the one table anybody would attack — or encrypted, in which case it can only be read by decrypting all of it, which is exactly the in-memory pass SearchService already does, plus a model in the image.
  • One process for one private group: ~90 MB of ONNX model and a CPU inference budget on the box that also serves the circuits, for a corpus of a few hundred cards.

What would change the answer

Total cards across all boards. SearchService reads and decrypts every card the viewer can see on the first keystroke of a search session; at a few hundred that is a handful of milliseconds, at tens of thousands it is not. The point where that stops being acceptable is also the point where the honest fix is a search index process beside the app rather than a column on Cards — and that is the right moment to put an embedding in it, because it can hold plaintext under its own access boundary instead of next to the ciphertext.

Concretely, before reaching for a model: measure SearchService.SnapshotAsync against a realistically sized deployment (it is one query plus one SearchDocument per card). If the number is small, this issue stays closed-by-default.


Filed by Claude while working on #159 (run).

Issue #159 asked for a semantically aware search over an embedding model with the database made vector-like. What shipped in `claude/issue-159` is lexical: the same word looked for in five places at once (title, tags, the people on the card, the board and column, description) with fuzzy matching, which covers most of "find it by its context" for short Kanban text. The embedding half was deliberately left out and the reasoning is written down in `docs/search.md` — this issue is the tracker for the decision, not a restatement of the feature. **Why it was not built now** - Every searchable column is AES-256-GCM encrypted with non-deterministic ciphertext, so there is nothing for `pgvector` to index. A vector column would have to be either plaintext beside a ciphertext column — an embedding is close enough to the content that this quietly undoes the encryption for the one table anybody would attack — or encrypted, in which case it can only be read by decrypting all of it, which is exactly the in-memory pass `SearchService` already does, plus a model in the image. - One process for one private group: ~90 MB of ONNX model and a CPU inference budget on the box that also serves the circuits, for a corpus of a few hundred cards. **What would change the answer** Total cards across all boards. `SearchService` reads and decrypts every card the viewer can see on the first keystroke of a search session; at a few hundred that is a handful of milliseconds, at tens of thousands it is not. The point where that stops being acceptable is also the point where the honest fix is a search index process beside the app rather than a column on `Cards` — and that is the right moment to put an embedding in it, because it can hold plaintext under its own access boundary instead of next to the ciphertext. **Concretely, before reaching for a model:** measure `SearchService.SnapshotAsync` against a realistically sized deployment (it is one query plus one `SearchDocument` per card). If the number is small, this issue stays closed-by-default. --- _Filed by Claude while working on #159 ([run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/386))._
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/Ponente#163
No description provided.