githubnext/ace2Public

Ace: a collaborative coding environment on the team's own machines

fix(host): recover open transcript watches after channel workers restart #159

Mergediamnbutlermerged 2 commits intomainfromrefs/pull/159/head
  1. IA

    Fixes #153. Dogfooding #5.

    **Before:** when a channel's worker restarted (for example `ace kill` then `ace ask`), the open chat stayed blank or stale while listings updated. Worker connections and peer `GatewayClient`s ended watches silently; the app only re-watched when its own gateway reconnected.

    **After:** the app's transcript replays in place on the same gateway connection and shows new output.

    **Watch lifetime** - The app's `useTranscript` owns each watch. Relays (worker or hosted `Connection`, the gateway, a peer `GatewayClient`) report how a watch ended and drop it; they never re-watch on their own. - A failure frame after a watch's accepted reply means it ended: released, or its worker, hosted connection or peer gateway closed. Only `watch` requests keep relay entries. - `useTranscript` resets, re-fetches info and replays. It ignores watches it released and stops after 3 quick ends with Try again. A rejected watch retries only when asked, or once when an offline channel becomes reachable. - **Delete:** `remove()` keeps the worker lock and removes `channel.json` first; workers read the record only after taking the lock. A recovering watch can't start a worker over a channel being deleted.

    **Rolling compatibility:** the channel `Event` union is unchanged; older clients drop a late failure frame, as they do today. No stored format changes.

    **Evidence:** `bun types`, `bun run ci`, React Doctor 100/100 on changed files, and GitHub CI. The real transport smoke used workers and Anthropic `claude-haiku-4-5`.

    **Headless React verification:** 32 of 32 checks passed using the built app in headless Chromium against the isolated source host. Covered: - kill while selected, then in-place restore; - a composer ask; - the 3-end limit and Try again; - release on channel switch; - CLI and app-menu delete; - host restart.

    Duplicates were checked with durable entry IDs. Details are in #153.

    **Pending** - Native app validation. - A physical two-host interruption. - Offline → reachable retry with real peers. - Unknown-chat rejection, which the UI can't reach, is transport-only.

    ### Built in Ace

    The implementation, smoke runs, commits and PR were done by an agent in the Ace channel `channel-watch-recovery`. Codex was used outside Ace to coordinate concurrent lanes and to independently review the code and this PR, because Ace can't run Codex as an external harness yet (#9). React was verified in headless Chromium through the shell because Ace has no browser automation surface (#50), and native capture is blocked while the macOS session is locked.

  2. iamnbutlerconvert-to-draftlast month on GitHub

  3. iamnbutlerreferenced this in Reattach the open chat watch after its channel worker restarts #153last month on GitHub

  4. iamnbutlerreferenced this in Desktop tools unavailable when a source CLI starts a worker in an installed app's data directory #128last month on GitHub

  5. iamnbutlerreferenced this in feat(app): add channel header agent and desktop access toggles #161last month on GitHub

  6. iamnbutlerreferenced this in Show and change collaborator agent invocation in the app #158last month on GitHub

  7. iamnbutlerreferenced this in Make stale worker.pid reclaim atomic so two workers cannot own a channel #166last month on GitHub

  8. iamnbutlerreferenced this in [Meta] Dogfood Ace end to end #5last month on GitHub

  9. iamnbutlerreferenced this in Reach teammates' terminals through the gateway #11last month on GitHub

  10. iamnbutlerready-for-reviewlast month on GitHub

  11. iamnbutlermerged 824d497d399elast month on GitHub

  12. iamnbutlerclosedlast month on GitHub

  13. iamnbutlerreferenced this in Verify Ace with two machines on the tailnet #10last month on GitHub