---
description: Stream A2: the Playwright rendered-fetch sidecar, the Shilla probe, then the Singapore collector
---

You are running **Stream A2** of the Duty Free Professor soft-launch build, as an
autonomous session. Start by running `pwd`; it must be `/srv/apps/dutyfreeprofessor`, or stop.

Read first, in this order: `.logs/planning/streams/OVERNIGHT-RULES.md` (binding), then your
brief `.logs/planning/streams/A2-rendered-fetch.md`, then `agents.md`, `brief.md`, build plan `.logs/planning/build-plan-2026-09.md`
sections 2, 7 and 9, and `.logs/decisions-for-rian.md` (generated from the running list: `python3 main/scripts/items.py list --decisions` shows what rian has decided).

Then follow the brief's ordered task list exactly as the rules describe: one task at a time,
verified and committed, recorded on `/plan` with `main/scripts/plan-set.py`. Delegate mechanical
subtasks to cheaper models per the rules and verify their output yourself. Never deploy; never
run a network collection your brief does not name for tonight; when blocked on a rian-only
decision, record it and continue. When the brief is exhausted or eight hours have passed, write
the final handoff entry, run `/checkpoint`, and stop the loop.

The 'Added 2026-09-04' section of your brief is binding: isolated network, egress allowlist, floor delay, no dialog click-through, Shilla probe first. Import the shared robots matcher from `collectors/robots.py` once Stream A lands it; do not fork it. Announce every network run in `.logs/runs/` first.

## Goal, and exactly when you are done

**Goal:** the browser sidecar, render(), the Shilla probe for Stream A2, delivered 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: **R1, R2, R3**. (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 ['R1', 'R2', 'R3']})"`.)
2. `../.venv-dev/bin/pytest tests -q` passes and `main/check.sh` prints "checks passed" on the
   current tree.
3. Every finished task has its own commit prefixed `A2:` (`git log --oneline | grep "^[0-9a-f]* A2:"`).
4. A handoff entry for this session exists at the top of `.logs/handoff.md` (≤25 lines: what
   landed and how it was verified, what is blocked and why, what is next, what you need from
   rian), and `/checkpoint` has been run.
5. Anything only rian can decide is on the running list (`python3 main/scripts/items.py add
   --kind decide ...`) with the assumption you proceeded under; issues you found or fixed are
   added or resolved there too.

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–5 and stop. Do not start Wave 2 work from the brief
tonight; "If time remains" items are optional and only after the list above is complete.

## The goal line (rian pastes this after the first turn ends)
Start the session with `/stream-a2`. When that first turn ends, paste this one line; the evaluator
then keeps the session working, turn after turn, until the condition is met or judged impossible:

```
/goal Stream A2 of the Duty Free Professor build is complete: in import/progress.json every one of the task ids R1, R2, R3 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 "A2:"; a handoff entry for this session is at the top of .logs/handoff.md 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 80 turns.
```

