Skip to content

fix: clear Side chat when its parent conversation is deleted - #139974

Merged
steipete merged 2 commits into
mainfrom
codex/qa-companion-delete-20260906
Sep 6, 2026
Merged

steipete merged 2 commits into
mainfrom
codex/qa-companion-delete-20260906

Conversation

@steipete

@steipete steipete commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Closes #139971.

What Problem This Solves

Fixes an issue where users deleting and recreating a conversation would see Side chat exchanges from the deleted conversation. The Gateway retained the old in-memory Side chat under the reused key.

Why This Change Was Made

Side chat now consumes the existing committed identity-deletion event and clears only a thread whose scoped key and previous backing session ID match. Cleanup reuses the existing reset/cancellation owner and unsubscribes when the service is disposed.

The internal identity event now carries the already-resolved operation agent from its canonical producers. Bare keys need that scope, while qualified keys retain their own embedded agent. Inferring the agent from a database owner or matching session ID alone would clear the wrong thread when agents share a bare key or ID.

Production is net +46 lines, tests net +228, and docs net 0 across 25 files. The production growth carries the missing operation scope through existing event producers and adds one scoped deletion listener; it adds no parallel store, fallback, schema, migration, public protocol, SDK surface, or configuration option. Database transactions, stored representations, event grouping and publication timing stay with their existing owners.

User Impact

Recreated conversations begin with empty Side chat. Deletion cancels an active Side chat ask for the removed generation and preserves other agents and newer backing generations. The Control UI reference now includes session deletion in the Side chat cleanup lifecycle.

Evidence

Exact candidate be0a581878ddfe51b1d63c9bbbc3c1b85bc01af1, based on 9c0cf2b6a56f0da6c5c23928eb63f8223f980449.

  • Before: a real isolated Gateway/browser run on 95f963e342ab476912c23c0e7fb9660c69bb9980 retained the old Side chat after committed parent deletion and recreation of the same key with a new backing ID. The public state response and visible UI both showed the old exchange before any new question. Its affected owner bodies were matched to the unpatched candidate lineage.
  • After: one fresh run on exact be0a5818 with current locked dependencies passed with zero failed attempts. Reopened Side chat was empty before a fresh ask; the second agent retained its original exchange; the recreated first conversation received one new exchange without old dialogue. There were three synthetic model requests, nine successful tracked browser responses, six successful public admin RPCs, and no main chat.send. All owned processes, ports and temporary runtime state were cleaned up.
  • The earlier bd94ee5 candidate passed 261 focused tests with current locked dependencies, covering committed deletion, stale expected-ID preservation, reset/unrelated-state behavior, same-ID cross-agent bare-global isolation, old-event/new-generation safety, and active-ask cancellation. After current-main integration, 90 cases across four complete observer/companion/lifecycle/event suites, owning gateway test types, targeted lint and format passed on the final candidate. Its uncached ciArtifacts runtime/UI build passed in 124.76 seconds, with exact source, lock, build stamps and full artifact inventories verified.
  • A fresh complete-candidate managed Codex review at P0–P2 found no actionable findings across six passes after the integration correction. The integration audit preserves the existing producer, scoped-key and lifecycle contracts; the additional upstream observer fixture was aligned with the required event scope as described below.
  • Earlier candidate live proof used old installed packages and remains recorded as such. A normal frozen install corrected that graph; the new tests, uncached builds and live run above use the committed dependency graph. Source/build/lock hashes were rechecked after the live flow.

The live proof uses qualified agent/session keys and a synthetic loopback Responses provider, not a hosted model. Same-ID collisions are regression-test evidence because public session creation cannot choose backing IDs.

A separate existing limitation remains: Side chat asks against a bare global policy key lose their independent policy owner before provider dispatch, raising AGENT_SELECTION_REQUIRED. That failed attempt performed no deletion and predates this repair. This PR does not repair or bypass that policy boundary, claim successful global end-to-end proof, or change security/persistence contracts to hide it. The global owner-propagation follow-up requires the relevant security owner.

Before: recreated conversation still shows its deleted Side chat

Initial CI 34023960500 caught a new upstream observer reset fixture that omitted the event’s required agent scope. The repair patch rebased identically, and one fixture line now supplies its existing main agent. Production behavior was not changed to accommodate the test. The focused checks, full-candidate review, uncached build and qualified live flow above were refreshed before this push; earlier proof remains separately identified.

Current candidate: recreated Side chat is empty before a new question

