Skip to content

fix(sessions): prevent delivery-mirror prompt contamination with adjacent dedup and identity fallback (#99470)#99504

Merged
steipete merged 3 commits into
openclaw:mainfrom
maweibin:fix/delivery-mirror-prompt-contamination-99470
Jul 16, 2026
Merged

fix(sessions): prevent delivery-mirror prompt contamination with adjacent dedup and identity fallback (#99470)#99504
steipete merged 3 commits into
openclaw:mainfrom
maweibin:fix/delivery-mirror-prompt-contamination-99470

Conversation

@maweibin

@maweibin maweibin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Delivery-mirror transcript receipts could leak into provider-bound replay after historical session rebuilds stripped their normal provider / model provenance. The issue reporter measured adjacent duplicate assistant content in 108 of 323 submitted prompts.

Fixes #99470.

Why This Change Was Made

The replay boundary now recognizes all three valid openclawDeliveryMirror marker kinds even when provider/model metadata is absent. For the observed older row shape where every marker was lost, it removes only a receipt that immediately follows an identical assistant response, carries an explicit zero-usage snapshot, has a successful stop, and contains no tool calls.

The original broad adjacent-content dedup was narrowed during maintainer review. It could delete legitimate repeated model turns and used JSON serialization for equality. The final comparison is structural and preserves ordinary nonzero-usage and tool-call repeats. Current session-tree logic independently keeps new delivery side branches out of prompt-visible paths.

User Impact

Historical delivery receipts no longer teach the model that assistant answers occur twice. Normal repeated assistant turns remain intact.

Evidence

  • node scripts/run-vitest.mjs src/agents/embedded-agent-runner/replay-history.test.ts --reporter=verbose — 36 tests passed.
  • node scripts/run-vitest.mjs src/agents/sessions/session-manager.test.ts -t 'accepts an unowned side leaf only when it preserves the active branch' --reporter=verbose — 2 tests passed across both shards; 132 skipped.
  • node scripts/check-changed.mjs -- src/shared/transcript-only-openclaw-assistant.ts src/agents/embedded-agent-runner/replay-history.ts src/agents/embedded-agent-runner/replay-history.test.ts — passed in Blacksmith Testbox: https://github.com/openclaw/openclaw/actions/runs/29536678577
  • Autoreview — whole patch clean at confidence 0.94; final tool-call regression delta clean at 0.95.
  • git diff --check — passed.

Regression Test Plan

Coverage locks valid marker-only mirrors, marker-free zero-usage receipts, invalid marker preservation, and ordinary nonzero-usage and tool-call repeated assistant turns. Existing session-manager coverage proves a delivery side leaf preserves the active prompt branch and remains absent from rebuilt session context.

AI Assistance

The contributor used Claude Opus 4.8. Maintainer review rewrote and narrowed the patch. The author and maintainer take responsibility for the final change.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M labels Jul 3, 2026
@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 6:11 AM ET / 10:11 UTC.

Summary
The PR adds provider-bound replay filtering for stripped and bare delivery-mirror assistant duplicates, recognizes Anthropic tool_use blocks, and adds regression/proof coverage.

PR surface: Source +69, Tests +194, Other +283. Total +546 across 5 files.

Reproducibility: yes. source-reproducible: current main lacks marker fallback and adjacent dedup, while the PR proof script exercises the provider-bound replay path for live, stripped, and bare delivery-mirror survivors. I did not execute the script in this read-only review.

Review metrics: 1 noteworthy metric.

  • Provider-bound replay filters: 2 added guards. The PR adds one marker fallback and one adjacent-dedup guard that change which assistant transcript rows are sent to models.

Stored data model
Persistent data-model change detected: serialized state: src/agents/embedded-agent-runner/replay-history.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #99470
Summary: This PR is the candidate fix for the delivery-mirror prompt contamination report; the broader duplicate-transcript umbrella and the merged provenance PR overlap but do not replace this replay-side fix.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Get explicit session-state owner signoff on the adjacent no-tool assistant dedup invariant.
  • Rerun or refresh exact-head checks after the unrelated-looking base failures are resolved.

Risk before merge

  • [P1] The adjacent byte-identical assistant collapse changes which persisted assistant rows reach the provider prompt; maintainers should explicitly accept the invariant that adjacent no-tool identical assistant turns are delivery-mirror contamination, not legitimate conversation state.
  • [P1] Exact-head CI is currently unstable with unrelated-looking failures outside the touched files, so merge still needs normal check triage even though the patch review did not find a code defect.

Maintainer options:

  1. Owner Signoff Then Land (recommended)
    Accept the session-state replay invariant after owner review and land once exact-head checks are green.
  2. Add More Replay Proof First
    Require a focused side-branch/session-rebuild proof before merge if maintainers are not ready to accept content-level dedup from the current proof script.
  3. Pause For Broader Transcript Work
    Pause this PR if maintainers want the duplicate transcript umbrella to choose a larger persistence or migration design first.

Next step before merge

  • No ClawSweeper repair lane is needed because no narrow code defect was found; the next action is maintainer session-state signoff and green exact-head checks.

Maintainer decision needed

  • Question: Should OpenClaw accept adjacent no-tool assistant duplicate collapse as a provider-bound replay invariant for stripped delivery-mirror recovery?
  • Rationale: The code appears to fix the reported prompt contamination, but it intentionally changes replay history reaching providers and green unit proof cannot by itself settle the session-state invariant for all channels and rebuild paths.
  • Likely owner: vincentkoc — They recently merged the delivery-mirror provenance fix and are the clearest owner for whether the replay-side defense complements that source-side repair.
  • Options:
    • Accept Replay-Boundary Dedup (recommended): Approve this PR's marker fallback and adjacent no-tool duplicate collapse as the replay-side defense once exact-head checks are green.
    • Require Narrower Replay Proof: Ask for additional live or fixture proof around side-branch merge/session rebuild before accepting the adjacent-dedup invariant.
    • Replace With Source-Only Repair: Pause this PR and pursue a narrower source/provenance-only fix, accepting that bare historical or rebuilt survivors may remain unhandled.

Security
Cleared: The diff changes replay filtering, tests, and a local proof script; it does not change dependencies, workflows, lockfiles, install hooks, permissions, or secret handling.

Review details

Best possible solution:

Land this provider-bound defense after session-state owner acceptance of the adjacent-dedup invariant, keeping the merged provenance fix from #99855 as the source-side complement.

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

Yes, source-reproducible: current main lacks marker fallback and adjacent dedup, while the PR proof script exercises the provider-bound replay path for live, stripped, and bare delivery-mirror survivors. I did not execute the script in this read-only review.

Is this the best way to solve the issue?

Yes, this looks like the narrow maintainable fix shape: source-side provenance from #99855 helps new rows, and this PR covers stripped or bare survivors at the provider boundary without changing transcript persistence.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a normal-priority bug fix for prompt contamination and duplicated assistant context with a bounded session/replay surface.
  • merge-risk: 🚨 session-state: The patch changes provider-bound replay history by dropping some adjacent assistant rows, so a bad invariant could stale or remove legitimate session context.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal proof from node --import tsx scripts/repro/issue-99470-proof.mts exercising provider-bound replay cases, plus focused regression test output.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal proof from node --import tsx scripts/repro/issue-99470-proof.mts exercising provider-bound replay cases, plus focused regression test output.
Evidence reviewed

PR surface:

Source +69, Tests +194, Other +283. Total +546 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 3 77 8 +69
Tests 1 194 0 +194
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 283 0 +283
Total 5 554 8 +546

What I checked:

Likely related people:

  • vincentkoc: Recent merged work includes the delivery-mirror artifact provenance fix and earlier delivery-mirror history dedupe, both central to this PR's transcript identity boundary. (role: recent delivery-mirror and replay contributor; confidence: high; commits: db7286187f16, f5eddc2b6d1f, b4bc1f20c9fc; files: src/shared/transcript-only-openclaw-assistant.ts, src/config/sessions/transcript.ts, src/agents/embedded-agent-runner/replay-history.ts)
  • steipete: Current-main shallow blame and recent GitHub history show broad core/agent runtime and module-boundary work touching the affected files after large refactors. (role: recent core runtime contributor; confidence: medium; commits: cc88aa6c3c56, bb46b79d3c14; files: src/agents/embedded-agent-runner/replay-history.ts, src/agents/tool-call-id.ts, src/shared/transcript-only-openclaw-assistant.ts)
  • LZY3538: Recent replay-history work on compaction usage touched the same provider-bound replay normalization surface, making them a secondary routing candidate if compaction interactions need review. (role: recent replay-history adjacent contributor; confidence: medium; commits: e6ec74c25430; files: src/agents/embedded-agent-runner/replay-history.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-07-03T13:06:13.506Z sha 72dffc4 :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jul 3, 2026
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Jul 3, 2026
@maweibin

maweibin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

P1 issues addressed:

  • native tool_use detection: Added "tool_use" to TOOL_CALL_TYPES in extractToolCallsFromAssistant() — now recognizes native Anthropic snake_case blocks
  • Real Behavior Proof: Added scripts/repro/issue-99470-proof.mts with 5 proof cases covering identity fallback, adjacent dedup, both layers together, and native tool_use protection (negative control + quantified before/after)
  • Test coverage: 37 replay-history tests + 26 tool-call-id tests + 96 session-manager tests all passing

@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 3, 2026
@clawsweeper clawsweeper Bot added status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 3, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 3, 2026
@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 3, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 3, 2026
@maweibin
maweibin force-pushed the fix/delivery-mirror-prompt-contamination-99470 branch from 968644f to 72dffc4 Compare July 3, 2026 12:42
@clawsweeper clawsweeper Bot removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 3, 2026
@maweibin

maweibin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Merge Readiness Summary

This PR is now proof-complete and CI-green. Here are the merge value points and remaining pre-conditions:

Value

Dimension Detail
Production impact Issue reporter measured 33% of prompts contaminated (107/322 trajectory events, 278 adjacent duplicate pairs → 0 post-fix)
Defence depth 3-layer coverage: live mirror (existing main filter), stripped-marker mirror (Layer 1 — identity fallback), bare no-marker mirror (Layer 2 — adjacent content dedup)
P1 safety guard Native Anthropic tool_use (snake_case) blocks recognized in extractToolCallsFromAssistant — tool-call-bearing turns are never collapsed
Proof 6-case proof script exercises full buildSessionContext() → normalizeAssistantReplayContent → provider-bound prompt pipeline, each layer independently proven
Regression +17 tests (38 total), all pass

Entry Conditions (for maintainer review)

  • pnpm build — green
  • pnpm check / oxlint — green
  • pnpm test (replay-history + tool-call-id + session-manager) — 159 passed
  • proof: sufficient — 6 live behavior cases, all pass
  • rating: 🐚 platinum hermit — previous review confirmed
  • Session-state merge-risk sign-off: changes which persisted assistant history reaches provider prompts. The adjacent dedup collapses only byte-identical no-tool-call adjacent assistant messages; tool-use turns and user-separated turns are preserved. Maintainer review of this replay invariant is the remaining gate.

What This Doesn't Touch

  • Session persistence (JSONL is unchanged)
  • Gateway message broadcast
  • User-visible transcript display
  • Provider API contract

Thank you for reviewing!

@steipete @cpojer — would appreciate a look when you have a moment.

@maweibin

maweibin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jul 3, 2026
@maweibin
maweibin force-pushed the fix/delivery-mirror-prompt-contamination-99470 branch from 72dffc4 to 79a28e5 Compare July 6, 2026 09:26
@maweibin

maweibin commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@vincentkoc Hi! I've rebased this PR onto the latest main which includes your #99855 (fix(transcripts): mark delivery mirrors as artifacts).

Our changes are fully compatible with the shared constants you introduced (OPENCLAW_TRANSCRIPT_ARTIFACT_API, OPENCLAW_TRANSCRIPT_ARTIFACT_PROVIDER, OPENCLAW_DELIVERY_MIRROR_MODEL). The rebase was clean with no conflicts.

How our two PRs work together:

Your #99855 fixes the source — ensuring newly written delivery-mirror records carry the correct api: "openclaw-transcript" artifact provenance instead of the misleading "openai-responses".

This PR (#99504) adds defense-in-depth on the consumption side for #99470 — three layers of protection against delivery-mirror entries leaking into model prompts:

Layer What it catches Status
Layer 0 Live mirrors with provider/model intact Existing main (your #99855 made this more robust)
Layer 1 Stripped mirrors (provider/model gone, but openclawDeliveryMirror survives) New — identity fallback in isTranscriptOnlyOpenClawAssistantMessage
Layer 2 Bare mirrors (ALL markers stripped — only {role, content, usage} remains) New — adjacent byte-identical content dedup in normalizeAssistantReplayContent
P1 Native tool_use blocks weren't recognized by extractToolCallsFromAssistant Fix — added "tool_use" to TOOL_CALL_TYPES

Additionally, this PR independently fixes a pre-existing bug in extractToolCallsFromAssistant() (src/agents/tool-call-id.ts): TOOL_CALL_TYPES recognized "toolCall", "toolUse", and "functionCall" but was missing "tool_use" — the native Anthropic API snake_case content block type. Without this fix, any assistant turn carrying native tool_use blocks would be invisible to the isAdjacentAssistantDuplicate() guard, and the Layer 2 dedup could incorrectly collapse tool-call-bearing assistant turns. This is a standalone correctness issue that predates the delivery-mirror work — it was discovered during the defense-in-depth analysis for #99470 — and fixing it is essential for the Layer 2 adjacent dedup to be safe.

The key insight from the issue reporter's production data for #99470 is that session rebuild / side-branch merge can strip ALL markers from delivery-mirror entries — leaving them completely indistinguishable from real assistant replies to any metadata-based filter. Your #99855 fixes the provenance for new entries, but existing/rebuild-stripped entries need the identity fallback (Layer 1) and the content-level dedup (Layer 2) to be caught.

Would love your thoughts on this approach!

@LeoLinksAZ

Copy link
Copy Markdown

Independent real-world validation from a self-hosted OpenClaw deployment (three agents, ollama/qwen2.5:7b, Discord + Telegram channels).

Reproduction before this fix: hit this bug organically within minutes of connecting a fresh Telegram channel — assistant replies started repeating verbatim turn over turn, including one case where a leaked literal NO_REPLY sentinel prefixed an otherwise-normal reply. Also observed the described downstream effect on auto-compaction: it hallucinated fictional conversation summaries (a Python sorting script, a factorial function, a chunk-processing pipeline) that were never actually discussed, consistent with the described mechanism of duplicated/misidentified assistant turns bleeding into the prompt.

Validation after this fix (cherry-picked onto local main, commit 9b42663): ran a fresh session, sent multiple messages, then inspected the raw session transcript directly (transcript_events table) rather than trusting model output. Zero adjacent duplicate assistant messages, and zero provider:"openclaw"/model:"delivery-mirror" artifacts leaking into the stored transcript. Also ran the repo's own focused suite locally (node scripts/run-vitest.mjs against replay-history.test.ts, transcript.test.ts, transcript-append-redact.test.ts) — 115 passed, 0 failed.

Would be a meaningful reliability improvement to land — this was actively corrupting conversation history on a real deployment, not just a theoretical edge case.

@maweibin

Copy link
Copy Markdown
Contributor Author

@LeoLinksAZ Thank you for taking the time to validate this on a real self-hosted deployment with multiple agents and channels! This is exactly the kind of independent verification that proves the fix works beyond unit tests — your observation of zero adjacent duplicates and zero delivery-mirror leakage in the raw transcript_events table is very valuable evidence.

@vincentkoc — wanted to flag that an independent self-hosted operator has now validated this PR on a live production deployment (ollama/qwen2.5:7b, 3 agents, Discord + Telegram). They confirmed:

  • Before: delivery-mirror contamination appeared within minutes, causing verbatim repeated replies and fictional compaction summaries
  • After: zero adjacent duplicate assistant messages, zero delivery-mirror artifacts in the stored transcript, 115 tests green

This validates that #99504 provides real-world defense-in-depth on the replay/consumption side, complementing your provenance fix (#99855) on the source side. Would appreciate your review when you have a moment.

@steipete steipete self-assigned this Jul 16, 2026
@steipete
steipete force-pushed the fix/delivery-mirror-prompt-contamination-99470 branch from 731265f to ee0de98 Compare July 16, 2026 21:44
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed scripts Repository scripts size: L labels Jul 16, 2026
@steipete
steipete force-pushed the fix/delivery-mirror-prompt-contamination-99470 branch from ee0de98 to ce448ce Compare July 16, 2026 21:52
maweibin and others added 2 commits July 16, 2026 22:55
…cent dedup and identity fallback (openclaw#99470)

Two-layer defence against delivery-mirror entries leaking into provider
prompts after session rebuild / side-branch merge strips metadata:

Layer 1 (identity fallback): isTranscriptOnlyOpenClawAssistantMessage
gains an openclawDeliveryMirror field check to catch stripped-metadata
survivors that lost provider/model during rebuild.

Layer 2 (adjacent dedup): normalizeAssistantReplayContent collapses
adjacent byte-identical no-tool-call assistant messages, catching
fully-bare {role,content,usage} survivors invisible to any metadata
filter.

P1 fix: added 'tool_use' (native Anthropic snake_case) to
TOOL_CALL_TYPES in extractToolCallsFromAssistant so adjacent dedup
never collapses tool-call-bearing turns.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@steipete
steipete force-pushed the fix/delivery-mirror-prompt-contamination-99470 branch from ce448ce to 24fdd95 Compare July 16, 2026 21:55
@steipete
steipete merged commit b8c7f31 into openclaw:main Jul 16, 2026
125 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 17, 2026
…cent dedup and identity fallback (openclaw#99470) (openclaw#99504)

* fix(sessions): prevent delivery-mirror prompt contamination with adjacent dedup and identity fallback (openclaw#99470)

Two-layer defence against delivery-mirror entries leaking into provider
prompts after session rebuild / side-branch merge strips metadata:

Layer 1 (identity fallback): isTranscriptOnlyOpenClawAssistantMessage
gains an openclawDeliveryMirror field check to catch stripped-metadata
survivors that lost provider/model during rebuild.

Layer 2 (adjacent dedup): normalizeAssistantReplayContent collapses
adjacent byte-identical no-tool-call assistant messages, catching
fully-bare {role,content,usage} survivors invisible to any metadata
filter.

P1 fix: added 'tool_use' (native Anthropic snake_case) to
TOOL_CALL_TYPES in extractToolCallsFromAssistant so adjacent dedup
never collapses tool-call-bearing turns.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(sessions): narrow delivery mirror replay filtering

* test(sessions): preserve tool-call replay duplicates

---------

Co-authored-by: Claude Opus 4.8 <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

# delivery-mirror transcript entries leak into model prompts as duplicate assistant messages → models repeat themselves

3 participants