Repository navigation
Calm connectivity: degrade hysteresis, staging sweep race fix, quiet reconnect UI - #170
Merged
Merged
Conversation
…t pill Four v0.2.12 field reports (wing, office/enterprise networks): 1. Amber warnings flashing ~300ms above the composer on chat switches, 'Reconnecting' before sends, and 'Queued' rows on strong networks: the raw connectivity snapshot reported any room mid-join / idle-link wake as degraded. compute_connectivity now runs show-slow/hide-fast hysteresis (DegradeGrace, 4s) per source (OS path, registry, per-chat room) — raw degradation must persist before it is reported; recovery is instant. Every consumer (pill, composer notice, Queued/Failed row states, send_queued) calms down at once. 2. 'Couldn't stage the attachment locally' on healthy machines: sweep() reclaimed EMPTY staging dirs unconditionally, racing the window between a parallel chunk's create_dir_all and its first write (3-wide uploads made this live; lockstep no-delay retries re-collided). Empty dirs are now judged by their own mtime against the TTL, and chunk retries stagger by seq. 3. Reconnecting UI restyle: the amber bordered strip (+ raw transport error dump) becomes one quiet frost line — neutral dot + 11px muted text, fade-in entrance, amber reserved for hard OS-offline; the composer notice likewise drops its warning box for a caption line. Retry countdown and last-failure detail removed from the sidebar. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wing on the frost chip: still reads as a foreign pill. Drop the surface and border entirely — reconnecting is the sidebar's own mini gradient spinner + a faint caption; offline keeps the amber dot. Transparent, borderless. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Same 2x3 snake grid and timing as the brand spinner, single flat tint (theme.text_muted) so the connection line stays neutral in both themes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wing's v0.2.12 report, the worse half: a failed attachment stage on a
NEW-chat send didn't just error — it stranded the user inside a
just-created empty chat with the message gone ('completely failed and
showed an empty transcript').
The send pipeline created state before it was entitled to: CreateChat
mutate ran before staging, and the composer had already selected the
minted chat and cleared the input. A staging failure then removed the
echo — empty transcript, empty composer, orphaned sidebar row.
- Attachments now stage FIRST, before the chat row or worktree spec
exist anywhere. Staging is chat-independent (uploadId-keyed), so a
failure aborts with NOTHING created. Both flows (queued local-stage
and legacy host-stage) move together.
- A post-mutate failure (QueueCommand) best-effort deletes the minted
row — no orphan either way.
- Failure restore targets the CANVAS for new chats: back to the
new-session canvas, prompt text and attachment stash restored under
the canvas key, banner keyed there too. Handles both re-key
orderings (the deleted row's watch event can re-key before the
failure handler runs — verified live in the rig; the draft-swap-only
variant lost the text to that race).
Verified E2E on the headless rig: read-only uploads dir + new-chat
image send → canvas retained, no sidebar row, banner + text + chip all
restored. 737 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tobi404
pushed a commit
to tobi404/comet
that referenced
this pull request
Aug 20, 2026
…sh#159/zeronsh#164/zeronsh#165/zeronsh#168/zeronsh#170 port) Send truth: - ConnectivityCenter: graced connectivity (DegradeGrace 4s per source — OS path / registry room / each open chat room; recovery reports instantly) feeding one stream every consumer inherits calm from. - Home bar: quiet "Reconnecting…" spinner / amber "Offline — sends are saved" dot, only while degraded past the grace. - Rows: amber "Queued" / red "Failed" corner pills override the status (and suppress the Working spinner — no fake progress); session strip shows "Sending…" / "Queued — will send automatically" / "Not delivered — tap to retry" with a 2-minute undelivered grace; retry restarts the clock, kicks the room, nudges the host, and re-derives escorts. - Composer: one caption line of pre-send honesty on a degraded path. Attachments: - PR zeronsh#164 uploader: ~510KB chunks (was ~45KB), 3-wide window, per-chunk retries staggered by seq, whole-upload deadline min(120+15/chunk, 900s), "Uploading… N%" narration. - Queued flow (host ≥ 0.2.12, version-gated via the registry device row): the command queues immediately with pending://{uploadId}/{name} refs — a durable local write — bytes stash to disk and an escort pushes them with retry-forever on the online bus (2s→30s backoff, 15min cap), surviving relaunches via re-derivation from the doc's pending refs. An image send no longer dies with a dead link (Aug 19 incident class). New chats: - New-worktree sends attach RunRequest.worktree {repoPath, base} for the HOST to materialize at drain time — the blocking CreateWorktree relay RPC before send (the one path that could hang forever on a zombie link) is gone; base defaults to HEAD so a branch list that never loaded can't silently drop isolation. - Legacy hosts stage attachments BEFORE the chat row exists — an upload failure aborts with nothing created, no stranded empty chat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
guilhermexp
pushed a commit
to guilhermexp/comet
that referenced
this pull request
Aug 30, 2026
Calm connectivity: degrade hysteresis, staging sweep race fix, quiet reconnect UI
guilhermexp
pushed a commit
to guilhermexp/comet
that referenced
this pull request
Aug 30, 2026
…sh#159/zeronsh#164/zeronsh#165/zeronsh#168/zeronsh#170 port) Send truth: - ConnectivityCenter: graced connectivity (DegradeGrace 4s per source — OS path / registry room / each open chat room; recovery reports instantly) feeding one stream every consumer inherits calm from. - Home bar: quiet "Reconnecting…" spinner / amber "Offline — sends are saved" dot, only while degraded past the grace. - Rows: amber "Queued" / red "Failed" corner pills override the status (and suppress the Working spinner — no fake progress); session strip shows "Sending…" / "Queued — will send automatically" / "Not delivered — tap to retry" with a 2-minute undelivered grace; retry restarts the clock, kicks the room, nudges the host, and re-derives escorts. - Composer: one caption line of pre-send honesty on a degraded path. Attachments: - PR zeronsh#164 uploader: ~510KB chunks (was ~45KB), 3-wide window, per-chunk retries staggered by seq, whole-upload deadline min(120+15/chunk, 900s), "Uploading… N%" narration. - Queued flow (host ≥ 0.2.12, version-gated via the registry device row): the command queues immediately with pending://{uploadId}/{name} refs — a durable local write — bytes stash to disk and an escort pushes them with retry-forever on the online bus (2s→30s backoff, 15min cap), surviving relaunches via re-derivation from the doc's pending refs. An image send no longer dies with a dead link (Aug 19 incident class). New chats: - New-worktree sends attach RunRequest.worktree {repoPath, base} for the HOST to materialize at drain time — the blocking CreateWorktree relay RPC before send (the one path that could hang forever on a zombie link) is gone; base defaults to HEAD so a branch list that never loaded can't silently drop isolation. - Legacy hosts stage attachments BEFORE the chat row exists — an upload failure aborts with nothing created, no stranded empty chat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
guilhermexp
pushed a commit
to guilhermexp/comet
that referenced
this pull request
Aug 30, 2026
…lity ios: port the network-reliability train (PRs zeronsh#159/zeronsh#164/zeronsh#165/zeronsh#168/zeronsh#170) to mobile
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.
Fixes the four v0.2.12 field reports on healthy networks:
1. Flashing warnings / phantom "Queued" / "Reconnecting" before sends
compute_connectivityreported raw socket state, so a chat room mid-join (every navigation), an idle link waking for a send, or any sub-second dial read as degraded — flashing the amber notice for ~300ms and stamping sends "Queued" on enterprise-grade connections.Degradation is now hysteretic (
DegradeGrace, engine-side): a source (OS path / registry room / per-chat room) must be raw-degraded for 4s continuously before it's reported; recovery reports instantly. All consumers (pill, composer notice, row Queued/Failed, send_queued) inherit the calm from the one stream. Unit-tested over injected instants.2. "Couldn't stage the attachment locally"
A real race shipped in the parallel-chunk upload path:
Uploads::appendrunssweep()before writing, and sweep reclaimed empty staging dirs unconditionally — deleting a sibling chunk's just-created dir between itscreate_dir_alland first write. 3-wide chunk concurrency made the window live, and the no-delay lockstep retries re-collided. Empty dirs are now judged by their own mtime against the 10-min TTL (regression test included), and chunk retries stagger byseq.3. Reconnect UI restyle
The amber-bordered strip with the raw transport-error line is gone. Degraded states render as one quiet frost pill — neutral dot + muted 11px label, fade-in entrance — with amber reserved for hard OS-offline. The composer notice drops its warning box for a single caption line ("Messages will send once the connection recovers."). Retry-countdown and last-failure text removed from the sidebar (they read as debug output; the detail still lands in logs).
4. Atomic new-chat sends (the "empty transcript" report)
The staging failure had a worse half on new-chat sends: the pipeline created state before it was entitled to (CreateChat mutate ran before staging; the composer had already selected the minted chat and cleared the input), so a staging failure stranded the user inside a just-created empty chat with their message gone.
Verified E2E on the headless rig — read-only uploads dir + new-chat image send: canvas retained, no stranded sidebar row, banner + prompt text + attachment chip all restored:
Tests
degrade_grace_tests(blip-never-reports, persist-then-report, hide-fast, per-source independence),sweep_spares_a_fresh_empty_staging_dir.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Screenshots
Degraded posture (dead edge, >4s — so the grace has expired and the state is real). Reconnecting is a transparent grayscale spinner + faint caption — no surface, no border:
Detail — sidebar spinner line and composer caption:
On healthy networks neither element ever renders — sub-4s blips (room joins, idle-link wakes, navigation dials) report Connected.