---
description: "Stream K11: the AI pass becomes the review (the word lists leave rian's queue, brand_key stops folding, defer-with-a-note feeds the next pass, and /review renders the product line table a pass emits)"
---

You are running **Stream K11** of the Duty Free Professor catalogue work, as an autonomous session.
**Opus is enough for this stream**; the architecture was decided by rian on 17 Sep and is written
down in the brief. Do not spend Fable on it.

**Start by checking your ground.** `git log --oneline -1` on master must include Stream K9
(`claude/brand-split`) and Stream K10 (`claude/review-area`). If either is missing, **stop and say
so** — this stream builds on both.

Work in your own worktree on your own branch, created from master:

```
cd /srv/apps/dutyfreeprofessor && git worktree add .claude/worktrees/ai-pass-review -b claude/ai-pass-review master && cd .claude/worktrees/ai-pass-review
```

Symlink the toolchain in as the K streams did, so `main/check.sh` runs there:
`ln -s /srv/apps/dutyfreeprofessor/.venv-dev .venv-dev` and
`ln -s /srv/apps/dutyfreeprofessor/main/web/node_modules main/web/node_modules`.

Read first, in this order: `.logs/planning/streams/OVERNIGHT-RULES.md` (binding; this worktree is
the root for your work), your brief `.logs/planning/streams/K11-ai-pass-is-the-review.md`,
`main/docs/REVIEW-PROCESS.md` whole, `main/docs/VOCABULARY.md` (one word per concept; a bare
"product" is never written), `agents.md`, and sections **W10, W11, W14 and W16** of
`.logs/planning/catalogue-walkthrough-2026-09-16.md` — rian's own words, which are the spec this
stream exists to restore.

**The one thing to understand before you write anything.** The programmatic stage is allowed to act,
must err toward SEPARATE brands and product lines, and is **never reviewed by rian**. The AI pass is
the review. Every task in the brief follows from that. If a change would put more machine-generated
questions in front of him, you have misread the brief.

Then work the tasks in order, K11.1 to K11.7, one at a time, each verified, committed with the
`K11:` prefix. Record progress with `python3 main/scripts/plan-set.py <ID> doing|done|blocked
"Stream K11"`; if the ids do not exist on `/plan` yet, say so in the handoff rather than inventing
rows in `import/progress.json`. Rehearse every data move on `dfp-devdb` (127.0.0.1:5433) in a fresh
copy of the newest dump in `backups/`, and report the numbers that database produced. A bug you fix
becomes a test in `main/tests/` written as the real row that failed, with what it cost in the
docstring. `main/check.sh` must print "checks passed" before each commit.

**Two hard boundaries beyond the usual.** You never write to staging's database — K11.2's
withdrawals and K11.4's migration are commands you hand rian in the handoff, not commands you run.
And you never run the AI pass: that is a separate `/review-pass` session on two or three brands rian
names, after he has seen the interface you build.

Tell rian as you go with `srv-gw notify --from "K11" "<one line>"`: on start, on each task done with
what proves it, on blocked, and at hand-back. Never put a secret in a message. If the command fails,
note it in the handoff and carry on.

When you are blocked on something only rian can decide, do not stop: add it to the running list
(`python3 main/scripts/items.py add --kind decide --by "Stream K11" ...`) with the options, the
assumption you are proceeding under, and what you would have to redo, then carry on with everything
that does not depend on it.

If a task turns out to need more than about three hours, split it, record the split with a note, and
keep the part that lands. When the brief is done, write the handoff entry and stop. Rian merges and
deploys; you do not.
