fix(web): no fleet, no fleet band - #49
Merged
Merged
Conversation
The sessions screen's gap band tells a reader their browser holds no key for the fleet and that pairing again from any machine on it will fix that. On a machine with no relay every clause of that is false: there is no fleet, no others to be missing, and no machine to pair against — and it is advice that cannot be followed and would fix nothing if it were. The band is fed by FleetGaps, which only an expansion produces, so it could only ever appear on a tab that had learned a relay origin. What it never did was give that origin back. A tab open across a `flue relay leave`, or a relay.json deleted by hand and the daemon restarted under it, reconnects to a welcome naming no relay at all — and kept the last expansion's counts for the life of the tab, plus a discovery tick asking a directory through a machine that had left, once a minute and on every focus, for an answer that can only be its own daemon's 404. So the fleet reads the fact it was already sent and ignored: a welcome with no relay on it — absent, or `off`, which the protocol says are one statement — is this machine saying it is on none. The origin goes, the once-per-epoch expansion flag goes with it so a machine that joins again builds against the new origin, and the gaps snapshot goes because it describes a fleet that is not there. noteGaps refuses a late one for the same reason, so an expansion still in flight cannot put the band back up. The slots already built stay: this machine leaving a relay says nothing about whether the others are still on it, which is the same reason adoptRemotes is additive. What each state says now. No relay, this load or since: nothing — one machine and no relay is a whole state, and the invitation to set up remote access belongs to the Remote screen, which can carry it out. A relay and no fleet key with no ceremony to this browser's name: the enrolment story from #46, unchanged — enrolThisBrowser answers a bare boolean, so 409 (this machine holds no fleet key) and 502 (the relay would not answer) cannot be told apart here, and `check flue status on this machine` is the honest sentence for both. A relay, no fleet key, and a machine this browser paired with: that machine is about to hand one over, unchanged. A relay and machines with no certificate to present to: unchanged. Tests: two at the fleet, two at the screen. The screen's `takes the band down when its machine leaves the relay` is the one that reproduces the report — it fails on main with the band still up, its text quoted in the diff — and `stops reading once the machine has left the relay it named` fails at four directory reads where it wants one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The state that produced the wrong advice
The fleet gap band on Sessions says this browser holds no key for the fleet and
that pairing again from any machine on it will fix that. On a machine with no
relay, every clause is false — there is no fleet, no others to be missing, and
nothing to pair against — and it is the first screen a new user opens.
The band is fed by
FleetGaps, which only an expansion produces, so it can onlyappear on a tab that has learned a relay origin from its daemon's welcome. What
the fleet never did was give that origin back. A tab open across a
flue relay leave— or arelay.jsondeleted by hand and the daemon restarted under it —reconnects to a welcome naming no relay at all, and on
mainit keeps:on describing a fleet that no longer exists; and
that has left the relay, once a minute and on every focus, for an answer that
can only be its own daemon's 404. (Measured: four reads in the three minutes
the new test covers.)
The fix
localWelcomenow reads the fact it was already being sent and ignoring. Awelcome with no relay on it — absent, or
status: 'off', whichclient/protocol.tssays are one statement — is this machine saying it is onnone. The origin is dropped, the once-per-epoch
expandedflag goes with it soa machine that joins a relay again builds against the new origin, and the gaps
snapshot is dropped because it describes a fleet that is not there.
noteGapsrefuses a late one while no relay is known, so an expansion still in flight when
the welcome lands cannot put the band back up.
A relay that is merely
connectingis a relay — configured, dialling, about toname an origin — so it is untouched. The slots already built stay exactly where
they are: this machine leaving a relay says nothing about whether the other
machines are still on it, which is the same reason
adoptRemotesis additive.No new fetch and no new wire field: the signal was already on every welcome.
What the band says in each state
welcome.relayabsent oroff)flue statuson this machine, then reload."On the loopback-with-relay case specifically:
enrolThisBrowseranswers a bareboolean, so 409 (this machine holds no fleet key), 502 (the relay would not
answer) and 404 (an old daemon) are indistinguishable by the time anything
downstream sees them. Wiring that distinction means changing enrolment's return
type, the
FleetOptions.enrolseam andFleetGaps— a larger change than thisone, through the trust path — so the band keeps #46's sentence, which is already
the enrolment story rather than pairing advice and is true of all three. Left
for a follow-up if that state turns out to be common.
Test evidence
Four new tests; three fail on
main.The report, at the screen —
sessions.test.tsx, takes the band down whenits machine leaves the relay. Fails on
mainwith the band still up:The pointless reads —
fleet.test.ts, stops reading once the machine hasleft the relay it named:
expected "vi.fn()" to be called 1 times, but got 4 times.The rejoin — expands again for a machine that joins a relay a second time:
expected 2 times, but got 1 timesonmain, becauseexpandedwas neverlowered.
The snapshot — forgets the fleet when the welcome says this machine is not
on a relay:
fleet.gaps()is non-null onmain.Plus one guard that passes before and after, pinning the state in the report
outright: says nothing at all about a fleet on a machine with no relay —
welcome with no relay, one machine, no band, and the session still listed.
styles.build.test.ts(the real vite build, guarding the Tailwind prosescanner) is in that run and green — the new comments were written with it in
mind. No Go touched.
🤖 Generated with Claude Code