Skip to content

fix(nextcloud-talk): strip internal tool-trace banners from outbound text#101712

Merged
steipete merged 7 commits into
openclaw:mainfrom
Pick-cat:fix/nextcloud-talk-sanitize-outbound-90684
Jul 10, 2026
Merged

fix(nextcloud-talk): strip internal tool-trace banners from outbound text#101712
steipete merged 7 commits into
openclaw:mainfrom
Pick-cat:fix/nextcloud-talk-sanitize-outbound-90684

Conversation

@Pick-cat

@Pick-cat Pick-cat commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Part of #90684. Incorporates the useful regression coverage from #103355 by @miorbnli.

What Problem This Solves

Nextcloud Talk could deliver internal assistant tool-trace scaffolding to users. The standard outbound adapter lacked the shared assistant-visible sanitizer, and the channel's custom inbound reply delivery bypassed that adapter entirely.

Trace-only replies also need accurate delivery accounting: treating a fully stripped reply as visible can suppress an older legitimate concurrent reply in the foreground dispatch fence.

Why This Change Was Made

  • Add the shared sanitizeAssistantVisibleText hook to the standard Nextcloud Talk outbound adapter.
  • Sanitize only the text field in the custom inbound reply path, preserving media URLs, reply IDs, and the remaining payload.
  • Return an explicit visibleReplySent result from inbound delivery so a fully stripped internal-only payload reports false.
  • Keep sendMessageNextcloudTalk literal. It is the low-level caller-authored transport boundary, so examples or intentional trace-like text must not be rewritten there.

This matches the channel ownership boundary and avoids changing global defaults or unrelated caller-authored sends.

User Impact

Automatic Nextcloud Talk replies no longer expose internal tool banners, XML tool calls, or function-response scaffolding. Ordinary prose, fenced code examples, attachments, and reply threading are preserved. Fully stripped internal-only output sends nothing without suppressing a valid visible reply.

Evidence

Exact reviewed head: d2abead8ffdd201a9af23f83fa23094aad76a616

Exact tree: 99b411e22e0babe3f59b77cbb98ea30c07ed7d36

Testbox-through-Crabbox: tbx_01kx6g156zgvy1y8at948jzh84, succeeded and auto-stopped.

  • Fresh clone pinned to the exact SHA/tree before dependency execution.
  • Current main negative control failed both missing sanitizer contracts; its raw low-level literal test passed.
  • Fixed focused tests: 23/23 passed.
  • Full extensions/nextcloud-talk/src suite: 108/108 passed.
  • Real node:http delivery loopback verified the Nextcloud bot request path/method, sanitized automatic text, attachment formatting, reply IDs, HMAC headers, and unchanged low-level literal text.
  • pnpm check:changed passed extension and extension-test tsgo, changed-file lint with zero warnings/errors, dependency and architecture guards, and the runtime import-cycle check.
  • Targeted oxfmt --check and git diff --check passed.
  • Fresh gpt-5.6-sol autoreview reported no findings (0.97 correctness confidence).

The request shape was checked against the official Nextcloud Talk bot API documentation. No authenticated external Nextcloud instance was used; the production HTTP sender was exercised end-to-end against an isolated real loopback server.

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 10, 2026, 12:34 PM ET / 16:34 UTC.

Summary
The PR sanitizes internal assistant scaffolding from Nextcloud Talk direct outbound and inbound-triggered replies, with focused regression coverage and a release-note entry.

PR surface: Source +10, Tests +156, Docs +1. Total +167 across 5 files.

Reproducibility: yes. Current main lacks the direct outbound sanitizer hook, and inbound-triggered replies use a local delivery callback that bypasses the composed outbound adapter.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: vector/embedding metadata: extensions/nextcloud-talk/src/inbound.behavior.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #90684
Summary: This PR is the Nextcloud Talk candidate fix for the open cross-channel assistant-visible-text sanitizer gap.

Members:

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

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

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

Rank-up moves:

  • [P1] Add exact-head redacted output from a live Nextcloud Talk round-trip or local Gateway-to-HTTP capture covering inbound-triggered replies.
  • Refresh the branch until GitHub confirms a clean merge result and rerun the relevant checks.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: Terminal output proves the earlier outbound hook, but the current head adds inbound-triggered sanitization with mocked coverage only; add redacted live or Gateway-to-HTTP capture to the PR body, which should trigger a fresh review, or ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The current-head inbound payload transform changes user-visible message delivery, but the available real-behavior output exercises only the earlier outbound-only head.
  • [P1] The supplied GitHub context reported a dirty merge state, while the latest live query returned UNKNOWN rather than confirming a clean merge.

Maintainer options:

  1. Refresh and prove both delivery paths (recommended)
    Refresh the branch, retain sanitizer coverage on direct outbound and local inbound fallback delivery, and attach exact-head captured behavior before merge.
  2. Defer the expanded inbound path
    If real inbound delivery proof is unavailable, split or defer that newly added path rather than merging an unproven message-delivery transformation.

Next step before merge

  • [P1] The contributor should add exact-head inbound delivery proof and refresh mergeability; a maintainer can then perform the ordinary final review without opening a separate repair PR.

Security
Cleared: The focused runtime and test changes add no dependency, permission, secret, downloaded-code, package-resolution, or other supply-chain surface.

Review details

Best possible solution:

Keep the canonical sanitizer on both the composed outbound adapter and the direct inbound fallback, then provide exact-head captured behavior for mixed, trace-only, metadata-bearing, and ordinary replies before landing a refreshed branch.

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

Yes. Current main lacks the direct outbound sanitizer hook, and inbound-triggered replies use a local delivery callback that bypasses the composed outbound adapter.

Is this the best way to solve the issue?

