diff --git a/CLAUDE.md b/CLAUDE.md index 58a2f68..1b14cd2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,9 +34,34 @@ e2e suite in the default pytest run (`tests/e2e/test_ingestion_slice.py`: duplicate upload, retry after failure, tenant isolation, capacity, timeout, parse and Qdrant failure), and the one Compose-based test — `scripts/smoke.sh` driving `tests/e2e/test_compose_smoke.py` against a real uvicorn process, which -skips itself unless `SMOKE_BASE_URL` is set. Not built yet: `/v1/points` CRUD -and keyword search (plan 002), and `src/agent/`. That maps to plan 001 Phases -1-6 done. +skips itself unless `SMOKE_BASE_URL` is set. That maps to plan 001 Phases 1-6 +done. + +Plan 002 (`/v1/points` CRUD and keyword search) is **Phase 1 done**. Landed: the +`PointRepository` port (`src/application/ports/point_repository.py`) with its +`Point` read model (`src/application/points/point.py`), the Qdrant adapter +(`src/infrastructure/qdrant/point_repository.py`), request/response schemas +(`src/api/schemas/points.py`), and lifespan wiring. This port is **separate from +`PointStorage`**, which stays exactly the two bulk operations ingestion +performs — reads, single-point edits, and keyword search have a different caller +and a different tenant-filter obligation, so do not accrete them onto the +ingestion port. `tenant_id` is a required keyword argument on every +`PointRepository` method by design; keep it that way, because it is what turns a +forgotten tenant filter into a type error. The `chunks` collection also gained +full-text `content`, `is_active`, and `chunk_index` payload indexes, so a +deployed environment needs `qdrant_bootstrap` re-run (indexes are additive — no +rebuild, no re-embedding). + +Two adapter mechanics there are load-bearing and easy to "simplify" into bugs: +reads go through `scroll` with a `HasIdCondition` rather than `retrieve` (which +takes no filter, and would move the tenant check to *after* Qdrant answered), +and ordered listing paginates by `order_id` value rather than offset (Qdrant +returns no page offset under `order_by`, and an offset cursor skips or repeats +rows under a concurrent insert). + +Not built yet: plan 002 Phases 2-6 — the `/v1/points` routes themselves, soft +delete with neighbour relinking, create/replace/patch, reorder and batch, and +the `api_request_logs`/`point_audit_events` tables — and `src/agent/`. Architecture decisions live in `docs/adr/` (18 ADRs plus the 0000 template; 0001–0004 are `Accepted` — 0004 amended by 0018; 0014 is `Superseded by 0017`;