@@ 302,3 302,42 @@ No removed / renamed JSON fields anywhere. No schema modifications to existing t
- **PH2 — second `Session.id` call site also fixed (`web/src/routes/project.$.tsx:33`)**: Plan bullet 2.4 already flagged this. Design said "single existing call site"; a second call site shipped in #5 (lethe-web-ui-aggregates) between design approval and execute. User explicitly approved option 1 (fix both) before dispatch. Both call sites now pass `s.sessionId` to `params.id`; React `key` in `SessionsTable.tsx:61` keeps `s.id` (composite) intentionally — IV6's "both coexist" exists for exactly this asymmetry.
- **PH3 — `apiFetchVoid` helper added in `web/src/api/client.ts`** (outside PH3's declared Owns set): backend DELETE `/api/v1/saved-searches/{name}` returns 204 No Content; the existing `apiFetch<T>` calls `resp.json()` unconditionally and would throw `SyntaxError` on an empty body. The dispatcher's pre-flight authorized this exact helper so the foundation invariant ("all API calls flow through `apiFetch`/its sibling — no raw `fetch` outside `client.ts`") stays intact. Single new exported function; mirrors `apiFetch` except it skips JSON decode and returns `void`.
- **PH3 — `internal/server/web/dist/index.html` regen included in the commit** (outside PH3's declared Owns set): Vite stamps content-hash bundle filenames; `npm run build` rewrote `dist/index.html` to point at the new asset hashes. #5's verify recorded the same artifact as a follow-up commit (`f6611d7`); catching it in-phase here is the corrected pattern.
+- **Verify — register `savedsearch.Repository`/`savedsearch.Handler` in the e2e test's local steward graph (`cmd/lethe/main_e2e_test.go`)**: PH1 added a `*savedsearch.Handler` `inject:""` field on `Server` and updated `cmd/lethe/main.go` accordingly, but missed the sibling `main_e2e_test.go` which constructs its own steward graph that mirrors `main.go`. `TestEndToEnd_MultiUserIsolation` panicked at `Inject` with `failed to find dependency: target=server.Server targetField=SavedSearches dependencyType=*savedsearch.Handler`. Verify-driven fix-up commit `964d802` adds the import and two `MustServiceAsset` lines, restoring the e2e test. Filed as a deviation because PH1's plan named only `cmd/lethe/main.go` for steward registration and the consistency sweep should have grepped for `MustServiceAsset` siblings before commit.
+
+## Verify
+
+**Result:** passed
+
+Positive:
+- CK1 — `go test ./internal/domain/savedsearch/... -race -count=1` → ok (22 tests)
+- CK2 — `go test ./internal/... -count=1` → ok (all packages)
+- CK2b — `go test ./cmd/lethe/... -count=1` → ok after fix-up commit `964d802` (initial run panicked: see Deviations)
+- CK3 — `go build ./cmd/lethe/` → 32 MB binary
+- CK4 — `cd web && npm test -- --run` → 50 passed across 4 files
+- CK5 — `cd web && npm run build` → 376 modules, 491 KB JS / 150 KB gzip; `dist/index.html` matches tracked artifact
+
+Negative:
+- CK6 (slash in name) — `TestHandler_Create_SlashInNameReturns400` covers `POST {name:"a/b"}` → 400 VALIDATION
+- CK7 (duplicate) — `TestHandler_Create_DuplicateReturns409` covers second POST same `(owner, name)` → 409 CONFLICT
+- CK8 (missing) — `TestHandler_Delete_Sequence` covers second DELETE → 404 NOT_FOUND
+
+Invariants / assumptions:
+- CK9 (IV1) — `grep -iE 'TRIGGER|FOREIGN KEY|FTS|REFERENCES' 0002_saved_searches.up.sql` → empty
+- CK10 (IV2) — owner derives from `auth.MustIdentity` via `ownerOf` (handler.go:46-48); `?owner=` on writes is rejected as INVALID, on reads is silently ignored — `TestHandler_List_OwnerParamIgnored` asserts the read path
+- CK11 (IV3) — `PRIMARY KEY (owner, name)` in 0002 migration
+- CK12 (IV4) — `Palette.tsx` consumes `useProjects`/`useSessions` unchanged; no new query params constructed in either hook; AS1 cap is client-side `.slice(0, 50)`
+- CK13 (IV5) — `find web/src/routes -name 'settings*'` → only `routes/settings.tsx`; no sub-route files
+- CK14 (IV6) — `Session.id` (composite, `${tool}/${host}/${session_id}`) and `Session.sessionId` (bare) both populated in `adaptSession`; `SessionsTable.tsx:61` keeps `s.id` as React `key` (unique cross-tool/host); `routes/index.tsx:48`, `routes/project.$.tsx:33`, `Palette.tsx:137` all use `s.sessionId` for `params.id`
+- CK15 (IV7+UK1) — `validateName` (handler.go:54-72): `name == ""` → 400, `len(name) > 64` → 400, `strings.Contains(name, "/")` → 400. Called on Create + Update.
+- CK16 (PC1) — saved-search palette activate at `Palette.tsx:141` → `navigate({ to: '/search', search: { q: item.query } })`; `/search` is the foundation stub, no execution wired
+- CK17 (AS1) — `Palette.tsx:95` caps sessions list with `.slice(0, 50)` before mapping to `SessionItem`
+
+Interfaces:
+- CK18 (IF1) — `Session.sessionId: string` declared at `adapters.ts:23`, populated at `:40`, consumed by `Palette.tsx:32, 98, 101, 137`; bare id never replaced by composite anywhere on the URL path
+- CK19 (IF2) — `useSavedSearches` exported from `web/src/features/settings/useSavedSearches.ts:9`, consumed at `Palette.tsx:5, 78` and `SavedSearchesSection.tsx`
+- CK20 (IF3) — `GET /api/v1/saved-searches` returns `{ saved_searches: [SavedSearch] }` (top-level key); `Owner` field omitted via `json:"-"` (IV2). `TestHandler_List_OwnerFieldAbsentInJSON` asserts the JSON shape; frontend `useSavedSearches.ts:8, 16` consumes the `data.saved_searches` key.
+
+Notes:
+
+- **Browser smoke deferred** — `/settings` saved-search CRUD and the widened palette were not exercised in a real browser. tsc + vitest + the production bundle are clean and the backend is verified by handler tests, but a full Chrome walk requires the running server + an authenticated session. Task #10 (`lethe-oidc-stub`, ✓ Reviewed) ships the `cmd/oidc-stub` binary that unblocks this, but standing it up and driving the UI is out of reach in autonomous mode without user input. Recommended walk: (a) start `lethe` with the OIDC dev stub config, (b) sign in, (c) `⌘K` and confirm projects/sessions/saved-search items appear in fixed group order, (d) `/settings` and create / rename / delete a saved search, (e) press a saved-search row in the palette and confirm it lands on `/search?q=…` (stub).
+- **Verify-driven fix-up commit** `964d802` — PH1 missed `cmd/lethe/main_e2e_test.go`'s steward graph; recorded under Deviations.