Skip to content

Filter internal compaction artifacts from chat history#70348

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

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
Contributor

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
Contributor

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.

Close: the useful parts of this PR are now split across current-main behavior and the canonical remaining issue. Current main keeps the memory-flush prompt out of the transcript, intentionally renders compaction records as checkpoint dividers, and routes the broader internal-prompt leak to #64613; this branch is conflicting, not maintainer-modifiable, proof-missing, and would regress current divider behavior.

Canonical path: Close this branch and keep the current-main compaction divider and memory-flush fixes; any remaining internal prompt filtering should proceed through #64613 with provenance-backed Gateway projection behavior.

So I’m closing this here and keeping the remaining discussion on #64613.

Review details

Best possible solution:

Close this branch and keep the current-main compaction divider and memory-flush fixes; any remaining internal prompt filtering should proceed through #64613 with provenance-backed Gateway projection behavior.

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

Yes, at source level for the merge blockers: current main intentionally preserves compaction markers for WebChat checkpoint dividers, while this PR drops them, and the prefix filter is visibly not provenance-scoped. No after-fix real WebChat proof was supplied for the contributor branch.

Is this the best way to solve the issue?

No. The best fix is not this stale server-methods prefix filter; the maintainable path is current-main shared display projection behavior that preserves compaction dividers and uses provenance or another structural marker for remaining internal prompt 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:

Likely related people:

  • BunsDev: Authored and merged the current compaction checkpoint divider behavior that supersedes removing compaction markers from history. (role: feature owner; confidence: high; commits: c322170b569f, 2810f1219a62; files: ui/src/ui/chat/build-chat-items.ts, ui/src/ui/views/chat.ts, docs/web/webchat.md)
  • vincentkoc: Authored and merged the current memory-flush transcript fix that keeps the pre-compaction flush prompt out of persisted history. (role: recent area contributor; confidence: high; commits: 9f69cb197fba, 7fd9c152d122; files: src/auto-reply/reply/agent-runner-memory.ts, src/auto-reply/reply/agent-runner-memory.test.ts)
  • liuhao1024: Current blame in the checked-out main points to recent work carrying the Gateway chat-display projection and history sanitizer code now owning this boundary. (role: recent area contributor; confidence: medium; commits: 7e0128ae659d; files: src/gateway/chat-display-projection.ts, src/gateway/session-utils.fs.ts, ui/src/ui/chat/build-chat-items.ts)

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

@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
@clawsweeper

clawsweeper Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jun 15, 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