---
status: accepted
---

# Watch registry is a per-repo GitHub masterlist issue with one comment per Watch; the Watch engine polls independently of the gateway

<!-- [doc->REQ-WATCH-REGISTRY] -->

Watches are durable, endpoint-owned interests in a Request's State changes
(ADR-0002), and stand in for cross-Project blocking (ADR-0003) — so losing one
silently is the worst failure shape the system has. The daemon holds the
registry in memory, but the memory copy must be rebuildable after a crash.
ADR-0008 rebuilds all board state from Discord; the registry deliberately does
NOT follow it, because a Watch must survive — and keep firing through — a
Discord outage or an unconfigured bot (Operator ruling, 2026-07-23). The
registry therefore lives in GitHub, the system of record the engine polls
anyway: each watched repo carries one masterlist issue, named after the daemon
node and labeled `kind: SPT-TRACKING (DO NOT DELETE)`, and every Watch is one
machine-parseable comment on it.

One comment per Watch — rather than lines in the issue body — because a body
edit is a full read-modify-write: with shells registering Watches and the
daemon deleting fired one-shots, concurrent body edits silently resurrect
fired Watches or erase fresh ones. Comment create and comment delete are
atomic per-Watch operations, so any shell registers directly with no
daemon-side serialization and no lost updates.

For the same independence reason, the Watch engine (GitHub poll → registry →
durable spt delivery) starts at process start and never touches Discord; the
Discord sync layer attaches when the gateway reaches Ready. Discord and
Watches are separate failure domains: a gateway outage pauses the board, never
the notifications.

## Considered Options

- **Discord registry thread** (ADR-0008 pattern) — same boot-scan machinery as
  the board, but couples Watch durability and firing to exactly the surface
  Watches must outlive.
- **Body-line encoding on the masterlist issue** — human-readable in one
  place, but the read-modify-write race between registering shells and the
  firing daemon loses Watches silently.
- **Local file on the daemon node** — the durable local state ADR-0008 exists
  to avoid; node loss or reconfiguration destroys every Watch with no rebuild
  path.

## Consequences

Registration is a GitHub comment write any bound shell can perform; the
daemon's boot and refresh read the masterlist comments per configured repo.
Firing delivers the durable spt message first, then deletes the comment — a
crash between the two re-fires once, which durable spt messaging tolerates,
and one-shot expiry is idempotent by construction. The masterlist issue is
infrastructure, not a Request: `kind:`-labeled issues are excluded from the
board, from `list`, and from Watch targets. A reader of the repo sees the
registry issue and its label explains itself. The daemon must now run
meaningfully with no gateway — provisioning and reconcile degrade to no-ops
while Watches continue.
