diff --git a/docs/immich-mcp/tickets.md b/docs/immich-mcp/tickets.md index 8450aa6..ad196d0 100644 --- a/docs/immich-mcp/tickets.md +++ b/docs/immich-mcp/tickets.md @@ -70,8 +70,25 @@ The roles do not change from ticket to ticket. 7. **Clean up.** Exit the workers, `herdr pane close` / `herdr tab close`, `git worktree remove` each worktree, and delete merged local branches. 8. **Report.** Give a table of ticket → PR → state, what each review round - caught, and anything left undone. Tick the ticket's checkbox in this file in the - same PR or a follow-up docs PR. + caught, and anything left undone. + +### Ownership of this file (sheepdog rule) + +Several panes run at once, and each opens its own PR, so this file would be a +merge-conflict magnet if everyone edited it. One pane owns it: + +- **The conductor is the sheepdog, and the only writer of `tickets.md`.** + Workers never edit it, and ticket PRs never touch it. A worker's diff that touches + this file is sent back in review. +- The conductor records status **once per wave**, after that wave's PRs merge. + It makes one small commit on `docs/immich-mcp-tickets-wave-` (tick checkboxes, + add the PR numbers to the order table, file follow-ups as IMM-09+) and merges that + PR before starting the next wave. No two branches edit the file at the same time, + so there's nothing to race on. +- Workers who find something ticket-worthy (a bug outside their scope, a design gap) + put it under "open doubts" in their report. The conductor decides whether it becomes a ticket. +- Live notes during a wave (pane mapping, review state) go in `/panes.md`, + not here. ### Worker ground rules (paste into every plan) @@ -81,6 +98,7 @@ The roles do not change from ticket to ticket. style: comment density, naming, and async everywhere. - Change only the files your ticket lists. If you think another file needs to change, say so in your report instead of editing it. +- **Never edit `docs/immich-mcp/tickets.md`.** The conductor owns it (sheepdog rule). - Run `.venv/bin/pytest tests/unit -q` and `uvx ruff==0.8.2 check .`; both must pass. For IMM-05 also run `cd raggr-frontend && yarn tsc --noEmit`. - Never hand-write DB migrations (none of these tickets need one). If you think @@ -105,8 +123,8 @@ The roles do not change from ticket to ticket. ## 2. Ticket order ``` - IMM-01 (conductor: verify prod Immich, make keys) - │ (informs defaults; must finish before IMM-04 merges) + IMM-01 (conductor: make keys, check Maine/partner facts) + │ (must finish before IMM-04 merges) ▼ ┌───────── Wave 1 ─────────┐ │ IMM-02 server foundation │──┐ @@ -127,7 +145,7 @@ The roles do not change from ticket to ticket. | Order | Ticket | Owner | Depends on | Runs alongside | Merge order | |---|---|---|---|---|---| -| 0 | IMM-01 Verify production Immich and create scoped API keys | conductor | – | Wave 1 | (no PR; updates design §13 in IMM-07) | +| 0 | IMM-01 Create scoped API keys, check Maine/partner facts (version already known: 3.3.1) | conductor | – | Wave 1 | (no PR; findings go in the wave-1 status commit) | | 1 | IMM-02 Server foundation: config, client, criteria, package skeleton | worker | – | IMM-03 | 1st | | 1 | IMM-03 Trip summaries: clustering, places, samples (pure functions) | worker | – | IMM-02 | 2nd (rebase on IMM-02) | | 2 | IMM-04 Phase 1 read tools in the MCP server | worker | 02, 03 | IMM-05 | 3rd | @@ -158,19 +176,28 @@ Why this order: ### [ ] IMM-01: Verify production Immich and create scoped API keys -- **Owner:** conductor (needs LAN access and the Immich admin UI; no worker, no PR) -- **Depends on:** nothing · **Blocks:** IMM-04 merge (default API style), IMM-08 -- **Why:** The design machine couldn't reach `IMMICH_URL` - (`http://192.168.1.5:2283`), so the production version is unknown. The API changed - shape in v3.2.0 (§11). The design also has two open questions (§13.1, §13.2) that - only the real server can answer. +- **Owner:** conductor (needs the Immich UI and an API key; no worker, no PR) +- **Depends on:** nothing · **Blocks:** IMM-04 merge, IMM-08 +- **Why:** The API changed shape in v3.2.0 (§11), and the design has an open + question (§13.2) that only the real server can answer. + +**Already known (checked 2026-10-13):** + +- `GET https://immich.ryanjchen.com/api/server/version` → + `{"major":3,"minor":3,"patch":1}`. **Immich 3.3.1**, so the `filter` API style + (nested `filter` plus `cursor` paging) is available and is the **default**. The legacy + flat fields still work on 3.3.x, so keep both code paths and their golden tests. + Production doesn't need `IMMICH_API_STYLE` set. +- **Public URL:** `IMMICH_PUBLIC_URL=https://immich.ryanjchen.com`. Links in tool + output use this. `IMMICH_URL` can stay on the LAN/compose address + (`http://192.168.1.5:2283`) for the server's own traffic. If that address isn't + reachable from the raggr container, use the public URL for both. **Steps** -1. `curl -s $IMMICH_URL/api/server/version` from the docker host. Record - `major.minor.patch`. - - **Below 2.0:** stop and tell the user. The design assumes v2+ endpoints. - - **3.2 or later:** the default API style is `filter`. Below 3.2 it's `legacy`. +1. ~~Get the server version~~: done above (3.3.1). Re-run + `curl -s https://immich.ryanjchen.com/api/server/version` right before IMM-08 + in case Immich was upgraded in between; a 4.x major means re-checking §11. 2. In Immich → Account Settings → API Keys, create two keys for **Ryan's user**: - `simba-immich-read` with exactly `album.read`, `asset.read`, `asset.statistics`, `person.read`. @@ -182,22 +209,24 @@ Why this order: 3. Using the read key, check the facts the design depends on (curl or httpie): - `GET /api/search/suggestions?type=state` contains `"Maine"` (confirms the reverse-geocoding spelling). - - `POST /api/search/statistics` with `{"state":"Maine"}` (legacy) or - `{"filter":{"state":{"eq":"Maine"}}}` (3.2+) returns a total. + - `POST /api/search/statistics` with `{"filter":{"state":{"eq":"Maine"}}}` + returns a total, and the same total as legacy `{"state":"Maine"}`, which proves + both paths agree on 3.3.1. - `GET /api/albums` returns albums including the existing Maine album. Record its name, `assetCount`, `startDate` and `endDate`; IMM-08 uses them. - **Partner photos (§13.2):** if a partner shares with Ryan with "show in timeline" on, check whether partner assets come back from `POST /api/search/metadata`. Write the answer down. Adding them to an album gets tested in IMM-08 with the write key. -4. Note the public URL people use to open Immich in a browser. That becomes - `IMMICH_PUBLIC_URL`. -5. Put the results (version, API style, partner answer, Maine album facts, public - URL) in `/imm-01-findings.md`, paste them into the IMM-04 and IMM-07 - plan files, and post them to the user. +4. Check which `IMMICH_URL` the raggr container can reach: + `docker compose exec raggr- curl -s $IMMICH_URL/api/server/ping`. +5. Put the results (partner answer, Maine album facts, chosen `IMMICH_URL`) in + `/imm-01-findings.md`, paste them into the IMM-04 and IMM-07 + plan files, and post them to the user. The conductor records them in the + wave-1 status commit (sheepdog rule). -**Done when:** the version is known and the API style decided; both keys exist with -exactly the listed permissions; the Maine facts and the partner answer are recorded. +**Done when:** both keys exist with exactly the listed permissions; the Maine facts +and the partner answer are recorded; the container-reachable `IMMICH_URL` is known. --- @@ -412,7 +441,7 @@ imports as a namespace package, which is fine for tests. - **Owner:** worker · **Branch:** `feat/immich-mcp-read-tools` · **Base:** `origin/main` **after IMM-02 and IMM-03 are merged** -- **Depends on:** IMM-02, IMM-03 (and the IMM-01 findings for the default API style) +- **Depends on:** IMM-02, IMM-03 (production is 3.3.1, so `filter` is the style exercised live; both styles must still be tested) - **Runs alongside:** IMM-05 · **Blocks:** IMM-06 - **PR title:** "Add read-only Immich tools: find albums, search photos, smart search, album gaps" - **Design:** §3 (scenarios A, B-read, C-read, D), §7, §11 @@ -706,7 +735,7 @@ lists them in the PR body. list, add a short **`immich_mcp/`** entry (in-repo stdio MCP server for Immich albums and photo search; admin-only in raggr; also usable from Claude Code; see `docs/immich-mcp/`). Add `IMMICH_*` to the household-integrations env line. -- `docs/immich-mcp/tickets.md` (this file): tick IMM-02 to IMM-07. +- Do **not** edit `docs/immich-mcp/tickets.md`. The conductor ticks it (sheepdog rule). **Acceptance:** `mkdocs build --strict` passes, if mkdocs is available locally (otherwise check the links by hand). Every command in `usage.md` was actually run once by the worker