Skip to content

Remove the code the watch relay's deletion left behind - #1615

Merged
suleimansh merged 2 commits into
mainfrom
relay-residue
Aug 21, 2026
Merged

Remove the code the watch relay's deletion left behind#1615
suleimansh merged 2 commits into
mainfrom
relay-residue

Conversation

@suleimansh

Copy link
Copy Markdown
Member

🤖 agent PR

Follow-up to #1611. That PR cleaned up after the watch relay's deletion (#1536); this removes three things it left behind, all verified against its own diff.

What was dead

1. AgentFeed's three display props. AgentView is its only caller, and it passed showSessionLink={false} showName={false} showStatus={false}. With all three false, the AgentOverview they configured hit its own if (!sessionLink && !status) return null — so it rendered nothing, every time. The props and that render are gone.

AgentOverview itself stays: ProjectHome renders it with the defaults, where it does show.

2. The enabled parameter on useWorking / useDaemonHealth / useFavicon. Not merely defaulted — nothing ever passed false. The relay view had been the only caller that did. Removed, with the two tests that existed only to cover it (useFavicon(true, false), and "disabled (the relay) never probes").

3. Stale reasons. Nine files still explained live behaviour by naming the deleted relay — FileTree ("the relay has no checkout"), GitStatusBar ("or on the relay"), EventList ("the read-only relay watch"), RoutineWork's sweep note, plus the favicon and use-daemon-health specs. In each case the behaviour is real and the reason was a ghost, so they now state the condition itself rather than the feature that used to cause it.

The name trap

The device relay (#1067) is a different feature that shares the word: relay-endpoints.ts, relay-dispatch.ts, relay-agent.ts and /_relay are untouched. A source-wide sweep for relay now returns only those.

Notes

  • No FEATURES-SPEC.md change — none of this was user-visible. There is no watch-link row to remove.
  • Suite 1489 + 774 (down two: exactly the tests removed above), typecheck clean.

One thing deliberately not done

EventList's projectId is now only absent in tests: AgentView requires it, so it always reaches EventList through AgentFeed. The same shape as the props above — but EventList is a presentational component whose optional prop is defensible on its own, and making it required would rewrite a dozen tests for no behavioural gain. Left as it is rather than decided unilaterally.

#1536 deleted the hosted watch relay and #1611 cleaned up after it, but three
things it was the only reason for stayed:

- AgentFeed's showSessionLink/showName/showStatus were passed `false` by
  AgentView, its only caller, so the AgentOverview they configured hit its
  `if (!sessionLink && !status) return null` on every render. The props and
  that render are gone; AgentOverview itself stays, since ProjectHome uses it
  with the defaults.
- The `enabled` parameter on useWorking/useDaemonHealth/useFavicon was never
  passed `false` by anything — the relay view had been its only caller. Gone,
  along with the two tests that existed only to cover it.
- Comments and specs across nine files still explained live behaviour by
  naming the deleted relay: FileTree "has no checkout", GitStatusBar "on the
  relay", EventList's "read-only relay watch", RoutineWork's sweep note,
  favicon, use-daemon-health's tests. The behaviour is real in each case, only
  the reason was a ghost — reworded to state the condition itself.

The device relay (#1067) is untouched: relay-endpoints, relay-dispatch and
relay-agent are a different feature that shares the word.

No FEATURES-SPEC.md change: none of this was user-visible.

Suite 1489 + 774, typecheck clean.
…log text

The last of the same shape #1615 removes. AgentView is AgentFeed's only caller
and always passes projectId, so the optional prop had exactly one production
value — and the conditional forward below it could only ever take one branch.

Required is the point, not tidiness: with it optional, a future caller that
omits it gets an open choice gate silently rendered as plain log text, which is
a run parked with nothing to answer it (#846). A required prop makes that a
compile error instead of a dead-quiet downgrade.

EventList's own projectId stays optional. It is a leaf presentational component
with 35 direct test renders, and its browser pane already degrades on a
genuinely nullable agentId, so the absent case is a real render mode there
rather than a fiction.
@suleimansh

Copy link
Copy Markdown
Member Author

🤖 agent comment

Five SPEC.md files change here, one line each. Walking them individually, since a one-line spec edit is easy to wave through and two of these five say something different about the code than the other three.

They split into two kinds: two describe a responsibility that moved, and three delete a reason that named a feature which no longer exists.


1. dashboard/components/AgentFeed.SPEC.md — a responsibility moved out

The file in full as it now stands (its intro sentence is the whole spec — there is no separate TLDR section):

One agent's feed: the live or replayed event log — with a waiting placeholder before anything streams, and a banner while the live stream is down, so a dead connection never reads as the agent going quiet.

-One agent's feed: the overview plus the live or replayed event log — with a waiting placeholder before anything streams, and a banner while the live stream is down, so a dead connection never reads as the agent going quiet.
+One agent's feed: the live or replayed event log — with a waiting placeholder before anything streams, and a banner while the live stream is down, so a dead connection never reads as the agent going quiet.

What it means for the rest of the file: "the overview plus" was describing a render that produced nothing. AgentViewAgentFeed's only caller — passed showSessionLink={false} showName={false} showStatus={false}, and with all three false the AgentOverview underneath hit its own if (!sessionLink && !status) return null. So the feed has never shown an overview to any user; the spec named a component that rendered empty every time. Everything the remaining sentence promises — the placeholder, the down-banner, and the reason for the banner — is untouched and still the whole of what this component does. AgentFeed no longer imports AgentOverview at all.


2. dashboard/components/AgentOverview.SPEC.md — the other half of the same move

The file in full:

The agent-overview cards projected from the event stream — the status line and an honestly-labelled link to the live session — each rendered only once its data has arrived.

-The agent-overview cards projected from the event stream — the status line and an honestly-labelled link to the live session — each rendered only once its data has arrived, with embedding views opting out of the parts their own chrome already shows.
+The agent-overview cards projected from the event stream — the status line and an honestly-labelled link to the live session — each rendered only once its data has arrived.

What it means for the rest of the file: the dropped clause described the three show* props as a feature — "embedding views opting out". There is now no embedding view and no opting out: ProjectHome is the sole caller, and it renders <AgentOverview events={events} /> with the defaults, where both cards genuinely show. The surviving clause "each rendered only once its data has arrived" is the other, real conditionality — the per-card guard on its own data — and that is unchanged. Worth separating the two, because they read alike and only one of them was ever load-bearing.


3. dashboard/components/FileTree.SPEC.md — a ghost reason

The opening, through the flow that changed:

The project panel's file tree — a context picker, not an editor: clicking a file toggles it in the Context (the set of files handed to the agent), the same set the other context pickers feed.

Flows

  • Per-file git-status marks […] roll up to folders […]
  • A filter box narrows to matching files […]
  • Every file previews on hover […]
-- Localhost-only: the relay — watching an agent that executes on another machine — has no checkout to list here, so the tree renders nothing.
+- With no files to list, the tree renders nothing rather than an empty frame.

What it means for the rest of the file: the behaviour is unchanged and still true — an empty tree renders nothing. What changed is that the line no longer explains why it would be empty by naming the watch relay, which #1536 deleted. Read against its three sibling flows, this one now matches their shape: each states a condition and what the tree does under it ("zero matches say so", "its diff when changed, its contents when not"). The old line was the odd one out — it stated a cause that no longer exists, so a reader chasing it would go looking for a feature that isn't there.


4. dashboard/lib/favicon.SPEC.md — same shape

The file in full:

The tab icon follows the work: the still logo while nothing is running, the animated one while an agent is working.

-The tab icon follows the work: the still logo while nothing is running, the animated one while an agent is working — and a view that cannot know (the relay) leaves the icon alone.
+The tab icon follows the work: the still logo while nothing is running, the animated one while an agent is working.

What it means for the rest of the file: the removed clause was the spec for the enabled parameter, and that parameter is gone in this PR — not merely defaulted, but never passed false by anything since the relay view was deleted. With no caller able to say "don't probe", there is no third state left to describe: the icon is still, or it is animated. The two states named in the surviving sentence are now exhaustive, which they were not while the clause stood.


5. dashboard/lib/use-daemon-health.test.SPEC.md — a test spec following its tests

The file in full:

Covers the liveness probe: an answering daemon reads healthy, and a failing one flips to down.

-Covers the liveness probe: an answering daemon reads healthy, a failing one flips to down, and the shared watch view (which has no daemon of its own) never probes.
+Covers the liveness probe: an answering daemon reads healthy, and a failing one flips to down.

What it means for the rest of the file: this one is a claim about what the suite covers, so it has to track the suite exactly. The third clause described a test named "disabled (the relay) never probes", which this PR deletes along with the enabled parameter it existed to exercise. Leaving the sentence would have left the spec promising coverage that no longer exists — the failure mode being that someone later reads it as a guarantee and assumes the case is protected. Two clauses, two remaining tests.


What is not in these five

No SPEC.md file gains or loses a user-facing behaviour, which is why FEATURES-SPEC.md is untouched: there is no watch-link row to remove, and nothing here is visible to a user who never had the relay. Every diff above either deletes a description of a render that always produced nothing (1, 2) or restates a live behaviour without naming a deleted feature as its cause (3, 4, 5).

Also pushed since the PR body was written

c42ed667 settles the "one thing deliberately not done" in the description, in the direction of the PR rather than against it: AgentFeed's projectId is now required. AgentView is its only caller and always passes it, so the optional prop had exactly one production value and the conditional forward below it could only take one branch.

The reason it is worth doing rather than tidiness: with the prop optional, a caller that omits it gets an open choice gate rendered as plain log text — a run parked with nothing to answer it (#846), failing silently. Required makes that a compile error. EventList's own projectId stays optional, deliberately: it is a leaf presentational component with 35 direct test renders, and its browser pane already degrades on a genuinely nullable agentId, so the absent case is a real render mode there rather than a fiction.

Suite unchanged at 774 dashboard tests (no test needed touching), dashboard typecheck clean.

@suleimansh
suleimansh merged commit b853d65 into main Aug 21, 2026
2 checks passed
@suleimansh
suleimansh deleted the relay-residue branch August 21, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant