Skip to content

Filter internal compaction artifacts from chat history#70348

Open
cholaolu-boop wants to merge 1 commit into
openclaw:mainfrom
cholaolu-boop:fix/chat-history-compaction-visible-artifacts
Open

Filter internal compaction artifacts from chat history#70348
cholaolu-boop wants to merge 1 commit into
openclaw:mainfrom
cholaolu-boop:fix/chat-history-compaction-visible-artifacts

Conversation

@cholaolu-boop

Copy link
Copy Markdown

Summary

This patch addresses the dominant chat.history visibility path where internal compaction and memory-flush artifacts leak back into normal chat history.

What This Fix Does

  • filters synthetic compaction markers from chat.history
  • filters internal Pre-compaction memory flush. prompts from chat.history
  • filters [Post-compaction context refresh] artifacts from chat.history
  • adds targeted sanitizer and gateway history tests for this path

Explicitly Not Part Of This Fix

  • audio payload removed during overflow recovery is not part of this patch

Why This Scope

The patch is intentionally limited to the dominant chat.history / compaction / flush visibility path. It does not touch Route A/B, step 1b, step 2, approval, heartbeat, or think-level behavior.

Optional Follow-up

  • optional end-to-end oversize regression coverage to guard the full overflow-to-history path

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime size: S labels Apr 22, 2026
@greptile-apps

greptile-apps Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR filters three categories of internal compaction artifacts from chat.history: synthetic messages carrying __openclaw.kind === "compaction" (created by readSessionMessages from raw JSONL compaction entries), Pre-compaction memory flush. user prompts, and [Post-compaction context refresh] system messages. Both a targeted unit test and a gateway-level integration test are added to cover the filtering path end-to-end.

Confidence Score: 5/5

Safe to merge; filtering logic is correct, well-tested, and isolated to the sanitization layer.

All findings are P2. The only observation is a redundant second call to shouldDropInternalHistoryMessage after sanitization — dead code in practice that doesn't affect correctness. The core logic, test coverage, and integration with the JSONL-to-message conversion path in readSessionMessages are all sound.

No files require special attention.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/server-methods/chat.ts
Line: 1037-1040

Comment:
**Redundant post-sanitization drop check**

`sanitizeChatHistoryMessage` only truncates/strips envelope content — it never adds an `__openclaw.kind` field or rewrites text to begin with a compaction prefix, so any message already passing the pre-sanitization guard at line 1027 will never flip to matching `shouldDropInternalHistoryMessage` after processing. This second invocation is dead code in practice and could mislead future readers into thinking sanitization can manufacture internal markers.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Filter internal compaction artifacts fro..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c520a62240

ℹ️ 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".

Comment on lines +994 to +995
text.startsWith("Pre-compaction memory flush.") ||
text.startsWith("[Post-compaction context refresh]")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict internal-history filtering to synthetic artifacts

The new prefix-based filter drops any history message whose text starts with Pre-compaction memory flush. or [Post-compaction context refresh] regardless of role or provenance, so legitimate user/assistant content that begins with those phrases is now silently removed from chat.history (and from session-history snapshots that reuse this sanitizer). This introduces false-positive data loss; the filter should be constrained to synthetic/internal entries (for example via metadata and/or stricter control-token checks) instead of raw text prefix alone.

Useful? React with 👍 / 👎.

Comment on lines +1037 to +1040
if (shouldDropInternalHistoryMessage(res.message)) {
changed = true;
continue;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant post-sanitization drop check

sanitizeChatHistoryMessage only truncates/strips envelope content — it never adds an __openclaw.kind field or rewrites text to begin with a compaction prefix, so any message already passing the pre-sanitization guard at line 1027 will never flip to matching shouldDropInternalHistoryMessage after processing. This second invocation is dead code in practice and could mislead future readers into thinking sanitization can manufacture internal markers.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/server-methods/chat.ts
Line: 1037-1040

Comment:
**Redundant post-sanitization drop check**

`sanitizeChatHistoryMessage` only truncates/strips envelope content — it never adds an `__openclaw.kind` field or rewrites text to begin with a compaction prefix, so any message already passing the pre-sanitization guard at line 1027 will never flip to matching `shouldDropInternalHistoryMessage` after processing. This second invocation is dead code in practice and could mislead future readers into thinking sanitization can manufacture internal markers.

How can I resolve this? If you propose a fix, please make it concise.

@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group powerful-tadpole-muy2

Title: Open PR candidate: internal compaction artifacts in chat.history

Number Title
#32068 Gateway/TUI: hide internal memory-flush prompts in chat history
#70348* Filter internal compaction artifacts from chat history

* This PR

@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep open: the bug area is valid, but this branch is not merge-ready because it drops the documented compaction checkpoint divider, uses provenance-free prefix filtering, is dirty against current main, and lacks real behavior proof.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

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

Yes, source-level: current main converts transcript compaction records into __openclaw.kind="compaction" messages and WebChat renders those as checkpoint dividers, while the PR drops them. I did not run tests because this is a read-only review.

Is this the best way to solve the issue?

No. The safer fix is provenance-aware filtering in the current shared display projection, not unconditional removal of compaction markers or text-prefix rows.

Security review:

Security review cleared: The diff changes Gateway TypeScript and tests only; no dependency, workflow, permission, secret-handling, or supply-chain concern was found.

AGENTS.md: found and applied where relevant.

What I checked:

  • stale F-rated PR: PR was opened 2026-04-22T21:24:57Z, is older than 30 days, and the latest review rated it F.
  • proof blocker: real behavior proof is missing and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • BunsDev: Merged the current compaction checkpoint divider and recovery affordance that this branch would remove. (role: feature owner; confidence: high; commits: 2810f1219a62; files: ui/src/ui/chat/build-chat-items.ts, ui/src/ui/views/chat.ts, docs/web/webchat.md)
  • vincentkoc: Recent current-main history and blame show repeated work in Gateway chat history projection and related session/history paths. (role: recent area contributor; confidence: medium; commits: f5eddc2b6d1f, 25f3d2d714e9, fa614d0907e8; files: src/gateway/chat-display-projection.ts, src/gateway/session-utils.fs.ts, src/gateway/server.chat.gateway-server-chat.test.ts)
  • openperf: Authored the recent current-main fix for stale subagent announce history in the same display projection and Gateway history test area. (role: recent area contributor; confidence: medium; commits: 982e88821c0d; files: src/gateway/chat-display-projection.ts, src/gateway/server-methods/server-methods.test.ts, src/gateway/server.chat.gateway-server-chat-b.test.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against fa614d0907e8.

@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. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 22, 2026
@clawsweeper

clawsweeper Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 22, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant