---
description: "Stream AW2: featured selection v3 (one standard for what is featured, written on a public methodology page the site reads at runtime, applied by one function on the home page, the category and family landings, brand pages, the airport best-value block and the full product list; the admin pin as a ledger decision with a CLI; before-and-after evidence on a restored copy)"
---

You are running **Stream AW2** of the Duty Free Professor away run of 19 September 2026, as an
autonomous session. The design was made by the panel the orchestrator ran before you and is
recorded in your brief's Design section by your first task; do not redesign it. Where the design
is silent, choose the option that favours a picture and write the choice in the brief and the handoff.

**Start by checking your ground.** `pwd` must be
`/srv/apps/dutyfreeprofessor/.claude/worktrees/collectors-live-page-plan-8951e2`; `git branch
--show-current` must print `claude/collectors-live-page-plan-8951e2`; `git log --oneline -20` must
include `05941b4` or later, and should show `AW3:` commits (AW3 lands `services/imagery.py` and
`image_tier`, which you read). If any of these is false, stop and say so. `.venv-dev` and
`main/web/node_modules` are symlinks in this worktree; `alembic heads` here must print one head.

Read first, in this order: your brief `.logs/planning/streams/AW2-featured.md` whole; the away plan
`.logs/planning/streams/AWAY-2026-09-19.md` (sections 1, 2 and 7 bind you);
`.logs/planning/streams/OVERNIGHT-RULES.md`; `agents.md`; `brief.md`; then the docs the tasks need:
`main/docs/VOCABULARY.md`, `main/docs/SEO.md` (the page list and "What renders server-side"),
`main/docs/DATA-MODEL.md` (the "uid, hidden, indexed" paragraph and "Pictures at three levels"),
`main/docs/RUNBOOK.md` (Dev database, Backups, the CLI block), and AW3's brief
`.logs/planning/streams/AW3-images.md` for the `image_tier` interface you consume. Then the code
your brief names: `featured.py`, `airport_featured.py`, `catalog_queries.py` (`featured_savings`
and the `sort == "featured"` branch), `process_doc.py`, `publish.py`, `decisions/writer.py`,
`appliers.py`, `undo.py`, `cli_index.py`, `main.py`'s `/data` route and the catch-all, and the
tests that pin them.

Then work the tasks in order, AW2.1 to AW2.4, one at a time, each verified and committed with the
`AW2:` prefix. Register the tasks on `/plan` first, one line per task:

```
python3 main/scripts/plan-set.py AW2.1 todo "Stream AW2" --add --stream AW2 --stream-title "Featured selection v3" --title "Adopt the panel's design into the brief, and measure the page as it is"
python3 main/scripts/plan-set.py AW2.2 todo "Stream AW2" --add --stream AW2 --title "featured.py v3, every featured sort through it, the admin pin"
python3 main/scripts/plan-set.py AW2.3 todo "Stream AW2" --add --stream AW2 --title "The methodology page"
python3 main/scripts/plan-set.py AW2.4 todo "Stream AW2" --add --stream AW2 --title "Evidence after, tuning by numbers, hand-back"
```

then `python3 main/scripts/plan-set.py <ID> doing "Stream AW2"` when you start one and `... done
"Stream AW2" --note "<what proves it>"` when it is verified. `main/check.sh` must print "checks
passed" before every commit; one task, one commit, a body that says what it cost or prevents; a
line under `## Unreleased` in `main/CHANGELOG.md` for anything a shopper or the client would notice.

Rehearse the migration up, down, up and run `featured evidence` on `dfp-devdb` (127.0.0.1:5433)
in a fresh restore of the newest dump in `backups/` with `DATABASE_URL` pointed at it (the restore
line is in `RUNBOOK.md` Backups); report the numbers that copy produced, before and after, in the
handoff. A bug you fix becomes a test in `main/tests/` written as the real row that failed, with
what it cost in the docstring. A test that pinned the old order is updated to the new one, never
weakened.

**Hard boundaries beyond the usual.** You never deploy: the orchestrator deploys D2 when you hand
back "green and ready". You never write to staging's or production's database. You never run a
collection or fetch anything from the network. You never edit `.app.env`, `.env`, `.bw-auth.env`,
`main/check.sh`, AW3's files (`services/images.py`, `services/imagery.py`, the image columns,
its migration, `uploads/`), the collectors, `award_picker.py`, `services/trip.py`, or the main
checkout's dirty paths (`.logs/runs/`, `notes/`). A GET never writes. No em dash in anything a
shopper or the client reads; never "cheap" or "free" as a price word; product line, product
variant, brand, never bare "product".

Tell rian as you go with `srv-gw notify --from "AW2" "<one line>"`: on start (`AW2 starting: 4
tasks, featured v3`), on each task done with the count (`AW2.2 done (2/4): ...`), on blocked, and at
hand-back (`AW2 done: 4/4, check green, handoff written; D2 may deploy`). Never put a secret or a
URL with a token 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 AW2" --blocks AW2.<n> --weight
costly --title ... --detail ... --option ... --assumption ...`) 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. Return every open question in your hand-back marked critical or not critical.

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, prepend the handoff entry to
`.logs/handoff.md` (25 lines or fewer: the migration command, no backfill, the page address
awaiting approval, the pins CLI, the before-and-after numbers, the questions with the assumption
taken), mark the tasks on `/plan`, and stop. The orchestrator deploys; you do not.

```
/goal Stream AW2 is complete: every task AW2.1 to AW2.4 is done on /plan, 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 "AW2:"; the brief's Design section holds the adopted design with every threshold a named constant; featured.py exposes order() and every featured sort in catalog_queries and airport_featured runs through it; the migration adding the featured pin was rehearsed up, down, up on dfp-devdb and its id is in the handoff; app.cli featured pin, unpin, list and evidence exist; main/docs/FEATURED.md is version 1 and renders at /how-we-choose with a "How we choose" link on every featured rail; the before-and-after numbers from the restored copy are in the handoff; nothing was deployed, staging's database was never written, no collection and no fetch was run. Or stop after 120 turns.
```
