Record Immich 3.3.1 and make the conductor sole owner of tickets.md
CI / backend (push) Successful in 43s
CI / frontend (push) Successful in 30s
CI / backend (pull_request) Successful in 42s
CI / frontend (pull_request) Successful in 29s

Production Immich is reachable at immich.ryanjchen.com and runs 3.3.1,
so the filter API style is the default and the public URL is known.
Parallel ticket PRs editing one status file would conflict, so only the
conductor updates tickets.md, once per wave.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 09:20:35 -04:00
parent 29200e49db
commit 609ee5aa7e
+55 -26
View File
@@ -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-<n>` (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 `<scratchpad>/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 `<scratchpad>/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-<color> curl -s $IMMICH_URL/api/server/ping`.
5. Put the results (partner answer, Maine album facts, chosen `IMMICH_URL`) in
`<scratchpad>/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