Stats Crawler Control
Steer the public stats crawler — which live channels it discovers, and the curated list of channels to crawl. This is a platform-operator surface: it controls the crawler globally, not a single account's data.
Access
Reaching the Admin app requires admin:access. The crawler controls are then
gated on granular, admin-scope (platform-operator) permissions, seeded to the
system_admin admin role (ZAF-725). They are enforced against the caller's admin
role (require_admin_permission / AdminPermissionGuard), so an account-scope
role grant never satisfies them:
| Control | Permission |
|---|---|
| View the scope mode | crawler:scope-read |
| Change the scope mode | crawler:scope-edit |
| View the watchlist | crawler:watchlist-read |
| Add a watchlist channel | crawler:watchlist-create |
| Remove a watchlist channel | crawler:watchlist-delete |
Every change is written to the operator audit log (crawler:scope_changed,
crawler:watchlist_added, crawler:watchlist_removed).
Scope modes
The scope bounds which live channels the crawler publishes crawl jobs for. It is DB-backed and live — a change takes effect on the crawler's next discovery sweep, with no redeploy.
| Mode | Channels crawled |
|---|---|
| Lumio | First-party roster only (connected Lumio channels). |
| List | The crawl watchlist only. |
| Lumio + List | The union of the two. Default. |
| Global | Every live channel (unfiltered). Kill-switch / ramp target. |
The default is Lumio + List — a bounded, curated set that lets /stats
launch on today's capacity. Global is an explicit, opt-in widening: switch to
it only once the crawler's capacity backbone (broker + cluster) is armed. The
system never widens to Global on its own — an unreachable database falls back to
the configured bounded default, never Global.
Watchlist
The watchlist is the List component of the scope: a curated set of channel
identities (platform + platform channel id) to crawl regardless of whether they
are connected Lumio accounts. Adding a channel is idempotent — re-adding the same
identity updates its labels rather than creating a duplicate. Removing a channel
takes effect on the next discovery sweep.
The watchlist governs which channels are candidates for crawling; it is
distinct from the per-channel opt-out registry (public_channel_settings),
which removes a channel from crawling even if it is in scope. See
Opt-out enforcement.
Using the admin control
The controls live in the Admin app under Stats → Stats Crawler
(/stats-crawler). The nav entry appears only if you hold at least one of the
five crawler:* permissions; each control on the page is additionally gated on
its own permission, so a read-only operator sees the current values without the
edit affordances.
Setting the scope mode
The Crawl scope card shows the four modes as selectable cards with the
current mode badged. Pick a mode and press Apply scope to persist it
(crawler:scope-edit). Selecting Global surfaces an inline warning and turns
the apply button destructive — it is the explicit, opt-in widening to an
unbounded sweep, so it never happens by a single stray click. Without
crawler:scope-edit the cards are read-only and the apply button is hidden.
Managing the watchlist
The Crawl watchlist card lists the curated entries and, for operators with
crawler:watchlist-create, an add form:
- Choose the Platform and enter the Platform channel ID — the channel identity. The optional Login, Display name, and Note are denormalized labels shown in the list.
- Press Add channel. The add is idempotent: re-adding the same
platform+platform_channel_idupdates the labels of the existing entry rather than creating a duplicate, and the row moves to the top of the list. - Remove an entry with the trash button (
crawler:watchlist-delete).
Both scope changes and watchlist edits take effect on the crawler's next discovery sweep and are written to the operator audit log.