---
type: run
---

# Scout window, 19 Sep 2026 (from the worktree, no collection): candidate hosts for three new collectors

Opened by Stream AW1 (task AW1.1, the away run `AWAY-2026-09-19.md` section 1 grants it) before
the first request. **Not a collection.** Per host at most three requests, each after the host's
own published crawl delay (the slower of theirs and 1 s): `robots.txt`, the discovery page, one
listing page. `main/scripts/scout-source.py` makes them with the collectors' own readers and
parsers (`robots.read`, `fetch.fetch`, `avolta.parse_product_variants`, `shopify.shelf_vertical`)
and our declared identity. A 401 or 403 at robots, or a block on content, is REFUSED: recorded
below, the host never asked again. A hostname that does not resolve gets no request at all.
Nothing is written to any database; the fixtures land in `main/tests/fixtures/scout/`, the
per-host JSON in `scout-2026-09-19c/report.jsonl`, the logs in `scout-2026-09-19c/<host>.log`.

## Every host this window may contact (nothing else)

**The platform registry, read once (two requests: robots, `/en/`):** `www.shopdutyfree.com`.
Its embedded storefront list (`locationconfig.locations`, `.logs/planning/poc-dfp.md` F1) names
which subdomains exist; dead legacy subdomains still resolve and 301 to this hub, so the
registry decides, never DNS.

**Avolta, UK, on Heathrow's pattern (`<name>.worlddutyfree.com`):** `london-gatwick`,
`manchester`, `london-stansted`, `edinburgh`, `glasgow`, `birmingham`, `bristol`.

**Avolta, `<name>.shopdutyfree.com`, the exact subdomain the registry names for each of:**
Vancouver, Las Vegas, Los Angeles, San Francisco, Melbourne, Helsinki, Lisbon, Milan. A
storefront the registry names that is not one of these eight is not contacted. An airport the
registry does not name is "no such storefront" and gets no request.

**Shopify, Attenza (Motta Internacional) sibling storefronts `<cc>.attenza.net`** (`pa`, `co`
and `es` are already collected and are not contacted): `ec`, `gt`, `ni`, `hn`, `cr`, `pe`, `cl`,
`bo`, `do`, `uy`, `py`, `ar`, `mx`, `br`. Two requests each (robots, `/products.json?limit=250`).

**ARI on the Salesforce shape:** no second host is named anywhere in the code or `.logs/`, so
none is contacted.

**Never:** any host `sweep plan` lists as refused (the four Heinemann hosts, iShopChangi),
Dubai, Singapore, or any host already collected.

## 18:20 UTC: a second pass on the eleven Avolta hosts, two more requests each

The first pass read, as its one listing, the first drinks link the collector's own rule finds on
`/en/`: the tree root (`/en/44/liquor`). That is the page the collector reads first too, but it
is not the grid. At the four `shopdutyfree.com` hosts it carried no tile at all (a landing
page); at the seven UK hosts it carried a carousel of the same 18 to 34 products at every
airport, written in a shape the parser does not read (`href` before `class`). Neither says what
a category grid holds, and the grid is where every Athens and Heathrow price comes from. So the
scout now prefers a category one level below the root, and reads each of the eleven hosts once
more: `/en/` again (the category list was not kept) and one child category, after the host's
delay, with the robots.txt saved in the first pass evaluated offline (no re-read). That is five
requests per Avolta host in this window instead of the three announced; the extra two are
recorded here before they are made, and the reason is the scout's own choice of page, not the
host's. The hub and the Attenza hosts are not touched again (Ecuador's third request, its home
page, is in its log: the feed names no airport). First-pass pages are kept in the session
scratchpad only.

## Per-host table (closed 19 Sep 19:05 UTC)

Pass 1 read robots, `/en/` and the tree root; pass 2 read `/en/` and one child category with the
saved robots. "tiles" and "barcode share" are the collector's own parser on the child grid
(`gtin_from_sku` on the tile SKU). Every robots.txt answered 200 (the hub 404: no rules);
**no host refused**. The hub took three requests (the first read kept no body).

| host | platform | robots | delay | page-one-only | currency (form) | grid read | tiles | barcode share | requests | outcome |
|---|---|---|---|---|---|---|---|---|---|---|
| www.shopdutyfree.com | hub | 404, no rules | 1 s | | | `/en/` | 171 storefronts in the registry | | 3 | ok |
| lasvegas.shopdutyfree.com | avolta | 200 | 60 s published | no (paged) | USD (currency_code) | `en/6/wines-spirits/champagne-sparkling-wine` | 15 (4 multi-size) | 33% (5) | 5 | ok |
| london-gatwick.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/99/liquor/aperitifs-digestifs` | 9 (1 multi-size) | 22% (2) | 5 | ok |
| helsinki.shopdutyfree.com | avolta | 200 | 60 s published | no (paged) | EUR (currency_code) | `en/44/liquor/aperitifs-digestifs` | 10 (3 multi-size) | 20% (2) | 5 | ok |
| manchester.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/95/liquor/aperitifs-digestifs` | 9 (0 multi-size) | 22% (2) | 5 | ok |
| london-stansted.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/75/liquor/aperitifs-digestifs` | 9 (1 multi-size) | 22% (2) | 5 | ok |
| edinburgh.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/117/liquor/aperitifs-digestifs` | 9 (1 multi-size) | 22% (2) | 5 | ok |
| birmingham.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/16/liquor/aperitifs-digestifs` | 9 (1 multi-size) | 22% (2) | 5 | ok |
| bristol.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | GBP (currency_code) | `en/113/liquor/aperitifs-digestifs` | 9 (1 multi-size) | 22% (2) | 5 | ok |
| ec.attenza.net | shopify | 200 | 1 s ours | no (feed) | USD (home page) | `/products.json?limit=250` | 134 variants on 102 of 250 products in scope (60 drinks, 42 beauty) | 1% (1) | 3 | ok; the shop names Quito Mariscal Sucre (UIO) |
| milan.shopdutyfree.com | avolta | 200 | 60 s published | yes (`Disallow: /*?`) | EUR (currency_code) | `en/141/liquor/aperitifs-digestifs` | 29 (4 multi-size) | 3% (1) | 5 | ok |
| vancouver.shopdutyfree.com | avolta | 200 | 60 s published | no (paged) | CAD (currency_code) | `en/18/wines-spirits/aperitifs` | 1 (0 multi-size) | 0% (0) | 5 | ok |
| glasgow.worlddutyfree.com | avolta | 200 | 30 s published | yes (`Disallow: /*?`) | | pass 1: the root (carousel, unparsed); pass 2: `en/122/liquor/2-for-20` | | | 5 | error: https://glasgow.worlddutyfree.com/en/122/liquor/2-for-20 returned HTTP 404 |

**No request at all** (hostname does not resolve): ar.attenza.net, bo.attenza.net, br.attenza.net, cl.attenza.net, cr.attenza.net, do.attenza.net, gt.attenza.net, hn.attenza.net, mx.attenza.net, ni.attenza.net, pe.attenza.net, py.attenza.net, uy.attenza.net. **Not a storefront** in
the registry, so never asked: Los Angeles, San Francisco, Melbourne, Lisbon.

Fixtures for the tasks that follow: `main/tests/fixtures/scout/<host>_robots.txt` (as read) and
`<host>_listing.html` (the child grid's tiles, imagery, copy, scripts, styles and form inputs
stripped; each parses to exactly the rows its raw page did) and `ec-attenza-net_products.json`
(the first ten in-scope feed products through `facts_only`). Raw pages stayed in the session
scratchpad. Chosen three and the ranking: the brief's Design decisions section.
