fix(review): operator-agnostic sanity check + invariant TODOs + dedupe

Code-review follow-ups on the pgvector spike:
- self-similarity sanity check now compares to the seed's own self-distance
  (0 for cosine/L2, ~-1 for inner product <#>) instead of a hardcoded ~0, so it
  no longer misfires if Immich ever uses a vector_ip_ops index (correctness P3).
- mark the deliberate raw-SQLite read in the probe as a spike-only exception and
  add an M1.5 TODO that the real pgvector reader belongs in shared/photoflow/immich
  and SQLite access in shared/photoflow/core (project-standards P2 x2).
- document join_and_coverage's return shape; extract a _pct() helper to dedupe the
  coverage-percentage formatting (maintainability P3 x2).
Findings doc refreshed from the latest live run (coverage now ~46%, re-run ongoing).
This commit is contained in:
2026-06-27 20:50:06 +02:00
parent 7745f05323
commit 1a6afe86fc
3 changed files with 38 additions and 19 deletions
@@ -1,6 +1,6 @@
# pgvector embedding feasibility spike — findings
**Generated:** 2026-06-27 18:39 UTC by `scripts/pgvector_spike.py`
**Generated:** 2026-06-27 18:49 UTC by `scripts/pgvector_spike.py`
**Status:** machine-probed against the live Immich Postgres.
**This is M1.5's contract.** See the design spec:
`docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md`.
@@ -35,14 +35,14 @@ Immich's documented API → **read-only Postgres access (below) is the viable pa
| # | Question | Answer |
|---|----------|--------|
| 1 | Embeddings readable? | **yes — read 19607 distinct embedding(s)** |
| 2 | Join to asset table? | **19607/19607 embeddings join to asset via assetId** |
| 1 | Embeddings readable? | **yes — read 20727 distinct embedding(s)** |
| 2 | Join to asset table? | **20727/20727 embeddings join to asset via assetId** |
| 3 | Table / column | `public.smart_search` / `embedding` |
| 3 | Vector dimension | **1152** (live sample=1152, declared typmod=1152) |
| 3 | Distance operator | **<=> (cosine) — from index opclass vector_cosine_ops** |
| 3 | Operator sanity check | OK — nearest neighbour (a duplicate (identical-vector) asset) at distance 0 |
| 4 | Coverage (raw) | **42.8%** (19607/45854 assets) |
| 4 | Coverage (image-only) | **44.1%** (19221/43601 IMAGE assets) |
| 3 | Operator sanity check | OK — nearest neighbour (a duplicate (identical-vector) asset) at distance 0 (seed self-distance 0) |
| 4 | Coverage (raw) | **45.2%** (20727/45854 assets) |
| 4 | Coverage (image-only) | **46.6%** (20323/43601 IMAGE assets) |
- **Asset-key join:** FK smart_search.assetId -> asset.id
- **Orphan embeddings** (no matching asset): 0