Keep Claude CLI sessions warm#69679
Conversation
🔒 Aisle Security AnalysisWe found 3 potential security issue(s) in this PR:
1. 🟡 CLI session reuse ignores OpenClaw MCP loopback port, enabling session binding confusion
Description
This is a session-binding weakening/regression:
Impact:
Vulnerable code: /^(http:\/\/(?:127\.0\.0\.1|localhost|\[::1\])):\d+(\/mcp)$/.exec(value.trim())
...
return `${match[1]}:<openclaw-loopback>${match[2]}`;RecommendationDo not treat the MCP port as non-semantic for session reuse unless you can cryptographically bind the resumed Claude session to the same local MCP server instance. Safer options:
Example (simple mitigation: include port): function canonicalizeBundleMcpConfigForResume(config: BundleMcpConfig): BundleMcpConfig {
return { mcpServers: sortJsonValue(config.mcpServers) as BundleMcpConfig["mcpServers"] };
}If you must ignore ephemeral ports, add an explicit allowlist flag (e.g., 2. 🟡 Unbounded stdout/stderr buffering after Claude live session is marked closing (memory DoS)
DescriptionThe Claude CLI live session continues to append to
This allows a misbehaving/compromised RecommendationStop processing output once a session is closing, and/or hard-cap buffers even in the closing state. Suggested fix (minimal): function handleClaudeStdout(session: ClaudeLiveSession, chunk: string) {
if (session.closing) return;
...
}
// in onStderr
if (session.closing) return;Additionally, consider:
3. 🟡 Global Claude live-session cap allows cross-tenant denial of service
DescriptionThe Claude CLI live-session implementation enforces a single, process-wide cap (
In a multi-tenant deployment (e.g., a shared gateway/service process handling multiple users/accounts), a single tenant can create/hold 16 sessions (or keep 16 creates pending) and cause other tenants to receive a Vulnerable code: const CLAUDE_LIVE_MAX_SESSIONS = 16;
...
if (
liveSessions.has(key) ||
liveSessionCreates.has(key) ||
liveSessions.size + liveSessionCreates.size < CLAUDE_LIVE_MAX_SESSIONS
) {
return;
}
...
throw new FailoverError("Too many Claude CLI live sessions are active.", { reason: "rate_limit", ... });RecommendationScope capacity controls to the resource owner and add fair eviction:
Example approach (sketch): type TenantKey = string; // e.g. sha256(agentAccountId + authProfileId)
const tenantSessions = new Map<TenantKey, Set<string>>();
const MAX_SESSIONS_PER_TENANT = 4;
function ensureTenantCapacity(tenant: TenantKey) {
const set = tenantSessions.get(tenant) ?? new Set();
if (set.size >= MAX_SESSIONS_PER_TENANT) {
throw new FailoverError("Too many live sessions for this account.", { reason: "rate_limit", ... });
}
}This prevents one tenant from exhausting shared process resources and causing cross-tenant service degradation. Analyzed PR: #69679 at commit Last updated on: 2026-04-22T08:13:12Z |
Greptile SummaryThis PR introduces a warm-process optimization for the Confidence Score: 5/5Safe to merge; all remaining findings are P2 style/minor correctness notes that don't block the primary user path. No P0 or P1 issues. The two logic comments (stale noOutputTimeoutMs and accumulated stderr) are P2 because noOutputTimeoutMs stays constant within a session in practice (same backend fingerprint), and the stderr mixing only matters on unexpected process exit after multiple turns. The unused streamingParser allocation is a style issue only. src/agents/cli-runner/claude-live-session.ts — see noOutputTimeoutMs and stderr comments.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff45a2a337
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ea62254fb4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b0546dbab
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6dbc6bf198
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 808675ec1a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 012f390901
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5b1959511
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 40f769dfeb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e6b40b2a7f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 704828f469
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| cleanup: () => Promise<void>; | ||
| }): Promise<ClaudeLiveRunResult> { | ||
| const key = buildClaudeLiveKey(params.context); | ||
| const useResume = params.args.includes("--resume") || params.args.includes("-r"); |
There was a problem hiding this comment.
Detect inline --resume values before deciding live reuse
runClaudeLiveSessionTurn only treats resume mode as active when args contains a standalone --resume/-r token. If a backend uses resumeArgs like "--resume={sessionId}" (single argv item, which is allowed by the {sessionId} placeholder contract), useResume is false here, so the turn is treated as a fresh run: buildClaudeLiveArgs re-adds first-turn system prompt behavior and the resumeCapable && !useResume restart path tears down warm sessions unnecessarily. That breaks resumed-session continuity for valid inline resume flag configurations.
Useful? React with 👍 / 👎.
490041f to
e23d9d2
Compare
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
…resume OpenClaw v2026.4.22 (released 2026-04-23) introduced native warm claude-cli stdio sessions and automatic resume from the stored Claude session id after Gateway restarts or idle exits, via openclaw/openclaw#69679 "Keep Claude CLI sessions warm". This covers the primary use case of boot-resume, so the standalone skill is no longer needed. This commit adds prominent deprecation banners to README.md (English and Chinese sections) and SKILL.md, pointing readers to the upstream PR. The repository will be archived after this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
* feat(cli): keep claude cli sessions warm * test(cli): cover claude live session reuse * fix(cli): harden claude live session reuse * fix(cli): redact mcp session key logs * fix(cli): bound claude live session turns * fix(cli): reuse claude live sessions on resume * refactor(cli): canonicalize claude live argv * fix(cli): preserve claude live resume state * fix(cli): close dead claude live sessions * fix(cli): serialize claude live session creates * fix(cli): count pending claude live sessions * fix(cli): tighten claude live resume abort * fix(cli): reject closed claude live sessions * fix(cli): refresh claude live fingerprints * fix(cli): stabilize MCP resume hash * fix: preserve claude live inline resume (openclaw#69679) --------- Co-authored-by: Frank Yang <[email protected]>
Summary
Tests