fix(compaction): restore session invariants across compaction and reset#69270
fix(compaction): restore session invariants across compaction and reset#69270de1tydev wants to merge 21 commits into
Conversation
Greptile SummaryThis PR propagates The fix is correct for the targeted channel-scoped session keys ( Confidence Score: 5/5Safe to merge; the edge case with All findings are P2. The core fix is correct and well-tested. The src/gateway/session-reset-service.ts — the Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/gateway/session-reset-service.ts
Line: 53-63
Comment:
**`inferMessageProviderFromSessionKey` misses non-channel `rest` prefixes**
Session keys built with `dmScope === "per-peer"` use the format `agent:{agentId}:direct:{peerId}`, so `rest.split(":")[0]` yields `"direct"` — a chat-type segment, not a channel name. Since `"direct"` is not in the sentinel list, `normalizeMessageChannel("direct")` is returned as `messageProvider`, giving downstream plugins an incorrect, non-channel value. Similarly, dashboard-scoped keys (`agent:ops:dashboard:…`) would surface `"dashboard"`. For those key shapes the function should return `undefined` to stay consistent with the "unknown provider" fallback the PR is trying to eliminate.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(hooks): preserve messageProvider in ..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f5b0e0e52
ℹ️ 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".
|
Addressed the follow-up issues in a6e53df.
Local verification:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6e53dfd81
ℹ️ 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".
|
Expanded this into a coordinated compaction/reset invariant fix, per the review suggestion. Included in this update:
I also updated the issue/PR title and description to reflect the broader scope. Local verification:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2171c3b21f
ℹ️ 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: ce4db4ebec
ℹ️ 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: 046100e827
ℹ️ 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: 53dd9aec43
ℹ️ 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".
|
Codex review: needs real behavior proof before merge. Reviewed June 14, 2026, 10:04 AM ET / 14:04 UTC. Summary PR surface: Source +144, Tests +185. Total +329 across 21 files. Reproducibility: yes. for the current PR blockers: CI logs reproduce the stale renamed-symbol failures at compact.hooks.test.ts:1075 and attempt.spawn-workspace.context-engine.test.ts:2339. The underlying session-invariant bug is source-reproducible on current main because inspected reset and compaction hook contexts still omit messageProvider on key paths. Review metrics: 2 noteworthy metrics.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land a refreshed branch that keeps the shared resolver approach, fixes the stale renamed test references, proves the actual reset/compaction hook and zero-token accounting paths, and preserves plugin hook identity compatibility. Do we have a high-confidence way to reproduce the issue? Yes for the current PR blockers: CI logs reproduce the stale renamed-symbol failures at compact.hooks.test.ts:1075 and attempt.spawn-workspace.context-engine.test.ts:2339. The underlying session-invariant bug is source-reproducible on current main because inspected reset and compaction hook contexts still omit messageProvider on key paths. Is this the best way to solve the issue? No as submitted. The shared resolver and centralized hook wiring are the right fix shape, but the branch needs the stale test references repaired and actual hook/accounting path proof before merge. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fc6d448138fc. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +144, Tests +185. Total +329 across 21 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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
|
9619013 to
054a6a8
Compare
|
ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical. Source PR: #69270 |
|
Working on this — going to address the ClawSweeper review points:
Will push the update shortly and request a re-review. |
- Pass resolveHookMessageProvider result to runBeforeCompactionHooks and runAfterCompactionHooks instead of the raw resolvedMessageProvider, fixing a P2 wiring gap where direct compaction still emitted undefined or non-normalized provider values. - Remove release-owned changelog entry.
|
Pushed the fix:
Latest commit: Now working on redacted runtime proof for actual hook emission. Will post update after. |
Real behavior proof updateBehavior addressed: Direct compaction hook calls now receive the resolved Real environment tested: Same Debian 12 host, Node v25.9.0, Exact steps: node --import tsx <<'EOF'
import { resolveHookMessageProvider } from './src/utils/hook-message-provider.ts';
const cases = [
{ label: "direct compaction: Feishu session key", sessionKey: "agent:main:feishu:default:direct:ou_testuser" },
{ label: "direct compaction: non-channel direct key", sessionKey: "agent:main:direct:peer_123" },
{ label: "direct compaction: mixed-case Telegram from caller", sessionKey: "agent:main:main", provider: "Telegram" },
{ label: "direct compaction: Telegram session key", sessionKey: "agent:main:telegram:direct:123" },
{ label: "direct compaction: Feishu key + explicit Discord override", sessionKey: "agent:main:feishu:direct:ou_test", provider: "Discord" },
];
for (const item of cases) {
console.log(`${item.label}: ${JSON.stringify(resolveHookMessageProvider(item))}`);
}
EOFEvidence after fix: Observed result: Channel-scoped session keys correctly infer the provider; non-channel keys return The
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Resolve conflicts across 17 files after upstream renamed pi-embedded-* → embedded-agent-* and refactored session-reset/gateway internals. Preserved all core PR changes: - hook-message-provider.ts (new shared resolver) - resolveHookMessageProvider wired into all 4 hook emission paths - zero-token compaction accounting in session-updates.ts - compact.ts P2 wiring fix - resolveCompactionHookMessageProvider in handlers.compaction.ts
|
Merged upstream/main (2026-06-06) to resolve stale drift and fix CI issues. Resolved 17 conflicts from upstream renames (
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
normalizeOptionalString moved to @openclaw/normalization-core/string-coerce. parseAgentSessionKey moved to ../sessions/session-key-utils.js.
…merge - Add missing resolveHookMessageProvider import in compact.ts - Remove duplicate messageChannel field in attempt.ts - Remove duplicate messageChannel field in subscribe.types.ts
Summary
Restore session invariants across compaction and reset instead of patching each symptom in isolation.
This coordinated fix now covers four connected paths:
before_compaction/after_compactionhook contextcompact.queued.ts/new//resethook context inemitResetCommandHookssessions.resethook context inemitGatewayBeforeResetPluginHookIt also fixes compaction bookkeeping so zero-token outcomes reset cached usage instead of leaving the session in a repeated safeguard loop.
What changed
Telegrambecometelegramagent:main:direct:peer_123unresolved instead of emitting fake providerstotalTokens/totalTokensFresh/estimatedCostUsdfrom compaction results even whentokensAfter === 0Why
These reports all describe the same broader failure mode: compaction/reset code paths were not preserving the session invariants downstream systems rely on.
That surfaced as different user-visible bugs:
messageProvidervalues and split one real conversation into multiple logical sessionsIssues
Fixes #69269
Fixes #69286
Also addresses the duplicate token-accounting report in #69287.
Related cluster: #69202.
Tests
pnpm buildpnpm checkpnpm exec vitest run src/auto-reply/reply/commands-core.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/auto-reply/reply/reply-state.test.ts src/gateway/server.sessions.gateway-server-sessions-a.test.tsReal behavior proof
node --import tsx.messageProvider: "feishu", legacy non-channel direct keys leave the provider unset, and explicitTelegramis canonicalized totelegrambefore hook context emission.