fix(anthropic): enable Claude CLI session-expired history reseed#80934
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. from source: current main's Anthropic backend lacks the opt-in while Real behavior proof Next step before merge Security Review detailsBest possible solution: Land the narrow Anthropic backend opt-in after redacted live Claude CLI session-expired proof or maintainer proof override, while keeping the shared reseed safety boundaries unchanged. Do we have a high-confidence way to reproduce the issue? Yes, from source: current main's Anthropic backend lacks the opt-in while Is this the best way to solve the issue? Yes, the proposed path is the narrow maintainable fix: the owner plugin opts into an existing generic contract and adds a regression for that backend. A broader core default change would weaken the explicit opt-in boundary added by the earlier reseed work. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 7121791735fa. Re-review progress:
|
|
@clawsweeper re-test |
|
hi. @clawsweeper bitloi sometimes forked other's pr. |
|
@clawsweeper i think it would be better to close this PR as soon as quickly. @bitloi has bad habit. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
bd464dc to
86e729b
Compare
|
Maintainer proof before landing:
GitHub CI note: pushed head Thanks @bitloi. |
|
Landed via rebase onto
Thanks @bitloi. |
…oryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped - Guard against slice(-0) returning the entire string when an oversize summary consumes the budget Tests added: - "keeps the most recent turns when rendered history exceeds the cap" - "preserves the compaction summary when the post-summary transcript exceeds the cap" - "caps oversize compaction summary; drops post-summary tail when summary alone exceeds the budget" Closes openclaw#83157
…oryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157
…oryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157
…oryChars (#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After #80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes #83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on #83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
…oryChars (openclaw#83117) * fix(cli-runner): keep recent tail when reseed history exceeds maxHistoryChars `buildCliSessionHistoryPrompt` was prefix-slicing the rendered history, dropping the most recent assistant turns from the reseed prompt. After openclaw#80934 made the Claude-CLI reseed default-on, every Claude-CLI user is exposed to this on session_expired when the rendered transcript exceeds 12288 chars. The truncation marker landed mid-word in real reproductions. Fix: - Tail-slice (keep the recent suffix, drop the older prefix) - Pin the compaction summary as a prefix when present, only cap the post-summary transcript (loadCliSessionReseedMessages deliberately places the summary first) - When the summary alone exceeds maxHistoryChars, head-slice the summary itself to honor the cap; drop the post-summary tail in that case - Move the truncation marker to the lead since what follows is the recent tail, not what was dropped Closes openclaw#83157 * fix(cli-runner): retain recent tail with oversize summaries * fix(cli-runner): cap summary block plus marker against maxHistoryChars ClawSweeper P2 on openclaw#83117 flagged that when `summaryRendered.length` is less than `maxHistoryChars` but `summaryBlock.length` (summary + `\n\n` separator) meets or exceeds it, the `remainingBudget <= 0` arm of `buildCliSessionHistoryPrompt` appends the truncation marker after the already-full summary block. A 199-char rendered summary under a 200-char cap produced a 257-char history block — defeating the cap that prevents reseeding fresh CLI sessions with unexpectedly huge prompts. Fix the budget edge by truncating the summary in this branch as well so `summary + separator + marker` stays within `maxHistoryChars`. The tail still drops (the summary alone consumes the budget) and the marker still leads its own line so the prompt announces what was discarded. Mirrors the existing oversize-summary branch's pattern of head-slicing the summary against an explicit budget that reserves marker + separator. Add a focused regression in `session-history.test.ts` covering exactly the gap the finding called out: `summaryRendered.length < maxHistoryChars` with a non-empty post-summary tail. Asserts the rendered history block stays within `maxHistoryChars` and the truncation marker is present. * fix(cli-runner): keep tail for near-cap summaries --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary
session_expiredrecovery could retry fresh without OpenClaw transcript history.Change Type
Scope
Linked Issue/PR
Real behavior proof
session_expiredfresh-session recovery can now use bounded OpenClaw transcript reseed because the bundled Claude backend opts into the existing reseed contract.fix/issue-80905-claude-cli-reseed, built fromupstream/mainabb4f96b81df4f91ab2b593d0aea2ebc9698e445.node scripts/run-node.mjs --helpCI=true corepack pnpm test:extension anthropicCI=true corepack pnpm test extensions/anthropic/cli-shared.test.tsCI=true corepack pnpm test src/agents/cli-runner/session-history.test.ts src/agents/cli-runner/prepare.test.ts src/agents/cli-runner.reliability.test.ts extensions/anthropic/cli-shared.test.tsCI=true corepack pnpm test extensions/anthropicCI=true corepack pnpm check:changedreseedFromRawTranscriptWhenUncompacted: truewhile preserving native resume args. The regression test failed before the fix withexpected undefined to be true, then passed after the backend opt-in was added.claudebinary installed (command -v claudereturned exit code 1), so live provider rotation proof needs a Claude-authenticated environment or maintainerproof: override.Root Cause
session_expiredfresh retries could be prepared without OpenClaw history.Regression Test Plan
extensions/anthropic/cli-shared.test.tssrc/agents/cli-runner/session-history.test.ts,src/agents/cli-runner/prepare.test.ts, andsrc/agents/cli-runner.reliability.test.tscover the safe reseed,session_expired, and preserved auth-boundary behavior.User-visible / Behavior Changes
Claude CLI fresh-session recovery after safe invalidations can include bounded OpenClaw transcript history instead of retrying with only the current prompt.
Diagram
Security Impact
No)No)No)No)No)Yes, explain risk + mitigation: N/A.Repro + Verification
Environment
claude-clibackend config; no live Claude binary available in this environmentSteps
buildAnthropicCliBackend().config.reseedFromRawTranscriptWhenUncompactedis true and native resume args remain present.expected undefined to be true.reseedFromRawTranscriptWhenUncompacted: truein the bundled Claude backend config.Expected
sessionMode: "always"and--resume {sessionId}.Actual
Evidence
Human Verification
What you personally verified (not just CI), and how:
session_expiredevent in a Claude-authenticated runtime.Review Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
Yes)No)No)Risks and Mitigations
claudebinary.proof: overrideor rerun the same branch in a Claude-authenticated environment for live proof.