Current candidate: the other agent keeps its Side chat

attachment-2004965384.webm

Final CI 34027358506 passed on the exact published candidate. Current-main composition was checked at b72a36a77d1b9fe5b7acb4e94042fddf827d7e40: the core cleanup and event producers are unchanged; disjoint documentation, repository-fork metadata, and added lifecycle-test changes combine cleanly. The recent ClawSweeper review has no actionable findings or before-merge items.

@steipete steipete self-assigned this Sep 6, 2026
@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime size: M maintainer Maintainer-authored PR labels Sep 6, 2026
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Sep 6, 2026
@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed September 6, 2026, 6:32 AM ET / 10:32 UTC.

ClawSweeper review

What this changes

Clear a conversation’s in-memory Side chat after committed deletion, cancel its active question, and preserve other agents’ threads and newer conversation generations.

Merge readiness

✅ Ready for maintainer review

This remains a useful, focused fix absent from current main and v2026.9.2. No actionable introduced defects were found.

Priority: P2
Reviewed head: be0a581878ddfe51b1d63c9bbbc3c1b85bc01af1

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused owner-level repair with meaningful regression coverage and no blocking findings; the recorded runtime evidence is supplemental under the maintainer exemption.
Proof confidence 🌊 off-meta tidepool Not applicable: The supplied MEMBER association exempts this PR from the external-contributor proof gate, and no material authority change triggers an exception. The captured body reports the changed cleanup through an exact-head Gateway/browser delete/recreate flow with preserved sibling state; linked media could not be independently retrieved.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The supplied MEMBER association exempts this PR from the external-contributor proof gate, and no material authority change triggers an exception. The captured body reports the changed cleanup through an exact-head Gateway/browser delete/recreate flow with preserved sibling state; linked media could not be independently retrieved.
Evidence reviewed 10 items Introduced change identity: The checkout matches the pinned original head. Review used the merge-base-to-head delta; the supplied verified test merge preserves the same introduced file set.
Scoped generation cleanup: The deletion listener matches the existing scoped thread key and previous backing session ID, then reuses reset/cancellation. Disposal unregisters the listener.
Committed producer boundary: Deletion events remain after successful reclamation and retain the existing commit guards and publication timing. The patch supplies the already-resolved operation agent without changing stored representations.
Findings None None.
Security None None.

How this fits together

The Gateway holds Side chat separately from the main conversation history. Committed session lifecycle events identify deleted conversations so the Side chat service can discard matching dialogue and cancel pending answers.

flowchart TD
  A[Conversation deletion] --> B[Session store commits deletion]
  B --> C[Event with agent and previous session identity]
  C --> D{Matching Side chat generation?}
  D -->|Yes| E[Clear thread and cancel question]
  D -->|No| F[Preserve existing thread]
  E --> G[Recreated conversation opens empty]
Loading

Before merge

None.

Agent review details

Security

None.

PR surface

Source +46, Tests +228, Docs 0. Total +274 across 25 files.

View PR surface stats
Area Files Added Removed Net
Source 16 70 24 +46
Tests 8 230 2 +228
Docs 1 1 1 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 25 301 27 +274

Review metrics

Metric Value Why it matters
Production versus regression coverage production net +46 lines; tests net +228 lines Production growth carries missing agent scope through existing event producers and adds one lifecycle listener; tests cover deletion and preservation boundaries.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #139971
Summary: This PR is the explicit implementation candidate for the paired delete/recreate report; the issue should remain open until resolution.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Technical review

Best possible solution:

Keep Side chat cleanup attached to committed lifecycle events, with agent and generation matching and the existing cancellation owner.

Do we have a high-confidence way to reproduce the issue?

Yes: populate Side chat, delete its parent, recreate the same key, and read Side chat before another question. Current-main source establishes the stale-cache path, and the paired report records that flow; this review did not execute it.

Is this the best way to solve the issue?

Yes: consuming the existing committed deletion event repairs the lifecycle owner without adding another store, configuration option, or public API.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against e74543854408.

Labels

Label justifications:

  • P2: Stale Side chat after conversation recreation is a bounded session-lifecycle defect with a focused repair.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The supplied MEMBER association exempts this PR from the external-contributor proof gate, and no material authority change triggers an exception. The captured body reports the changed cleanup through an exact-head Gateway/browser delete/recreate flow with preserved sibling state; linked media could not be independently retrieved.

Evidence

