---
description: Stream K5: The product line page at /products/: variants within it, the price cases, cards deep-linking, redirects, noindex, JSON-LD
---

You are running **Stream K5** of the Duty Free Professor catalogue refactor, as an autonomous
session. Start by running `pwd`; it must be
`/srv/apps/dutyfreeprofessor/.claude/worktrees/table-layout-db-structure-1d5bc2` (the refactor
branch's worktree; the checkpoint hook walks up to its `.logs/`), or stop. Confirm with
`git branch --show-current` that you are on `claude/table-layout-db-structure-1d5bc2`.

Read first, in this order: `.logs/planning/streams/OVERNIGHT-RULES.md` (binding; where it says the
cwd must be the workspace root, this worktree is the root for the refactor), then your brief
`.logs/planning/streams/K5-line-page.md` (it names what already exists; build on it), the accepted plan
`.logs/planning/catalogue-refactor-plan-2026-09-16.md` (section 1's decision for your items, section
9's order), `main/docs/VOCABULARY.md` (the words; a bare "product" is never written), `agents.md`,
`brief.md`, `main/docs/REVIEW-PROCESS.md` (from K0), the top three entries of `.logs/handoff.md`, and
`python3 main/scripts/items.py list --decisions`. Runs: in the Thursday-night wave with K3 and K4; never alongside a collection.

Tell rian as you go with `srv-gw notify --from "K5" "<one line>"`: on start, on each task done with the count, on blocked, and at hand-back (OVERNIGHT-RULES, "Telling rian as you go"). Never put a secret in a message.

Then work the brief's tasks in order, K5.1, K5.2, K5.3, K5.4, K5.5, K5.6, one at a time, each verified and committed and
recorded on `/plan` with `main/scripts/plan-set.py` (`doing` when you start, `done` with a `--note`
that says what proves it, `blocked` with why). Delegate mechanical edits to a cheaper model with
the exact files and the acceptance test and verify the diff yourself; never delegate identity or
matching rules, a security-relevant change, or anything a person reads on a page. Rehearse every
migration and backfill on `dfp-devdb` (127.0.0.1:5433) in a fresh copy of the newest nightly dump and
report the numbers it produced, read from that database. **Never deploy, never touch the live
database, never run a collection.** Stay inside the files your brief lists under Owns; a change you
need elsewhere is an issue on the running list owned by that stream.

## Goal, and exactly when you are done

**Goal:** the product line page at /products/<slug> with ?variant and &airports, every W20 price case proven by a URL, cards deep-linking to the same comparison, old variant addresses answering 301, noindex follow by default, ProductGroup JSON-LD, the route inventory closed, to the verified-and-committed standard.

**You are done when ALL of the following are true**, and not before:
1. Every one of these task ids in `import/progress.json` is `done`, or is `blocked` with a
   note saying why: **K5.1, K5.2, K5.3, K5.4, K5.5, K5.6**. (Check with `python3 -c "import json;d=json.load(open('import/progress.json'));print({t['id']:t['status'] for s in d['streams'] for t in s['tasks'] if t['id'] in ['K5.1','K5.2','K5.3','K5.4','K5.5','K5.6']})"`.)
2. `../.venv-dev/bin/pytest tests -q` (from `main/`) passes and `main/check.sh` prints "checks passed" on the
   current tree.
3. Every finished task has its own commit prefixed `K5:` (`git log --oneline | grep "^[0-9a-f]* K5:"`).
4. A handoff entry for this session exists at the top of `.logs/handoff.md` (≤25 lines: what
   landed and how it was verified with the numbers from the rehearsal, any migration id and the
   after-deploy commands in order, what is blocked and why, what rian must do), and `/checkpoint`
   has been run.
5. Anything only rian can decide is on the running list (`python3 main/scripts/items.py add
   --kind decide --by "Stream K5" --blocks <task> --weight ...`) with the assumption you proceeded under.

A task you cannot finish is not a reason to keep going or to stop early: mark it `blocked`
with the reason, record the decision if one is needed, and move to the next. If all tasks
are done or blocked, finish steps 2 to 5 and stop. If eight hours have passed, mark every
unfinished task `blocked` with the note "eight-hour cap; resume with /stream-k5", write the handoff,
run `/checkpoint`, and stop.

## The goal line (rian pastes this after the first turn ends)
Start the session with `/stream-k5`. When that first turn ends, paste this one line:

```
/goal Stream K5 of the Duty Free Professor catalogue refactor is complete: in import/progress.json every one of the task ids K5.1, K5.2, K5.3, K5.4, K5.5, K5.6 has status done, or blocked with a note saying why; main/check.sh has printed "checks passed" on the final tree; every finished task has its own commit prefixed "K5:"; a handoff entry for this session is at the top of .logs/handoff.md naming any migration id and the after-deploy commands, and /checkpoint has been run; anything only rian can decide has been added to the running list with main/scripts/items.py. Or stop after 140 turns.
```
