Repository navigation
fix: keep loaded conversations visible while disconnected - #1950
roboclaw-bot wants to merge 10 commits into
Conversation
Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com>
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 8a49c09f-5192-4363-999c-1e3b9fb2d587
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. What this changesRetains loaded native conversations during disconnection and verifies connection identity before restoring chat access. Example: Disconnect while reading the fixture's 240-message conversation with an unsent draft.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 2 items remain This PR addresses a bug still present on main and merits continued work; it remains a conflicted draft with no newly identified source defect. Priority: P2 Before merge
FindingsNone. Tests
Agent review detailsHow this fits togetherThe chat coordinator consumes manager-owned operator connections, binds them to the conversation provider, and supplies snapshots to the native Reactor timeline and composer. flowchart LR
A[Connection manager] --> B[Chat provider connection]
B --> C[Retained gateway bridge]
C --> D[Gateway client transport]
C --> E[Conversation provider]
E --> F[Native timeline and composer]
Technical reviewBest possible solution: Retain the existing provider through same-authority outages while preserving current-main navigation and voice behavior and restoring IO only after fresh verification. Do we have a high-confidence way to reproduce the issue? Current-main SetOperatorClient(null) unconditionally disposes the conversation provider, establishing the reported path from explicit disconnection to loss of the mounted conversation; no runtime reproduction was performed in this review. Is this the best way to solve the issue? The stable binding and verified recovery fit the existing connection and conversation owners, and the new bridge has a distinct lifetime from its immutable client adapter; source review found no smaller complete repair that preserves the demonstrated authority and cancellation boundaries. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 122bda71b221. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
Likely related people:
Preflight sourceSource unknown. Source comparison at the observed PR snapshot only. Completion is self-reported; body, policy, tests, execution, and report bytes are not verified. Review metrics
LabelsLabel changes:
Label justifications:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (8 earlier review cycles)
Reviewed November 6, 2026, 12:53 AM ET / 05:53 UTC (Revision 9). |
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 55af0c68-4c40-44f4-818a-28a43b915bff
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 22b5e5d1-dc26-401b-8ea3-010c5925bdd5
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 5663d836-4ac1-46b1-bbe1-fb08abc404a4
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 942f5a7b-f627-4e99-bec0-e7295f386162
Worked on by: - @TheAngryPit - @vyctorbrzezowski Co-authored-by: TheAngryPit <7040636+TheAngryPit@users.noreply.github.com> Co-authored-by: vyctorbrzezowski <51521767+vyctorbrzezowski@users.noreply.github.com> OpenClaw-Publication: 2ddc1d8d-dbcc-4041-b571-cc80244b2352
|
@clawsweeper re-review |
|
🦞👀 Re-review progress:
|
PR cleanup reviewReviewed head: This older draft is explicitly carried forward by #2037 (fix: keep loaded conversations visible while disconnected). The fix is not on main, and #2037 remains an open draft with native/upgrade proof and current-main reconciliation outstanding. I am leaving this PR open in this cleanup pass rather than claiming main supersession. Implementation and proof should remain in the existing replacement lane; the duplicate can be retired explicitly when that handoff is settled. Action in this cleanup pass: leaving this PR open. No branch changes or runtime-proof waiver. The findings above come from source, discussion and recorded-CI review; Windows validation was not rerun in this pass. |
What Problem This Solves
Fixes: Disconnect replaces a loaded native conversation with connection guidance.
Related: #1795 (fix: retain the selected assistant and conversation after reconnect); Workspace selection only.
User Impact
Keeps the loaded conversation offline; verified authority gates recovery. Draft: native/UI proof, CI and fork-first workflow compliance remain unresolved.
Why This Change Was Made
Existing owners retain state and verify recovery. No new transcript cache, client or credential reads.
Evidence
Current draft candidate: f9dbbaa. Windows CI qualification pending.
This update preserves the retention/security implementation and applies the reader-anchor and reload correction. Native anchoring remains enabled: bottom while following, top for an established reader away from the tail. Reload reattaches observation and positions only for following or admitted initial history. Unload retains initial admission, while version invalidation, queue clearing and detachment retire old work. Explicit cancellation, replacement and successful initial-dispatch boundaries remain.
Fresh final-source focused evidence: 57 timeline policy/source-contract cases passed, 0 failures/skips. The new lifecycle characterization failed before removing the unload admission clear, then passed after the correction. This is not WinUI compilation or native runtime proof. The earlier 91-case broad selection predates the correction and is not additive.
Independent source review identified initial-admission loss across Request -> non-tail ViewChanged -> Unloaded -> Loaded. The correction retains admission without retaining queued work. Canonical helper attempts returned outer aborted without final reports; no helper clean verdict is claimed.
Historical evidence from earlier published candidates, not current-head qualification
Current diagnostic continuation: f8508b7
The audit repairs below remain the published 9da baseline. This candidate appends only bounded test-owned diagnostics in the existing native Disconnect case (one file, +94/-1). It is not a claimed repair of reader-position loss. The exact anchor locator, 4-pixel tolerance, positioning predicate, scroll-percentage bounds, draft/input identity, disabled-IO and ordinary-Send assertions are unchanged. No sleep, retry, skip, viewport manipulation or production export was added.
At before-disconnect, offline-mounted and offline-anchor-failure, the normal failed-test output now records explicitly SYNTHETIC message ordinal, original expected offsets, freshly queried anchor/viewport/intersection rectangles, relative offsets, offscreen/visibility flags, UIA RuntimeIds, native scroll percentage/view size, selected-fixture-reader flag and real render/history/positioning receipt fields. Raw request keys are fingerprinted. No arbitrary UI/chat text, tree dump or exception message is logged. The existing provider snapshot is reduced to availability/readiness/history booleans only after the assertion has already failed, so it cannot refresh history and rescue the tested boundary. There are no newly authored test cases in this diagnostic-only delta.
Source reconstruction: Settings suspends but does not dispose the mounted chat; returning Home restores the existing page, queues the retained session and restores focus. Offline composer status can change layout, and the positioner/ScrollView owns navigation/anchoring. These are candidate boundaries, not an established failure cause. Actual baseline/offline geometry is not yet observed for this candidate. The protected 9da diagnostics archive was not accessed through another identity or transport.
Qualification for this delta:
Published audit repair baseline
Audit repair baseline: 9da2645. Scoped test-audit repairs A5/A6/A7/A9, not a new transport design. Final source-bound local selections: 753 owning tests + 150 protocol tests passed, no failures/skips. Native A5 compiled and executed in Windows CI, but failed the offline visible-reader-anchor check before reconnect. Current-head Release compilation passed. The uploaded native diagnostics remain uninspected because artifact payload access is blocked. The old46-case aggregate does not qualify these changed tests.
Authored cases are not suite totals:20 authored unit/protocol cases (net19 additional executed cases), plus one strengthened existing native case. Existing lifecycle cases were also strengthened. No coverage deletion quota, skip, assertion relaxation, arbitrary settling sleep or test-only public API was introduced.
Negative controls failed at their intended assertions, not setup/compilation: row-count guard removed4/10 failures; duplicate guard removed1/10; the fail-closed lifetime control1/1; queued final token fence removed3/6; history revision made explicit navigation1/5; premature native receipt1/1. Missing render-revision receipt first failed2/5, then passed after extending the existing passive receipt. All temporary mutations were restored and the final assemblies recompiled. The original native tail-jump mutation still needs Windows execution.
An independent P2 review found input-idle alone insufficient. It was repaired using a passive fixture-only observer of the existing positioner's pending dispatch/layout work, real BringingIntoView/ScrollCompleted correlation IDs, native Idle and two actual composition frames. It cannot request navigation. Final independent P0-P3 source review: scoped-clean, not native proof or a Diamond rating.
Current-candidate stored-data interoperability
Recovered from the already-completed final owning TRX, not a rerun:
OpenClaw.Tray.Tests.ChatProviderConnectionSecurityTests.LatestStableStoredProfileAndSigningIdentitySurviveCurrentReconnectPassed on candidate9da264564ef72438d0b30cc2e0fdc1f03bc81880, executed2026-11-03T00:14:00.1170890+00:00(duration00:00:00.1344708). It is included in the753-test owning selection whose exact command is below.Actual test stdout:
The fixture was emitted by the released DeviceIdentity/GatewayRegistry writers from stable
v2026.9.8-1, source2ba89f377ce8ce3f5ddfc452e4d509329f109114, assetOpenClawTray-2026.9.8-1-win-x64.zipSHA-256c50955809afdd07c0d2c17f30bf7c45cf06bed09d751a915bd92945be27f2047. Fixture provenance and generated-file hashes are checked in alongside the exact producer. The current test verifies the stored public-key signature, device-token precedence without shared fallback, readable history/current send after reconnect and byte-identical stored files. The current test-owner source SHA-256 is6f6810ed7046e4e37003f2e5f87f2dda9f5cbf95b2b99f96721020b3e9506326. Only the in-memory route is redirected to that owned synthetic loopback server.This is current-reader/stored-format compatibility evidence, not actual installed-upgrade, native UI, real Gateway or provider proof. The installed-upgrade/current native behavior gates remain open. No protected artifact download, new test run or extra review request was used to recover this evidence.
Historical de5 production-client transport proof follows. It is not execution evidence for the new audit tests; its original source/assembly hashes and limits are preserved:
Inspectable transport request census and ordering
Historical evidence head: de5e667. Command run in this owned Linux x64 workspace with .NET SDK10.0.400:
Copied actual TRX Standard Output, not expected output. Request ordinals/census are recorded on the receiving server. The canceled task settles while the production send lock is held; an acknowledged health response follows release, then fresh profile/roster verification admits exactly one selected-session send and a final acknowledged health barrier. No random-delay absence window is used.
Profile reassignment is delivered over the real fixture socket and awaited through SelfProfileChanged. The auth branch is the existing production lifetime owner receiving a typed manager Auth observation while that socket survives. It is not server-side credential revocation, a real installed Gateway, native UI or upgrade proof.
SHA-256 of source read for the build/run:
{ "src/OpenClaw.Shared/OpenClawGatewayClient.RequestLifetime.cs": "11163ff9d6682e872ba0ba666cdc3d7664b9e044c224ec9250c86e6892dd4633", "src/OpenClaw.Shared/WebSocketClientBase.cs": "18b301fd4d57740ef7dac3a77d381be1daeae0ea20bda5c2f2f2a0176d295088", "src/OpenClaw.Tray.WinUI/Chat/ChatProviderConnection.cs": "74cd395e9d7117ce819ecbc6d822cd3ca0e675bd6136899bbc25d7a14c7dcb10", "src/OpenClaw.Tray.WinUI/Chat/RetainedChatGatewayBridge.cs": "d16e29947d6774e6af55165699461d31ec5fd3fc33dacf7341b60961153cedf7", "tests/OpenClaw.TestSupport/Gateway/FixtureGatewayServer.cs": "7bd7533dc385a65d529799e5b3d0cc1adbe089a921e4b2b602751e12c62a546c", "tests/OpenClaw.Tray.Tests/ChatProviderConnectionRecoveryTests.cs": "05851d89b1a530e3e2f67f6c7272fefabdb28051fec05e048f641f55e4385828", "tests/OpenClaw.Tray.Tests/ChatProviderConnectionSecurityTests.cs": "06d992bea0b03fc13c541c336f3cff37eefcd12cf8504233a9c7b8ac6ffb5de8", "tests/OpenClaw.Tray.UITests/GatewayFixtureUiTests.VerificationRecovery.cs": "028ae32d4e0320a66f34cb198d4340d35b0d47ea0bf01baa1f9d12b2968f3142" }Executed assembly SHA-256:
{ "src/OpenClaw.Shared/bin/Debug/net10.0/OpenClaw.Shared.dll": "d2c47f992392468fecae47243c1028aca52c6e4733408af82cc3839489a3153b", "src/OpenClaw.Connection/bin/Debug/net10.0/OpenClaw.Connection.dll": "1d87e7564285dd5a365e77b11ef6ad0e6ef2252e035df7b67e1e170c7b05337f", "tests/OpenClaw.TestSupport/bin/Debug/net10.0/OpenClaw.TestSupport.dll": "647fddff911e61f3563cde4a76158efc413adf3a680cb598ede22466b07c8003", "tests/OpenClaw.Tray.Tests/bin/Debug/net10.0/OpenClaw.Tray.Tests.dll": "4d93769b87fdd6e5fd576298bf0318288c1094e61dd97163641e27e28348e135", "tests/OpenClaw.Shared.Tests/bin/Debug/net10.0/OpenClaw.Shared.Tests.dll": "841bfe32a9a44b64c621f673815b1846db0ae5b04f42ed08bb17e137af9049ed" }Requested by Vitor Cepeda Lopes.
Work sessions
Change Type
Scope
winnodeRequired proof pools
windows-winui-interactive: transcript/draft continuity, viewport anchoring, page reload and reconnect UX. Not verified on the current head. Hosted synthetic fixture execution is separate from interactive/visible proof.windows-wsl-gateway-e2e: verified Gateway recovery and routing. Ordinary Windows CI is requested; results must bind to the exact new head. Synthetic fixtures alone are not live Gateway proof.windows-clean-installer-upgrade: installed-profile preservation and previous-version upgrade. Not verified; no new host lease, install or shared-runtime authority is implied.Validation
Current candidate f9dbbaa:
dotnet test tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore --filter FullyQualifiedName~ChatTimelinePresentationTests, with TRX output and task-owned isolated data/toolchain.git diff --checkpassed. The strict native fixture remains byte-identical to the preserved candidate: no 4px tolerance increase, fresh-history/draft/send relaxation or new skip.Real behavior proof
Current head f9dbbaa: not yet native-qualified. The unchanged strict Windows scenario must prove offline visible-reader offset within 4px, fresh verified reconnect-history consumption, mounted local draft, correct conversation and ordinary acknowledged Send. Initial/explicit positioning, streaming/tail, reflow, cancellation and lifecycle behavior also need current-head proof.
Historical native red on f8508b7, run41560429591/job125670946806: same visible fixture row189 and RuntimeIds/history/request, settled native receipt; viewport height646 ->628 and relative anchor Y294 ->276. The strict assertion failed by18px, and fresh reconnect-history consumption was not reached. This is a failure, not qualification of this update.
Not verified / blocked: current-head native and visible after-change proof, live Gateway recovery beyond synthetic fixtures, and installed upgrade/fresh-install compatibility. No private production credentials/configuration, global/shared runtime changes, direct host lease or protected artifact retry is authorized by this update.
Security Impact
NoNoYes: fresh existingusers.selfandsessions.listreads.NoNoYes, explain the risk and mitigation: identity/cancellation fences; no content logged.Compatibility and Migration
Bounded: fallback tested; native/installed compatibility unverified.Yes: optionalOPENCLAW_CHAT_RECOVERY_TIMEOUT_MS, default 12000.NoReview Conversations
Worked on by