Automations and webhooks for the AT Protocol airglow.run

Watched repos behaviour is unclear #22

Closed tyb.there-hugo.dev
Closed opened by tyb.there-hugo.dev

Problem #

  • The watched repos block only appears for high-volume NSIDs (AutomationForm.tsx:2679), so users don't know it exists for other lexicons.
  • With no repos watched, nothing says the automation watches all repos (index.tsx:329).
  • {{self}} isn't explained.
  • Nothing flags a condition that contradicts the watched set.

Seen in the session #

In https://www.youtube.com/watch?v=5MnT-ZgbBIc:

  • 0:34: "if you do this one, you can add a repo to watch. That's what I want."
  • 1:06.

Fix direction #

Always show the block with an explicit "all repos" default, explain {{self}}, and warn when a DID condition can never match the watched set.

Details: docs/brainstorms/2026-10-17-graze-conference-automation-feedback.md (U6).

Queued: the loop will work on this version of the issue.

loop:queued cid=bafyreih3wf2ltzupjbr4sqz7psdumn3s6up4earbkvusahkbusmwndcssq

Working on this, attempt 1.

loop:claim run=contribute-20261026-153909-3my32g6a5td22 branch=loop/3my32g6a5td22 attempt=1 issue=22

feat(automations): make watched repos visible and explain what they do

The automation form now shows the Watched repos block for every valid lexicon, not only for NSIDs that require it. When no repo is listed, the form says so outright ("Watching all repos"), and the block explains {{self}}. Any event.did check that can never pass with the watched set gets a warning on the check itself, plus a summary in the Watched repos block. The automation page now always has a Watched repos row: it says "All repos" when the list is empty and marks {{self}} as the owner's DID.

Verification #

  • pnpm run check passes (format, lint, types).
  • pnpm run test passes: 169 files, 2624 tests.
  • New unit tests in app/islands/step-drafts/watched-repos.test.ts cover the conflict finder: no watched repos, {{self}} vs. the owner's DID, an unknown owner, neq on the only watched repo, templated values, and nested branches.
  • New form tests in AutomationForm.test.tsx cover: the block on a custom lexicon with the all-repos default and the {{self}} explanation, the required variant, the warning appearing and then clearing once the repo is added, and no warning when the check names a watched repo or nothing is watched.
  • New page tests in [rkey]/index.test.tsx cover the "All repos" row and the {{self}} note.
  • I did not check this in a browser. The dev server and PDS were not available in this run.

Acceptance criteria #

Decisions you can reverse #

  • Which checks get flagged: only event.did equals a literal DID or {{self}} that is not watched, and does not equal the only watched repo. Other templates (e.g. {{someVar}}) and other operators are never flagged. Neither is a watched entry that is not a DID yet. Without a known owner DID, {{self}} is treated as possibly matching any DID, so it never causes a false warning.
  • Where the warning shows: it appears on any matching check anywhere in the tree, including inside branches, where it means the then side never runs.
  • Legacy branch removed: the old read-only view ("This NSID no longer requires watched repos... Clear watched repos") is gone. Watched repos are now editable for every NSID, so such rows simply show their list with a Remove button on each entry.
  • Wording: for non-gated NSIDs the legend now reads "(optional)".

Review: https://tangled.org/exosphere.site/airglow/compare/main...loop/3my32g6a5td22

loop:pushed run=contribute-20261026-153909-3my32g6a5td22 sha=2e82fe967e16447ca245ea47c42948f22b1d9b6d

Verdict: merge. The branch covers all four points of issue #22. The Watched repos block now shows for every valid NSID, marked "(optional)" or "(required)". With no repos watched, the form and the automation page both say all repos are watched. {{self}} is explained in both places, and an advisory warning flags event.did checks that the watched set makes impossible. pnpm run check and pnpm run test both pass on 2e82fe9.

What I checked and how:

  • Commands: ran pnpm run check (format, lint and types all clean) and pnpm run test (169 files and 2624 tests, all passing).
  • Always showing the block is safe: the server accepts wantedDids for any NSID. validateWantedDids and resolveWantedDids in lib/actions/validation.ts only apply the required gate. The Jetstream consumer (canonicalDids and _doRefresh in lib/jetstream/consumer.ts) subscribes per DID set for every lexicon, and an empty list means the global stream. So the "Watching all repos" default and the hint text are accurate. The legacy read-only "no longer requires watched repos" view is replaced by the normal editable list, and that list still saves correctly.
  • The conflict finder (app/islands/step-drafts/watched-repos.ts):
    • It walks the whole draft tree through iterateDrafts.
    • It treats {{self}} as the owner's DID, and as unknown when there is no owner DID, so there are no false warnings.
    • It ignores other templates, and it skips everything while a watched entry is still half-typed.
    • It only flags eq on a DID that is not watched, and neq on the only watched repo.
    • It matches the event.did field the same way self-pattern.ts does.
    • The warning is advisory only: the test confirms submit stays enabled.
  • The automation page (index.tsx): the Watched repos row now always shows, with "All repos" when the list is empty and "(the owner's DID)" next to {{self}}. Both are tested.
  • Tests: the new tests cover the finder (empty list, self vs. owner, unknown owner, neq, templates, nested branches), the form block (custom lexicon, required variant, a warning that appears and then clears, quiet cases) and the page row.
  • Scope: no migration, and nothing changed outside the issue.

Minor note, not a change request: for a condition set to match "any", one impossible event.did row does not make the whole condition impossible. The per-row wording ("This check can never pass") is still literally true for that row.

loop:verdict run=review-20261026-154823-3my32g6a5td22 sha=2e82fe967e16447ca245ea47c42948f22b1d9b6d verdict=merge

Merged onto main as fe70e1fdd334e214743ade6447617bdc44ce1463.

loop:merged sha=fe70e1fdd334e214743ade6447617bdc44ce1463 head=2e82fe967e16447ca245ea47c42948f22b1d9b6d

Sign up or Sign in to add to the discussion.