fix(nextcloud-talk): strip internal tool-trace banners from outbound text#101712
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 10, 2026, 12:34 PM ET / 16:34 UTC. Summary 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 Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. 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 detailsBest 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 changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +10, Tests +156, Docs +1. Total +167 across 5 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
Review history (3 earlier review cycles) |
|
@clawsweeper re-review — Evidence updated with negative control + direct |
|
🦞🧹 I asked ClawSweeper to review this item again. |
2b61d49 to
9b035d0
Compare
Co-authored-by: liyuanbin <[email protected]>
9b58304 to
d2abead
Compare
|
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 Exact reviewed head: Exact tree: Proof:
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. |
|
Merged via squash.
|
…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]>
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
sanitizeAssistantVisibleTexthook to the standard Nextcloud Talk outbound adapter.visibleReplySentresult from inbound delivery so a fully stripped internal-only payload reports false.sendMessageNextcloudTalkliteral. 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:
d2abead8ffdd201a9af23f83fa23094aad76a616Exact tree:
99b411e22e0babe3f59b77cbb98ea30c07ed7d36Testbox-through-Crabbox:
tbx_01kx6g156zgvy1y8at948jzh84, succeeded and auto-stopped.mainnegative control failed both missing sanitizer contracts; its raw low-level literal test passed.extensions/nextcloud-talk/srcsuite: 108/108 passed.node:httpdelivery 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:changedpassed extension and extension-test tsgo, changed-file lint with zero warnings/errors, dependency and architecture guards, and the runtime import-cycle check.oxfmt --checkandgit diff --checkpassed.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.