Follow-up to the "streaming preview deleted without persistent replacement" issue. Concrete fix proposal for `extensions/telegram/src/draft-stream.ts`:
Problem: `scheduleDetachedDelete` deletes a superseded preview detached (fire-and-forget `void runDelete()`, scheduled after dwell) whenever the final lands as a *new* message instead of an edit-in-place. If the replacement fails or never becomes visible, the chat is left with nothing.
Proposed fix (Telegram plugin only, no harness/turn-pipeline changes):
1. In `draft-stream.ts`, make `scheduleDetachedDelete` conditional on confirmed delivery of the superseding message (gate on `deliveryState` / the replacement send-edit result). Otherwise retain the preview as the visible fallback.
2. Prefer edit-in-place of the live preview when still editable, instead of send-new + delete.
Verification: new tests "replacement failed → preview retained" and "replacement delivered → preview deleted", plus `pnpm build` (hot plugin entrypoint). Manual repro: codex-bound Telegram DM, `streaming.mode: partial`, model-identity question.
Note on versions: traced statically against 2026.9.8 sources while the reporting gateway ran 2026.9.7 — confirm exact line numbers against the `2026.9.7` tag before implementing.
Codex review: this still needs some work. _Reviewed October 3, 2026, 7:25 PM ET / 23:25 UTC._
**Summary**
Current main still deletes rotated previews without confirming replacement delivery. Keep this concrete repair proposal paired with the same author’s symptom report and handle both through one focused fix.
Reproducibility: yes. for the source-level race: create a visible preview, rotate it, reject or withhold the replacement, and advance the deletion timer. This review did not execute that regression or reproduce the broader harness symptom.
**Root-cause cluster**
Relationship: `same_root_cause`
Canonical: https://github.com/openclaw/openclaw/issues/164610
Summary: The paired report describes the symptom and this issue supplies a focused repair sketch for the same timer-based preview deletion.
Members:
- `canonical`: https://github.com/openclaw/openclaw/issues/164610 - Contains the original environment, observed disappearance, and streaming-off workaround.
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.
**Next step**
One clustered repair can address the source-proven rotation race and preserve the paired report’s runtime evidence without adding configuration or changing harness behavior.
<details>
<summary>Review details</summary>
Best possible solution:
Let the Telegram stream retain rotated message custody until the matching replacement is accepted, while preserving existing in-place finalization and explicit cancellation cleanup.
Do we have a high-confidence way to reproduce the issue?
Yes, for the source-level race: create a visible preview, rotate it, reject or withhold the replacement, and advance the deletion timer. This review did not execute that regression or reproduce the broader harness symptom.
Is this the best way to solve the issue?
Yes, gating rotation cleanup on the matching replacement result is a focused repair; a turn-wide delivery flag alone could authorize deletion based on an unrelated message. Edit-in-place finalization already exists.
AGENTS.md: found and applied where relevant.
Remaining risk / open question:
- The source establishes premature rotation cleanup, but its causal connection to the reported harness model-identity disappearance has not been verified through a live turn.
Codex review notes: model internal, reasoning medium; reviewed against [f42f774c8309](https://github.com/openclaw/openclaw/commit/f42f774c83090d86b202d9e8588ee3a414003c99).
</details>
<details>
<summary>Label changes</summary>
Label changes:
- add `P1`: A reported active Telegram workflow loses its visible reply, and current source independently establishes deletion before replacement confirmation.
- add `impact:message-loss`: Deleting the only visible preview after a failed replacement can leave the conversation without a response.
- add `issue-rating: 🦞 diamond lobster`: Current issue advisory state selects this label.
- add `clawsweeper:source-repro`: Current issue advisory state selects this label.
- add `clawsweeper:queueable-fix`: Current issue advisory state selects this label.
- add `clawsweeper:fix-shape-clear`: Current issue advisory state selects this label.
Label justifications:
- `P1`: A reported active Telegram workflow loses its visible reply, and current source independently establishes deletion before replacement confirmation.
- `impact:message-loss`: Deleting the only visible preview after a failed replacement can leave the conversation without a response.
</details>
<details>
<summary>Evidence reviewed</summary>
Acceptance criteria:
- pnpm test extensions/telegram/src/draft-stream.test.ts --maxWorkers=1
- pnpm build
- git diff --check
- Use the telegram-e2e-userbot skill for redacted Test Server proof of the affected streaming replacement flow.
What I checked:
- **Current source proves the deletion race:** Rotation resets the stream and immediately schedules deletion of the old message. The deletion callback checks neither replacement acceptance nor delivery state; elapsed dwell and a 1.5-second floor are its only gates. ([`extensions/telegram/src/draft-stream.ts:818`](https://github.com/openclaw/openclaw/blob/f42f774c83090d86b202d9e8588ee3a414003c99/extensions/telegram/src/draft-stream.ts#L818), [f42f774c8309](https://github.com/openclaw/openclaw/commit/f42f774c83090d86b202d9e8588ee3a414003c99))
- **Production caller establishes the intended ordering:** repositionLaneForNewMessage calls this rotation operation and explicitly requires the replacement to land before deferred cleanup. Tool-progress transitions can reach this operation before the next preview is sent. ([`extensions/telegram/src/bot-message-dispatch-draft.ts:236`](https://github.com/openclaw/openclaw/blob/f42f774c83090d86b202d9e8588ee3a414003c99/extensions/telegram/src/bot-message-dispatch-draft.ts#L236), [f42f774c8309](https://github.com/openclaw/openclaw/commit/f42f774c83090d86b202d9e8588ee3a414003c99))
- **Existing coverage misses failed replacement:** The inspected reposition tests successfully send the replacement before advancing deletion timers, including late first-send and failed-delete scenarios. They do not establish retention when the replacement fails. ([`extensions/telegram/src/draft-stream.test.ts:332`](https://github.com/openclaw/openclaw/blob/f42f774c83090d86b202d9e8588ee3a414003c99/extensions/telegram/src/draft-stream.test.ts#L332), [f42f774c8309](https://github.com/openclaw/openclaw/commit/f42f774c83090d86b202d9e8588ee3a414003c99))
- **Existing finalization capability:** The documented partial-streaming path already finalizes short answers in place and reuses the preview for the first long-answer chunk. The narrow missing behavior is replacement-confirmed rotation cleanup, rather than a new finalization mode. Public docs: [`docs/channels/telegram/messaging.md`](https://docs.openclaw.ai/channels/telegram/messaging). ([`docs/channels/telegram/messaging.md:73`](https://docs.openclaw.ai/channels/telegram/messaging), [f42f774c8309](https://github.com/openclaw/openclaw/commit/f42f774c83090d86b202d9e8588ee3a414003c99))
- **Reported releases retain the same mechanism:** GitHub contents reads for v2026.9.7 and v2026.9.8 both show immediate scheduling during rotation at lines 834–852. GitHub tag records resolve these releases to c074824a27c96d3983043f9eeb33823cd1772d8c and fc23bc864e4553c2d215e479eeec47b67a0bf943 respectively; the latest release does not repair this mechanism. ([`extensions/telegram/src/draft-stream.ts:834`](https://github.com/openclaw/openclaw/blob/fc23bc864e4553c2d215e479eeec47b67a0bf943/extensions/telegram/src/draft-stream.ts#L834), [fc23bc864e45](https://github.com/openclaw/openclaw/commit/fc23bc864e4553c2d215e479eeec47b67a0bf943))
- **Paired symptom report and workaround:** https://github.com/openclaw/openclaw/issues/164610 is open, by the same author, and describes the same deletion mechanism. Its partial-versus-off observation and workaround are useful evidence to preserve in one shared repair. Bounded GitHub searches found no open PR specifically owning replacement-confirmed Telegram deletion.
Likely related people:
- **obviyus:** Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
- **vincentkoc:** Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
- **Peter Steinberger:** Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
</details>
<details>
<summary>How this review workflow works</summary>
- 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.
</details>
<!-- clawsweeper-review-version item=164611 reviewed_at=2026-10-03T23:25:28.300Z sha=na source_revision=de50fc7984a33b11a77270ab392219e63fbef918da88e0c32e951ea434e5df93 lease_owner=github-run-37161506297-1 lease_comment_id=5974556398 v=1 -->
<!-- clawsweeper-review item=164611 -->
<!-- clawsweeper-command-status:164611:implement_issue:auto -->
🦞⚠️
Automatic implementation stopped before completion.
Reason: The automatic implementation worker stopped before all deterministic gates completed. Open the workflow run for the exact blocker.
Worker: https://github.com/openclaw/clawsweeper/actions/runs/37161812378
<!-- clawsweeper-issue-implementation-progress:start -->
Automatic implementation progress:
- State: Planning
- Detail: Codex is reading the issue and repository, choosing an implementation, and planning validation.
- Run: https://github.com/openclaw/clawsweeper/actions/runs/37164133328
- Updated: 2026-10-04T00:11:37.530Z
- Opt out: add `clawsweeper:manual-only` or `clawsweeper:human-review`.
<!-- clawsweeper-issue-implementation-progress:end -->