Repository navigation
Never lock a person out of their own chat on an older sync service - #2075
Merged
Merged
Conversation
santoshkumarradha
added a commit
that referenced
this pull request
Oct 30, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
santoshkumarradha
marked this pull request as ready for review
October 30, 2026 15:35
A chat whose lease had lapsed could only be written after a conditional take, which the client allowed only when the service promised codeaf-conditional-takes. The deployed hosted service does not, so every lapsed chat was refused: the drive failed, turns were saved locally only, and the next open found this computer's own newer turns and showed the chat read-only behind "Continue this chat here?". A take of a lapsed lease is now made on every service: an older service still refuses a live holder atomically and raises the fence, and the caller checks the head the acquire answers. Only displacing a live holder waits for the promise. Turns this computer sealed on top of the record's head are published when the free lease is taken, instead of opening the chat read-only. The release workflow now probes the live hosted service as a throwaway identity and refuses to build when it lacks a capability this build needs (codeaf-release service). The refusal for the one waiting feature says what still works and what to do. devices revoke --all now removes every device of the name, computers that sync chats included. Part of #2072 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a removed device A chat whose lease this computer held and let lapse read as off, so Home and the card asked "Continue this chat here?" on the only computer that used it, saying "this chat was last held here". With nobody else holding it there is nothing to continue from: it now reads as free and opens. A chat whose holder was removed read as released by that device, so the resume card offered "Continue <removed device>'s latest chat here?". Rows now carry that the holder was removed, and the card never offers it. Part of #2072 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refusal named an operator task and was cut off on a normal terminal. It now says the one thing that waits, that everything else works, and what to do: close the chat on the other computer and continue here. The manual describes the lapsed-chat and older-service behaviour. Part of #2072 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lder A terminal whose environment differs from the running engine was offered only engine --stop, which interrupts the other window. The sentence now offers codeaf chat --no-host first, which opens this window on its own. The folder that holds older chats' live copies is named .moving and reads like a stuck transfer; it now carries a README.txt saying it holds the chats and must not be deleted. Part of #2072 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
santoshkumarradha
force-pushed
the
fix/2072-never-locked-out
branch
from
October 30, 2026 15:41
d4d5720 to
854f3cf
Compare
AbirAbbas
approved these changes
Oct 30, 2026
AbirAbbas
left a comment
Collaborator
There was a problem hiding this comment.
Hand-tested on two computers through a relay that lacks the conditional-take promise: reopening a released chat accepts writes with no card, the other computer continues it (Moved from desk-a … Everything as you left it.) and writes, and devices revoke --all removes the synced computer.
This was referenced Oct 30, 2026
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.
Part of #2072. This covers items A, B (partly, see Limitations), D, F, G, I, L (the sync-service sentence) and M. Items C, E, J and K are handled with #2070.
What a person sees
Before. On the hosted sync service, I reopened a chat whose hold had lapsed on its only computer, typed a message and pressed enter. The words stayed in the box. The chat showed:
Each later enter refused again. A second computer could not continue a chat the first had closed.
codeaf devices revoke <name> --allsaidno device called "<name>" is paired with this machinefor a computercodeaf deviceslisted. After that computer was removed, Home still offeredContinue <name>'s latest chat here?.After.
Continue this chat here?withthis chat was last held here.taking an open chat from another computer waits for a sync service update; all else works, so close it there and continue here. Continuing the chat after the other computer closes it works.codeaf devices revoke <name> --allremoves every device of that name, whichever kind it is.codeaf chat --no-host. That opens the window on its own and leaves the other window running..movingfolder that holds the live copies of older chats now has aREADME.txt. It says the folder holds the chats and must not be deleted.Code
directory.HTTP.Acquirenow needs thecodeaf-conditional-takespromise only for a forced take, that is, taking from a live holder. A take of a lapsed lease is safe on an older service for three reasons:syncsetup.driving, a free lease is taken when this computer's newest turn is the record's head or descends from it (newcellstore.Extends).catchUpthen publishes those turns. A local head that does not extend the record's head still opens read-only, as before.chatlist, this device's own lapsed lease reads asIdleinstead ofOff. Rows carry a newHolderRemovedfield, and the resume card skips those rows.directory.Capabilitieslists each promise this build needs from the service and the feature that waits on it.syncsetup.ProbeServicechecks a live service as a throwaway identity: it registers a device, creates an empty chat record, reads it and archives it.codeaf-release service [--url]exits 1 and names any missing promise.devices revoke --allstops the matching device in every kind. It prints what it stopped even if a later kind fails.codeaf chat --no-host.cell.CopyLegacywritesREADME.txtinto the copy folder once..movingfolder.TestReleasedOlderHeadIsNotAcquiredOverLocalWorkpinned the law that caused the lockout.TestReleasedHeadIsContinuedWithThisComputersNewerTurnsnow pins the opposite.Validation
Red then green
TestOldServiceStillLetsTheOnlyComputerWriteItsChat: two homes, with a real relay that strips the conditional-take promise.TestOldServiceLetsLocalTurnsCatchUpTestOldServiceStillTakesALapsedLeaseTestProbeServiceNamesWhatAnOlderServiceLacks: current service and older service.TestServiceGateFailsAheadOfTheServiceTestThisComputersLapsedChatOpensWithoutAQuestionTestARowSaysItsHolderWasRemovedTestDevicesRevokeAllFindsAComputerThatSyncsChatsTestTheCopyFolderSaysItIsTheLiveStoreSuites
internal/directory,chatlist,cell,relayserve,cmd/codeaf-release, thecmd/codeafdevices and engine-environment tests, and the relatedtui3tests.make test-packed-manual manual-gatespasses.make test-quickpasses.make pr-ready: every failure it reports also fails on unchangedorigin/devhere (listed below), exceptcmd/codeafTestCellRewindRestoresTheWorkspaceTheSessionSealed, which passes alone on both and failed once under the full touched-package loadPre-existing failures. These tests also fail on unchanged
origin/devon the same machine:internal/cellstoreTestStartupInALargeHomeWalksNoHomeinternal/releaseTestC16PromotionTriggerAndCutoff,TestPromotionWorkflowExplainsItsSafetyLawsinternal/syncsetupcost, scope, death-branch, running-take, public-take and drive-timeout testsinternal/syncsetupTestTasklessTakePreservesConversationWorkspaceIdentityfails sometimes on both, after a model-catalog lookup.Live check against the hosted service as deployed today. Two paired computers. Every model role, including router, title and reflex, ran on
deepseek/deepseek-v4.1-flash, as recorded in the transcript.Reply with exactly the word BANANA.BANANA; the service's head equals the local headKIWIsent and answeredcontinue hereon a chat open on the firsttaking an open chat from another computer waits for a sync service update; …codeaf devices revoke alpha --allno device called "alpha" is paired with this machinealpha was removed — it can no longer sync your chats.Continue alpha's latest chat here?CODEAF_SYNC_URL=offwhile one is openengine --stopcodeaf chat --no-host; that window opens, lists chats, andGRAPEis answered; the first window keeps runninggo run ./cmd/codeaf-release servicethe sync service at https://codeaf.agentfield.ai/fabric must be updated before this build ships; it does not promise codeaf-conditional-takes (…)Limitations
.github/workflows/release.yml, because the push token has no workflow permission. A maintainer needs to add the job below and makebuilddepend on it (needs: [prepare, test, service], withneeds.service.result == 'success'in itsif:). Today the job would fail every release, because the hosted service does not answercodeaf-conditional-takes. Deploy the hosted service from currentrelay/hostedfirst.this chat was last held here.continue herethen works. That send-hold logic is part of Continuing a chat on another machine fails silently and can list it twice #2070's scope..movingcopies were not reproduced here.codeaf doctordoes not yet report capability gaps, lapsed holds or removed devices.🤖 Generated with Claude Code