From d9ba194b3040469b61085aa74345d2469c8ff161 Mon Sep 17 00:00:00 2001 From: mischa Date: Sat, 27 Jun 2026 22:31:26 +0200 Subject: [PATCH] docs(spike): add runbook + definition of done Consolidate the scattered run instructions and pass/fail criteria into one place: - design spec gains 'Running the spike' (venv bootstrap + flags + DB prereqs) and 'Definition of done' (Req 0-4 are the bar; coverage does not gate done-ness; the only follow-up at ~100% CLIP coverage is one no-flag re-run to snapshot the final coverage into the contract doc) sections, and the status line now reads 'passed 2026-06-27'. - script docstring Usage now includes the missing 'python3 -m venv .venv' bootstrap a fresh checkout needs, and points to the spec's definition of done. --- ...6-06-27-pgvector-embedding-spike-design.md | 40 ++++++++++++++++++- scripts/pgvector_spike.py | 15 ++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md b/docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md index 87f1353..164a050 100644 --- a/docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md +++ b/docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md @@ -2,7 +2,7 @@ **Date:** 2026-06-27 **Milestone dependency:** unblocks **M1.5** (visual similarity). See `docs/ROADMAP.md`. -**Status:** design +**Status:** passed 2026-06-27 — Req 0–4 answered (see findings doc). Final coverage snapshot pending CLIP re-run completion; see "Running the spike" / "Definition of done" below. ## Why this exists @@ -149,6 +149,44 @@ It hardcodes nothing destructive, takes no write path, and is safe to re-run. that M1 "runs a read-only feasibility spike" (→ "spike defined/pending per this spec") **and** M1.5's status note "verified in M1" (→ "dependency spike pending/this spec"). +## Running the spike + +Prereqs: read access to Immich's Postgres and `IMMICH_DB_URL` set — put it in `.env` at the +repo root; the probe searches upward from the working directory to find it. DSN form: +`postgresql://USER:PASSWORD@HOST:PORT/DBNAME` (Immich defaults: user `postgres`, db `immich`; +URL-encode special chars in the password). Immich's stock compose does **not** publish Postgres +to the host, so either map its port or run where the DB is reachable on the LAN. + +From the repo root (a fresh checkout / new worktree has no `.venv`): + +```bash +python3 -m venv .venv +.venv/bin/python -m pip install -r scripts/requirements-spike.txt +.venv/bin/python scripts/pgvector_spike.py # read-only, idempotent, safe to re-run +``` + +The probe prints a report and (re)writes the findings doc. Flags: `--no-write` (report only, +leave the doc untouched), `--sqlite PATH` (optional SQLite cross-check target; skips gracefully +when absent), `--findings PATH` (write the doc elsewhere). The DB session is opened read-only at +the session layer, so the probe cannot mutate Immich even via the write-capable `postgres` user. + +## Definition of done + +The spike is **done** once Requirements 0–4 are answered and recorded in the findings doc: +REST insufficiency documented (R0), embeddings readable (R1), join to `asset` confirmed (R2), +shape pinned — table / column / dimension / distance operator (R3), and coverage recorded both +raw and image-only (R4). **Coverage value does not gate done-ness** — per Risks, near-zero +coverage is a recorded fact, not a failure. By these criteria the spike already passed on +2026-06-27 (see the findings doc); `ROADMAP.md` reflects this. + +**Picking it up when the CLIP re-run reaches ~100%:** the only remaining action is to refresh the +coverage snapshot in the contract doc. Once the re-run completes, run +`scripts/pgvector_spike.py` (no flags) so the committed findings doc records the final +full-library coverage, then commit the regenerated doc. Nothing else changes — readability, the +`assetId → asset.id` join, and the vector shape are already locked and are re-verified on every +run. (If a later Immich upgrade changes the schema, the probe's catalog discovery adapts; re-run +and re-commit the doc — that is M1.5's version-guard duty.) + ## Out of scope (explicitly M1.5) CLIP clustering; a tested `shared/photoflow/immich/db.py` reader; nearest-neighbor queries at diff --git a/scripts/pgvector_spike.py b/scripts/pgvector_spike.py index 085e0c9..51b8d2e 100644 --- a/scripts/pgvector_spike.py +++ b/scripts/pgvector_spike.py @@ -15,12 +15,17 @@ This is read-only and idempotent. The DB session is opened read-only at the session layer (not merely by which statements we issue), so even Immich's write-capable postgres user cannot mutate the source-of-truth DB while we probe. -Usage: - IMMICH_DB_URL=postgresql://user:pass@host:5432/immich \\ - python scripts/pgvector_spike.py +Usage (from the repo root; a fresh checkout / new worktree has no .venv): + python3 -m venv .venv + .venv/bin/python -m pip install -r scripts/requirements-spike.txt + .venv/bin/python scripts/pgvector_spike.py # read-only, idempotent, safe to re-run - # or rely on a .env (searched upward from CWD) that defines IMMICH_DB_URL - python scripts/pgvector_spike.py [--sqlite PATH] [--findings PATH] [--no-write] +IMMICH_DB_URL is read from the environment, else from the nearest .env searched upward from the +working directory (postgresql://USER:PASS@HOST:PORT/DBNAME). Or pass it inline: + IMMICH_DB_URL=postgresql://user:pass@host:5432/immich .venv/bin/python scripts/pgvector_spike.py + +Flags: --sqlite PATH (optional SQLite cross-check), --findings PATH, --no-write (report only). +See docs/superpowers/specs/2026-06-27-pgvector-embedding-spike-design.md for the definition of done. """ from __future__ import annotations