Skip to content

A displaced window keeps its unsent turns, and a taken chat can be taken again - #2091

Merged
AbirAbbas merged 4 commits into
devfrom
fix/test-reds-2026-10-30
Oct 31, 2026
Merged

AbirAbbas merged 4 commits into
devfrom
fix/test-reds-2026-10-30

Conversation

@AbirAbbas

Copy link
Copy Markdown
Collaborator

Fixes the test failures still red on dev after #2086. Two of them were real bugs in taking a chat from another computer.

What changes

  • A displaced window keeps its unsent turns (code). When an ownership check (CheckLease, from the directory watch or before a tool call) found another device holding the chat, the window became a viewer at once and never told the batcher. So unsent turns were not kept as a branch then. Now:
    • The hold is retired at once, so Gate refuses new work and the send receipt is cleared.
    • A seal already past Gate is allowed to note its turn.
    • Batcher.Displaced resolves the pending work under flushMu.
    • Only then does the window say who has the chat, exactly once.
    • A publish refused with a stale fence goes the same way (OnLost now retires the hold, and resolve announces), so the window no longer says another device continued this chat and then <device> continued this chat a moment later.
    • A direct refusal(ErrFenceStale) still makes the window a viewer at once.
  • A take no longer trips over the sender's old upload note (code). A snapshot carries the sender's .cell/published.json, which names the head published before it. The receiver never fetched that head, so the next take failed with snapshot … is not held in this store. Materialize now records the head it received as published. That head is on the service by definition.
  • R7 flake (test). personalLeader returned as soon as Status answered, while other peers' replies were still on the member socket. R23 then counted those frames as traffic started after the quiet decision, about 1 run in 20. It now waits for the member to go idle. The assertion is unchanged.
  • TestPairJourney. The add-device pitch now comes through the tuiwords table instead of a retyped needle. The home tip is respelled space space brings you back to home, because the journey's vocabulary law forbids "take". The manual pages that quote it are updated.

Proof

These two fail on current dev with the engine staged, and pass on the branch:

Test Failure on dev
TestTwoHomesL12DeathBranches A's branch row = {…}; want 3 turns from tower
TestPublicTakeRestoresEveryWorkspaceSetRoot snapshot … is not held in this store

CI does not stage the engine, so these real-engine tests do not run there.

  • New: TestStalePublishRefusalMakesViewerAndNotifiesOnce, a real stale publish across two homes. The window ends as a viewer, and the notices are exactly [kept edits, superseded].
  • TestAStaleDriveRefusalImmediatelyMakesTheWindowAViewer now also checks that two refusals give one notice.
  • #2086's versions of TestDriveSideSupersededStopsTools, TestDriveSidePublishesOverTheDefaultDaemon and TestTwoHomesTakeARunningChatAtOnce pass unchanged.
  • R7 at -count=100 twice in a row (lane). Locally, R23 did not recur in 50 more runs. Two runs hit a client timeout talking to the local cluster during setup, on a box at load average 8 with other suites running.
  • Focused internal/syncsetup, internal/cellsync, internal/cellstore, internal/tui3 tips, internal/manual, untagged internal/e2e, go vet -tags e2e ./internal/e2e/, and make test-laws.

🤖 Generated with Claude Code

AbirAbbas and others added 4 commits October 31, 2026 01:59
Status returns once one anchor voter answers, while the other peers'
replies and cursor acknowledgments are still on the member socket. R23 then
counted those frames as traffic started after the quiet decision, about one
run in twenty. personalLeader now waits for the member to go idle first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…blished

When an ownership check found another device holding the chat, the window
became a viewer at once and never told the batcher, so unsent turns were not
kept as a branch then (TestTwoHomesL12DeathBranches). The hold is now retired
at once, in-flight seals are let finish, and the batcher resolves pending work
before the window says who has the chat, exactly once.

A taken snapshot carried the sender's earlier upload note, naming a head this
store never fetched, so the next take refused with "snapshot … is not held in
this store" (TestPublicTakeRestoresEveryWorkspaceSetRoot). Materialize now
records the received head as published; it is on the service by definition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestPairJourney retyped the add-device pitch in an older spelling, and its
vocabulary law refused the tip "space space takes you back to home". The
pitch now comes through the tuiwords table, and the tip says "brings".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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