cmux-next: session registration resyncs on a same-process reconnect, and a seen refusal does not show again
Summary
Follow-ups from the sixth review of #28056 (B7a, session registration). Stacked on #28056: this branch starts at #28056's head 8f39adf578f; it should land after #28056, and its own diff is the two commits on top.
- Same-process reconnect.
SessionRegistrar's observation key now holds the home store's connection epoch. A disconnect and a reconnect to the same daemon process that both landed before one key check gave an equal key, so a record waiting for an event after its timed retries was not sent again. The epoch changes only together withconnectionState, so it adds no wakeup. - A seen refusal no longer shows again.
SessionRegistrationforgot the shown refusal whenever a new send dropped a pending notice, also a "no answer" notice; a refusal the person had already seen then showed again. It now remembers which pending notices are refusals and forgets only those. SessionRegistrationLedger.retain's doc now says the owner forgets a gone session's shown refusal.- Arabic and Thai reasons no longer use one word for both "record" and "log" (the same issue fixed for Spanish in #28056).
Not in this PR: a test that drives SessionRegistrar's observation loop end to end (start the registrar, reconnect or restart the home daemon, check that put-session is sent again). My first note said this needs a production seam; the review showed it does not: existing tests start a real DaemonService against a same-tree cmux-tui (AgentCLIUpdateRecoveryJourneyTests.swift:24-45, also AgentTabSessionTopologyTests, ClassicImportTests). It is a named follow-up as an integration test of that kind. Today the epoch regression test covers homeKey only; that SessionRegistrar passes store.connectionEpoch is checked by reading, not by a test.
Known edge cases, older than this PR (review, low): after a refusal, a "no answer" toast and the same refusal again on a new epoch, the toast keeps the "did not answer" reason (the "not saved" statement stays true); and with refusal A shown, refusal B pending with no window, then the record back to A, A shows a second time (the ledger remembers one shown record per session).
R9: the change is in the notice rule (R-L5: a lost record is shown, once per refusal the person has not seen) and the resend trigger; no new cap.
Owner of the area: PL-daemon (session cmux-b6), plans/cmux-next/OWNERS.md.
Testing
Red commit 2f43463caf2 (tests, homeKey takes the epoch and ignores it), fix e250cb29ef5. The test files are the same at both (git diff 2f43463caf2 e250cb29ef5 -- Packages/macOS/CmuxNext/Tests is empty).
SessionRegistrarWiringTests.aReconnectToTheSameDaemonProcessChangesTheKeySessionRegistrationTests.aDroppedNoAnswerNoticeDoesNotShowASeenRefusalAgain
Compile-check of the head and the Mac red (at 2f43463caf2) and green (at the head) of both suites: job ids follow in a comment.
Observed / Not run
- Observed:
prepush-gate.py --base 62e7f04c16b(#28056's merge base) adds no violations;check-l10n.shhas 0 errors at its ceiling. - Not run: the fleet jobs (pending). No live check in a running app. Austin's-day numbers: pending harness; no restore step in the scenario.
Changelog
none
Proof
No capture: the only UI is the existing text toast; this changes when it shows, not how.