Yes for the code shape: each real Nextcloud Talk delivery path applies the existing canonical sanitizer at its channel-owned boundary without introducing config or a parallel policy; exact-head behavioral proof is still required before merge.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add merge-risk: 🚨 message-delivery: The new sanitizer transforms payload text immediately before inbound delivery, so incorrect composition could alter or suppress user-visible replies.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: Terminal output proves the earlier outbound hook, but the current head adds inbound-triggered sanitization with mocked coverage only; add redacted live or Gateway-to-HTTP capture to the PR body, which should trigger a fresh review, or ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • remove proof: sufficient: Current real behavior proof status is insufficient, not sufficient.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 📣 needs proof.

Label justifications:

  • P1: The PR fixes internal runtime and tool scaffolding leaking into user-visible Nextcloud Talk replies.
  • merge-risk: 🚨 message-delivery: The new sanitizer transforms payload text immediately before inbound delivery, so incorrect composition could alter or suppress user-visible replies.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: Terminal output proves the earlier outbound hook, but the current head adds inbound-triggered sanitization with mocked coverage only; add redacted live or Gateway-to-HTTP capture to the PR body, which should trigger a fresh review, or ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +10, Tests +156, Docs +1. Total +167 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 2 10 0 +10
Tests 2 157 1 +156
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 168 1 +167

What I checked:

Likely related people:

  • steipete: Authored the bundled message-lifecycle migration, many recent Nextcloud Talk refactors, and the current PR head's inbound sanitization expansion. (role: recent area contributor and current-head author; confidence: high; commits: 05eda57b3c72, 2b61d491c3b5; files: extensions/nextcloud-talk/src/channel.ts, extensions/nextcloud-talk/src/inbound.ts, extensions/nextcloud-talk/src/inbound.behavior.test.ts)
  • vincentkoc: Recent merged history includes Nextcloud Talk runtime-boundary and inbound allowlist hardening, and this person is currently assigned to the PR. (role: recent channel contributor; confidence: medium; commits: ba20e6cd9863, a47722de7e3c; files: extensions/nextcloud-talk/src/channel.ts, extensions/nextcloud-talk/src/inbound.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 (3 earlier review cycles)
  • reviewed 2026-07-07T14:22:46.392Z sha ccc41f1 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-07T14:40:21.153Z sha ccc41f1 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-07T14:53:34.998Z sha ccc41f1 :: 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. P1 High-priority user-facing bug, regression, or broken workflow. labels Jul 7, 2026
@Pick-cat

Pick-cat commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review — Evidence updated with negative control + direct node --import tsx plugin proof.

@clawsweeper

clawsweeper Bot commented Jul 7, 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. and removed 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 7, 2026
@vincentkoc vincentkoc self-assigned this Jul 8, 2026
@steipete steipete self-assigned this Jul 10, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. 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. labels Jul 10, 2026
@steipete
steipete force-pushed the fix/nextcloud-talk-sanitize-outbound-90684 branch from 2b61d49 to 9b035d0 Compare July 10, 2026 16:49
@steipete
steipete force-pushed the fix/nextcloud-talk-sanitize-outbound-90684 branch from 9b58304 to d2abead Compare July 10, 2026 16:58
@steipete

Copy link
Copy Markdown
Contributor

Maintainer fixup and land-ready proof

I expanded the original outbound-hook fix to cover the channel's custom inbound reply path as well. The final shape keeps ownership narrow: automatic assistant text is sanitized at the two delivery boundaries, transport fields survive unchanged, a fully stripped reply reports visibleReplySent: false, and the low-level caller-authored sender remains literal.

Exact reviewed head: d2abead8ffdd201a9af23f83fa23094aad76a616

Exact tree: 99b411e22e0babe3f59b77cbb98ea30c07ed7d36

Proof:

  • git diff --check origin/main...HEAD — passed.
  • oxfmt --check on all five changed files — passed.
  • Fresh gpt-5.6-sol autoreview — no findings, 0.97 correctness confidence.
  • Testbox-through-Crabbox tbx_01kx6g156zgvy1y8at948jzh84: run 29109921152, succeeded and auto-stopped.
  • Fresh clone pinned to the exact SHA/tree before dependency execution.
  • Current-main negative control reproduced both missing sanitizer contracts; the raw low-level literal test passed.
  • Focused fixed tests — 23/23 passed.
  • Full pnpm test extensions/nextcloud-talk/src — 108/108 passed.
  • Real node:http loopback — verified sanitized automatic media delivery, attachment formatting, reply IDs, bot request path/method, HMAC headers, and unchanged raw literal text.
  • pnpm check:changed — passed extension/test tsgo, changed-file lint with zero warnings/errors, dependency and architecture guards, and runtime import-cycle check.

The bot request was checked against the official Nextcloud Talk bot API. Remaining gap: no authenticated external Nextcloud instance was available; the production HTTP sender itself was exercised end-to-end against an isolated real loopback endpoint.

Thanks @Pick-cat for the canonical report/fix and @miorbnli for the useful duplicate coverage folded from #103355.

@steipete
steipete merged commit 8a93d28 into openclaw:main Jul 10, 2026
96 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 11, 2026
…text (openclaw#101712)

* fix(nextcloud-talk): strip internal tool-trace banners from outbound text

* fix(nextcloud-talk): sanitize inbound replies

Co-authored-by: liyuanbin <[email protected]>

* test(nextcloud-talk): prove low-level send text preservation

* test(nextcloud-talk): focus inbound sanitizer coverage

* fix(nextcloud-talk): report stripped replies as non-visible

* docs(changelog): note Nextcloud Talk reply sanitization

* chore: keep PR changelog-neutral

---------

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

Labels

channel: nextcloud-talk Channel integration: nextcloud-talk merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants