Skip to content

fix: group agent session resume churns when messages toggle between @-mention and plain#99722

Merged
obviyus merged 1 commit into
mainfrom
fix/mention-state-binding-churn
Jul 4, 2026
Merged

fix: group agent session resume churns when messages toggle between @-mention and plain#99722
obviyus merged 1 commit into
mainfrom
fix/mention-state-binding-churn

Conversation

@obviyus

@obviyus obviyus commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Closes #99696
Related: #99640, #99595, #99372

What Problem This Solves

Fixes an issue where CLI-backend agents (e.g. Claude CLI) in group chats abandon their resumed session whenever consecutive messages toggle between explicitly @-mentioning the bot and not mentioning it — the most common message pattern in groups ("hi @bot" followed by a plain follow-up). Each toggle invalidated the stored session binding (reuse=invalidated:system-prompt) and spawned a fresh CLI session, dropping continuity and re-paying warm-up.

Also fixes a related guaranteed one-shot invalidation: the group behavioral intro was injected only on a session's first turn, so turn 2 of every fresh group session hashed differently from turn 1 and invalidated once more.

Fourth member of the per-turn-facts-in-session-stable-hash family (#99372, #99595, #99640).

Why This Change Was Made

buildGroupChatContext appended a "the incoming message explicitly mentions your channel identity" line when ExplicitlyMentionedBot was true — a per-message fact — and that context is part of extraSystemPromptStatic, which is hashed into the CLI session reuse fingerprint. The fix moves the mention notice to the per-turn inbound user context (Conversation info payload, explicit_bot_mention_note), which is already excluded from the static hash and stripped from replays/UI by existing metadata handling. The model still learns about the mention every time it happens; the system prompt no longer changes shape because of it.

The group intro is now included unconditionally for group sessions (Claude CLI fixes the system prompt at session creation, so session-stable content must not depend on turn ordinality). Activation-mode changes still invalidate — correctly — because the intro text itself changes.

Non-goal: the shouldInjectGroupIntro / groupActivationNeedsSystemIntro flag machinery now only maintains its own state and is a candidate for removal, but it touches command flows, session reset, and session-entry slot keys, so that cleanup is left as a follow-up rather than expanding this fix's surface.

User Impact

Group-chat agents on CLI backends keep one resumed session across natural conversations that mix @-mentions and plain messages, and no longer burn an extra fresh session on the second turn of every new session. No change to what the model is told about mentions — the information moved from the system prompt to per-turn context.

Evidence

  • Production attribution (2026-07-03, live Telegram group, per-hash diagnostic logging in resolveCliSessionReuse): extraSystemPromptHash flipped 2dba…5ac0… tracking exactly the mention state of each inbound message while promptToolNamesHash/messageToolPolicyHash stayed constant — full table in CLI session binding churns on mention-state toggles: ExplicitlyMentionedBot leaks into extraSystemPromptStatic #99696.
  • Fail-confirmed regression tests (prod edits reverted → red, re-applied → green): mention → no-mention → mention with identical hash; fresh-session turn 1 vs turn 2 with identical hash; mention notice present in per-turn context when ExplicitlyMentionedBot is true.
  • Local validation: pnpm tsgo 0, pnpm check:test-types 0, affected-test sweep (prompt-composition, groups, inbound-meta, strip-inbound-meta, get-reply-run.media-only, cli-runner/prepare, cli-session) all 0, prompt:snapshots:check 0, oxlint 0, git diff --check 0, autoreview clean.
  • Live canary on a production deployment planned before merge (same flow as fix: CLI agent session resume churns when owner and non-owner alternate in a group #99640); observations will be added below.

Draft until the live canary confirms stable reuse across mention toggles.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M maintainer Maintainer-authored PR labels Jul 4, 2026
@clawsweeper

clawsweeper Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 3, 2026, 8:43 PM ET / 00:43 UTC.

Summary
The PR moves explicit group-chat bot mention state out of the session-stable group prompt and into per-turn inbound context, and makes group intro stable across CLI session turns.

PR surface: Source -1, Tests +269. Total +268 across 10 files.

Reproducibility: yes. at source level: current main includes per-message mention state and conditional group intro in the static CLI prompt hash path. The PR comment also gives live Telegram claude-cli canary output for the after-fix mention/plain/mention sequence.

Review metrics: 1 noteworthy metric.

  • CLI reuse fingerprint inputs: 2 volatile prompt inputs stabilized. Explicit mention state and first-turn group intro both affect durable CLI prompt identity today, so maintainers should notice the session-state behavior change before merge.

Stored data model
Persistent data-model change detected: vector/embedding metadata: src/auto-reply/reply/inbound-meta.test.ts, vector/embedding metadata: src/auto-reply/reply/strip-inbound-meta.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #99696
Summary: This PR directly fixes the linked mention-state CLI session churn issue and partially overlaps the broader CLI false-invalidation cluster.

Members:

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

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

Mantis proof suggestion
A live Telegram group transcript plus redacted reuse diagnostics would materially help maintainer confidence for this session-continuity change. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis telegram live: verify a claude-cli Telegram group keeps the same session across mention, plain follow-up, mention, and third-party-bot turns.

Risk before merge

  • [P1] The patch intentionally changes CLI session prompt identity, so upgraded deployments may see one expected hash-convergence invalidation before reuse stabilizes.
  • [P1] The groupIntro portion overlaps the older open groupIntro PR and the broader false-invalidation tracker, so maintainers should decide sequencing before merge.

Maintainer options:

  1. Merge With Session-State Approval (recommended)
    Merge after maintainers accept the one-time hash convergence behavior and confirm this PR supersedes or cleanly sequences with the older groupIntro branch.
  2. Split The groupIntro Scope
    Remove the unconditional groupIntro part here if maintainers want this PR limited to mention-state churn and leave groupIntro to the existing tracker.
  3. Pause For Canonical Tracker
    Pause this PR if maintainers want mention-state and groupIntro false invalidations solved under one broader canonical plan.

Next step before merge

  • [P2] The protected maintainer-label PR has no narrow automated repair finding; maintainers need to decide session-state approval and groupIntro sequencing.

Security
Cleared: No concrete security or supply-chain regression was found; the diff changes prompt composition and tests without touching dependencies, workflows, secrets, package metadata, or permissions.

Review details

Best possible solution:

Land this PR after maintainer session-state approval, treating it as the candidate fix for #99696 while explicitly superseding or sequencing the older groupIntro work.

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

Yes at source level: current main includes per-message mention state and conditional group intro in the static CLI prompt hash path. The PR comment also gives live Telegram claude-cli canary output for the after-fix mention/plain/mention sequence.

Is this the best way to solve the issue?

Yes for the mention-state axis: per-message mention facts belong in per-turn inbound context instead of the session-stable CLI prompt identity. The groupIntro change is plausible and live-proven, but maintainers should reconcile it with #91157 before merge.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f59310a555d7.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. A PR comment provides live production Telegram claude-cli canary output showing the mention/plain/mention sequence reused one session after one expected convergence invalidation.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit. Replaced prior rating: 🧂 unranked krab.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P1: The PR targets active CLI-backed group chat session churn that can drop resumed-session continuity in common group reply flows.
  • merge-risk: 🚨 session-state: The diff changes the durable prompt identity used to decide CLI session reuse, so an incorrect merge could reset or wrongly preserve agent session state.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit. Replaced prior rating: 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Sufficient (live_output): A PR comment provides live production Telegram claude-cli canary output showing the mention/plain/mention sequence reused one session after one expected convergence invalidation.
  • proof: sufficient: Contributor real behavior proof is sufficient. A PR comment provides live production Telegram claude-cli canary output showing the mention/plain/mention sequence reused one session after one expected convergence invalidation.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. The PR affects Telegram group conversation continuity in a way a short Telegram proof with reuse diagnostics can demonstrate.
Evidence reviewed

PR surface:

Source -1, Tests +269. Total +268 across 10 files.

View PR surface stats
Area Files Added Removed Net
Source 3 7 8 -1
Tests 7 284 15 +269
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 10 291 23 +268

What I checked:

  • Repository policy applied: Root AGENTS.md and scoped src/agents plus test/helpers policies were read; the session-state, proof, protected-label, and deep-review rules affected this verdict. (AGENTS.md:25, f59310a555d7)
  • Current main mention-state leak: Current main appends explicit bot-mention guidance inside buildGroupChatContext when ExplicitlyMentionedBot is true, so stable group context changes with a per-message fact. (src/auto-reply/reply/groups.ts:250, f59310a555d7)
  • Current main static prompt hash input: Current main includes groupChatContext and conditional groupIntro in extraSystemPromptStatic, which is passed into CLI session binding facts. (src/auto-reply/reply/get-reply-run.ts:670, f59310a555d7)
  • CLI reuse hash path: prepareCliRunContext hashes cliSessionBindingFacts.extraSystemPromptStatic when present, making that prompt text part of the durable CLI session reuse fingerprint. (src/agents/cli-runner/prepare.ts:351, f59310a555d7)
  • CLI reuse invalidation path: resolveCliSessionReuse invalidates with system-prompt when the stored extraSystemPromptHash differs from the current hash, matching the reported reset mode. (src/agents/cli-session.ts:159, f59310a555d7)
  • PR patch removes mention from stable group context: The PR head removes the mention-specific line from buildGroupChatContext, leaving provider and delivery guidance stable across mention toggles. (src/auto-reply/reply/groups.ts:249, 9bb687dd33f3)

Likely related people:

  • obviyus: Authored the merged CLI binding-facts and prompt-tool-scope fixes that this PR follows up, touching the same session-stable prompt hash path. (role: recent area contributor; confidence: high; commits: 48e8965b1060, fe513ffe5e76; files: src/auto-reply/reply/get-reply-run.ts, src/agents/cli-runner/prepare.ts, src/agents/cli-session.ts)
  • joelnishanth: Current blame for the affected group context, static prompt assembly, hash preparation, and comparator lines routes through commit 97e582e. (role: current-line carrier; confidence: medium; commits: 97e582ec7400; files: src/auto-reply/reply/groups.ts, src/auto-reply/reply/get-reply-run.ts, src/agents/cli-runner/prepare.ts)
  • Peter Steinberger: Local history shows repeated adjacent work on auto-reply, CLI runner, session preservation, and prompt/runtime seams around the same surface. (role: adjacent session-runtime contributor; confidence: medium; commits: 12100719b8a9, 89d7a24a3523, 10dcd5784641; files: src/auto-reply/reply/get-reply-run.ts, src/agents/cli-runner/prepare.ts, src/agents/cli-session.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jul 4, 2026
@obviyus

obviyus commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Live canary results (validated)

Branch build (9bb687dd33f) deployed to a production Telegram group (claude-cli backend). Maintainer ran the exact repro pattern — mention → plain → mention → third-party-bot message:

UTC (2026-07-04) inbound mention? reuse
00:30:40 "Hi @HamVerBot" yes invalidated once (expected transition: stored binding predates this build's stable static prompt) → new session 64807bd29430
00:30:53 "You are a banger" no reusable, same session — pre-fix, this exact mention→plain toggle invalidated (#99696 production trace)
00:31:18 "Hi @HamVerBot" yes reusable, same session
00:31:30 third-party bot reply (non-owner sender) no reusable, same session — also re-confirms #99640's sender-independence on this build

One CLI session survived the full mention-toggle + sender-flip sequence with zero spurious invalidations. No turn failures.

Marking ready for review.

@obviyus
obviyus marked this pull request as ready for review July 4, 2026 00:32
@obviyus

obviyus commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Prompt-cost numbers from the production canaries

Measured from the same production group deployment's cli exec log lines across the canary windows (19 user turns total):

turn type n mean promptChars relative
resumed (reuse=reusable) 13 985 1x
invalidated → fresh session + history replay 4 9,900 10.1x
cascade (reuse=none, queued during a fresh spawn) 2 history replay lost entirely

Spurious invalidation rate on the same group, same traffic shape, across the fix series:

build spurious invalidations
pre-#99640 (#99633 trace) 1 per owner↔non-owner sender flip (1:1)
#99640 only (2026-07-03 20:15Z window) 3 of 11 user turns (mention-state axis, → #99696)
this PR (2026-07-04 00:30Z window) 0 of 4 (only the expected one-time deploy transition)

Net effect: the common conversational turn now sends ~10x fewer prompt characters than an invalidated one, keeps Claude CLI's warm session state (native compaction instead of history replay), and the cascade case — where queued turns lost history entirely — no longer occurs outside genuine session-level changes.

Small samples from a single deployment, but the per-turn costs are deterministic (bootstrap + replay vs delta) and the invalidation mechanism is covered by the fail-confirmed regression tests.

@obviyus

obviyus commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

The single red check ("Run agentic native Telegram proof") is a capture-environment limitation, not an observed regression: its mantis-evidence.json reports both baseline and candidate as skipped with no artifacts — the harness "could not capture Telegram Desktop proof because this PR needs a CLI-backed Telegram group continuity scenario that is not available in this capture environment", and it filled comparison.pass: false instead of the documented no-visible-delta skip path.

The Telegram-visible behavior in question (session continuity across mention toggles) is proven above on a real Telegram group deployment (#99722 (comment)). All 70 other checks pass. Landing on that evidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI session binding churns on mention-state toggles: ExplicitlyMentionedBot leaks into extraSystemPromptStatic

1 participant