What I checked:

  • Introduced change identity: The checkout matches the pinned original head. Review used the merge-base-to-head delta; the supplied verified test merge preserves the same introduced file set. (be0a581878dd)
  • Scoped generation cleanup: The deletion listener matches the existing scoped thread key and previous backing session ID, then reuses reset/cancellation. Disposal unregisters the listener. (src/gateway/session-companion.ts:84, be0a581878dd)
  • Committed producer boundary: Deletion events remain after successful reclamation and retain the existing commit guards and publication timing. The patch supplies the already-resolved operation agent without changing stored representations. (src/config/sessions/session-accessor.sqlite-lifecycle.ts:561, be0a581878dd)
  • Late-answer protection: The existing ask runtime rejects cancellation, changed thread ownership, and changed backing identity before appending an answer. Its production runner explicitly selects the OpenClaw harness; this repair does not depend on a Codex harness contract. (src/gateway/session-companion-ask.ts:558, be0a581878dd)
  • Meaningful regression coverage: Added cases exercise real session handlers and the context reader for delete/recreate, stale deletion expectations, reset isolation, cross-agent identical IDs, delayed deletion events, and active-ask cancellation. Model execution is mocked in these supplemental tests; tests were inspected, not executed during this review. (src/gateway/server.sessions.delete-state-lifecycle.test.ts:323, be0a581878dd)
  • Still necessary on current main: Current main subscribes to Gateway resets but has no committed deletion listener; state reads return cached exchanges without checking the backing session generation. (src/gateway/session-companion.ts:74, e74543854408)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Shakker: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-09-06T09:16:19.073Z sha bd94ee5 :: needs maintainer review before merge. :: none

Carry the resolved operation agent through internal session-identity events
so bare keys retain their owner. Match companion cleanup to that scoped
identity and the cached previous generation when deletion commits.

Preserve reset timing, stored representations, schema, and public protocol.
Keep the newly integrated observer fixture aligned with the required
operation scope on committed session identity events.
@steipete
steipete force-pushed the codex/qa-companion-delete-20260906 branch from bd94ee5 to be0a581 Compare September 6, 2026 10:24
@steipete
steipete merged commit dc0578a into main Sep 6, 2026
186 of 187 checks passed
@steipete
steipete deleted the codex/qa-companion-delete-20260906 branch September 6, 2026 10:44
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

vincentkoc added a commit to ylcn91/openclaw that referenced this pull request Sep 6, 2026
* origin/main: (47 commits)
  ci: record CPU time for Node test jobs (openclaw#140054)
  test(crabbox): consolidate wrapper boundary coverage (openclaw#140058)
  fix(test): keep native filesystem access checks portable (openclaw#140047)
  fix: preserve models when OAuth preparation fails (openclaw#139951)
  feat(update): recover failed updates with bounded repair (openclaw#139495)
  refactor(plugins): share managed npm package traversal (openclaw#140040)
  chore(ui): refresh control ui locales (openclaw#140059)
  refactor(auth): share profile failure state reset (openclaw#140049)
  fix(cron): surface skipped on-exit payloads when jobs are busy (openclaw#139987)
  fix(codex): preserve exec-server WebSocket backpressure under Bun (openclaw#140048)
  fix(agents): ground exec approvals in tool results (openclaw#140043)
  refactor(policy): reuse authored policy value helpers (openclaw#140019)
  docs: keep ClawSweeper status inspection read-only (openclaw#139958)
  fix: reduce task maintenance stalls with large histories (openclaw#140038)
  fix(code-mode): identify unawaited promise output (openclaw#140028)
  fix(test): release memory search fixtures after failed phases (openclaw#140013)
  test(gateway): isolate Serve hello lifecycle fixtures (openclaw#140044)
  fix(microsoft-foundry): bound Entra token retention across accounts (openclaw#127216)
  fix(process): preserve the cause of cleanup observation failures (openclaw#140015)
  fix: clear Side chat when its parent conversation is deleted (openclaw#139974)
  ...
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 7, 2026
…w#139974)

* fix(gateway): clear side chat after its parent session is deleted

Carry the resolved operation agent through internal session-identity events
so bare keys retain their owner. Match companion cleanup to that scoped
identity and the cached previous generation when deletion commits.

Preserve reset timing, stored representations, schema, and public protocol.

* test(gateway): scope observer reset fixture to its agent

Keep the newly integrated observer fixture aligned with the required
operation scope on committed session identity events.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Side chat survives deletion and reappears in a recreated conversation

1 participant