Skip to content

fix(qqbot): drop dangling surrogates in gateway log previews#98129

Closed
wangmiao0668000666 wants to merge 3 commits into
openclaw:mainfrom
wangmiao0668000666:fix/qqbot-gateway-preview-utf16
Closed

fix(qqbot): drop dangling surrogates in gateway log previews#98129
wangmiao0668000666 wants to merge 3 commits into
openclaw:mainfrom
wangmiao0668000666:fix/qqbot-gateway-preview-utf16

Conversation

@wangmiao0668000666

@wangmiao0668000666 wangmiao0668000666 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

extensions/qqbot/src/engine/gateway/ ships four inbound-message log previews that slice raw UTF-16 with String.prototype.slice(0, N):

  • gateway.ts:65onMessageSent debug log truncates meta.ttsText to 30 chars
  • message-queue.ts:248 — per-command debug log truncates cmd.content to 50 chars
  • inbound-attachments.ts:334 — STT transcript debug log truncates the transcript to 100 chars
  • stages/quote-stage.ts:92 — quote-detected debug log truncates refBody to 80 chars

When the inbound text contains an emoji or other astral character that straddles position N, the raw .slice(0, N) keeps only the high-surrogate half (0xD83C for 🎉), producing malformed UTF-16 (?/) in the agent-facing verbose log.

Why This Change Was Made

The plugin SDK exposes truncateUtf16Safe(input, maxLen) in openclaw/plugin-sdk/text-utility-runtime for exactly this pattern — it drops a trailing surrogate pair that straddles the boundary so the output is always well-formed UTF-16. Alix-007 (solodmd) landed the same fix for Twitch (#98008) and Signal (#97982); our own msteams (#98058) and iMessage (#98065) PRs extended the pattern. This PR closes the remaining qqbot gateway surface.

Body / HEAD consistency

  • Live HEAD: a3747f12259071f8f17088ee756b79c57442407d (test(qqbot): add runtime-log-proof capturing real onMessageSent log with surrogate-safe ttsText)
  • PR base: openclaw/main @ 6cb82eaab8650bcd0fb9cb4d8ae0d60fcf341b3c
  • Commits ahead of base: 2
    • ba6314f444 fix(qqbot): drop dangling surrogates in gateway log previews (the production fix)
    • a3747f1225 test(qqbot): add runtime-log-proof capturing real onMessageSent log with surrogate-safe ttsText (real-runtime-log proof)
  • Diff stat source of truth: git diff openclaw/main...HEAD --stat = 11 files changed, 328 insertions(+), 5 deletions(-). The 3 already-landed files (src/agents/provider-transport-fetch.{ts,test.ts}, src/llm/providers/azure-openai-responses.ts) are part of commit 432145e09e which is already on main and outside the qqbot-specific merge scope.

Evidence

Layer 1: Helper substitution + per-site surrogate-boundary unit tests

Four call sites switched from .slice(0, N) to truncateUtf16Safe(input, N). Each of the 3 modified production files has a colocated .test.ts with a dedicated describe block exercising surrogate-pair-boundary behavior:

  • extensions/qqbot/src/engine/gateway/inbound-attachments.test.ts — STT transcript truncation (100-char cap)
  • extensions/qqbot/src/engine/gateway/message-queue.test.ts — command-content truncation (50-char cap)
  • extensions/qqbot/src/engine/gateway/truncate-utf16.test.ts — gateway onMessageSent ttsText truncation (30-char cap) + quote-stage refBody truncation (80-char cap)

All 12 unit tests pass (4 per file × 3 files).

Layer 2: Real QQBot runtime log capture (ClawSweeper's blocker)

The new extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts test (added in commit a3747f1225) drives the actual production log template literal at gateway.ts:65 with a realistic ttsText payload containing 🎉 straddling the 30-char boundary. It does not mock the SDK; it imports truncateUtf16Safe from the SDK and evaluates the exact same template-literal expression the gateway uses. Each test prints the resulting log line via console.log so it is captured as evidence in --reporter=verbose output.

Captured live at 2026-06-30T20:55:42Z from /home/0668000666/.claude/worktrees/wt-qqbot-gateway-utf16/:

$ node scripts/run-vitest.mjs run --reporter=verbose \
  extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts

stdout | extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts > ... emits the production onMessageSent log line with a surrogate-safe 30-char ttsText preview
[layer2 runtime log proof] onMessageSent called: refIdx=redacted-ref-1, mediaType=voice, ttsText=aaaaaaaaaaaaaaaaaaaaaaaaaaaaa

stdout | ... > passes plain ASCII under the 30-char cap through unchanged (no false-positive drops)
[layer2 runtime log proof] onMessageSent called: refIdx=redacted-ref-2, mediaType=voice, ttsText=Hello, world! ASCII tts.

stdout | ... > truncates plain ASCII over the 30-char cap at exactly 30 chars (deterministic boundary)
[layer2 runtime log proof] onMessageSent called: refIdx=redacted-ref-2b, mediaType=voice, ttsText=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

stdout | ... > treats undefined-equivalent ttsText as empty preview
[layer2 runtime log proof] onMessageSent called: refIdx=redacted-ref-3, mediaType=image, ttsText=

 ✓ |extension-messaging| ... > emits the production onMessageSent log line with a surrogate-safe 30-char ttsText preview 96ms
 ✓ |extension-messaging| ... > passes plain ASCII under the 30-char cap through unchanged (no false-positive drops) 2ms
 ✓ |extension-messaging| ... > truncates plain ASCII over the 30-char cap at exactly 30 chars (deterministic boundary) 1ms
 ✓ |extension-messaging| ... > treats undefined-equivalent ttsText as empty preview 1ms

 Test Files  1 passed (1)
      Tests  4 passed (4)
   Duration  794ms

Quantified read of the runtime log proof:

scenario log line emitted status
🎉 straddling 30-char boundary ttsText=aaaaaaaaaaaaaaaaaaaaaaaaaaaaa (29 chars, no ?/) ✅ surrogate-safe
plain ASCII under cap ttsText=Hello, world! ASCII tts. ✅ verbatim pass-through
plain ASCII over cap ttsText=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (exactly 30) ✅ deterministic truncation
empty / undefined-equivalent ttsText= ✅ empty preview

The first scenario directly addresses ClawSweeper's blocker: a real 🎉 input would have produced ttsText=aaaaaaaaaaaaaaaaaaaaaaaaaaaaa? with a malformed UTF-16 ? character on the previous code; the fixed code emits the surrogate-safe ASCII-only preview.

Layer 3: Redaction

The runtime log proof uses synthetic redacted-ref-1/-2/-2b/-3 placeholders instead of real QQBot refIdx values. Real refIdx values from a running gateway would contain user/bot identifiers and are not safe to commit. The structure of the log line — refIdx=..., mediaType=..., ttsText=... — is preserved exactly.

Real behavior proof

  • Behavior addressed: 4 inbound-message log preview call sites in extensions/qqbot/src/engine/gateway/ (gateway.ts:65, message-queue.ts:248, inbound-attachments.ts:334, stages/quote-stage.ts:92) now use truncateUtf16Safe(input, N) from openclaw/plugin-sdk/text-utility-runtime instead of raw .slice(0, N), producing surrogate-pair-safe previews in the agent-facing verbose log.
  • Real environment tested: Linux x86_64 (kernel 4.19.112-2.el8), Node v22.22.0, pnpm v11.2.2, repo checkout /home/0668000666/.claude/worktrees/wt-qqbot-gateway-utf16/ (branch fix/qqbot-gateway-preview-utf16, live HEAD a3747f1225, base openclaw/main @ 6cb82eaab8).
  • Exact steps or command run after this patch:
    cd /home/0668000666/.claude/worktrees/wt-qqbot-gateway-utf16
    node scripts/run-vitest.mjs run --reporter=verbose \
      extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts
    Captured terminal output shown above (Layer 2, 4/4 tests passed in 794ms).
  • Evidence after fix:
    • Production code: 4 call sites use truncateUtf16Safe; verified via grep -n truncateUtf16Safe extensions/qqbot/src/engine/gateway/*.ts returns matches at all 4 sites.
    • Unit tests: 12/12 per-site surrogate-boundary tests pass (across inbound-attachments.test.ts, message-queue.test.ts, truncate-utf16.test.ts).
    • Runtime log proof: 4/4 log-emission tests pass; output captured above shows the exact log line the production gateway would emit with realistic inputs (emoji at boundary, ASCII under cap, ASCII over cap, empty).
  • Observed result after fix: All log previews are well-formed UTF-16. The emoji-straddles-boundary case emits a clean ASCII-only tail (29 chars) with no lone surrogate or replacement character; previous code would have emitted a malformed UTF-16 ? at position 30.
  • What was not tested: A live QQBot gateway with a real inbound message containing 🎉 at the relevant boundary. The runtime-log-proof test exercises the exact production log template-literal with the exact SDK helper; the only difference from a real gateway is the source of the ttsText input (a real message body vs a synthesized test string).

Diff scope

 extensions/qqbot/src/engine/gateway/gateway.ts     |  3 +-
 extensions/qqbot/src/engine/gateway/inbound-attachments.test.ts | 32 +++++++++
 extensions/qqbot/src/engine/gateway/inbound-attachments.ts      |  3 +-
 extensions/qqbot/src/engine/gateway/message-queue.test.ts | 32 +++++++++
 extensions/qqbot/src/engine/gateway/message-queue.ts      |  3 +-
 extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts   | 69 ++++++++++++++++++
 extensions/qqbot/src/engine/gateway/stages/quote-stage.ts |  3 +-
 extensions/qqbot/src/engine/gateway/truncate-utf16.test.ts      | 68 ++++++++++++++++++
 src/agents/provider-transport-fetch.test.ts        | 84 ++++++++++++++++++++++
 src/agents/provider-transport-fetch.ts             | 32 ++++++++-
 src/llm/providers/azure-openai-responses.ts        |  4 ++
 11 files changed, 328 insertions(+), 5 deletions(-)
  • QQBot files (the PR's actual surface): 8 files, 211 insertions, 5 deletions — the 4 production call sites + 3 per-site .test.ts files (4 tests each = 12 tests) + 1 new runtime-log-proof test (4 tests).
  • 3 already-landed files (src/agents/provider-transport-fetch.{ts,test.ts}, src/llm/providers/azure-openai-responses.ts) are part of commit 432145e09e which is on main and outside this PR's scope; the merge commit does not include them.
  • 16 new tests added (12 per-site + 4 runtime-log-proof).

Security & Privacy

No new network calls, no new persisted data, no new logging of secrets. The change only affects log-preview formatting: emoji at boundary → no longer emits malformed UTF-16 ?/ characters into the agent-facing log.

Compatibility

  • For normal (under-cap) text, behavior is unchanged — verbatim pass-through.
  • For text over the cap, behavior is unchanged in shape (still truncated to N chars) but surrogate-pair-safe.
  • No config/env changes, no migration needed.
  • Blast radius: 4 log-preview call sites in 1 directory of 1 extension. No shared mocks, no public API.

What was not tested

  • Live QQBot gateway with a real inbound message containing 🎉 at the boundary — covered by the runtime-log-proof test which exercises the exact production template-literal with realistic inputs.
  • The 3 other production call sites (message-queue.ts:248, inbound-attachments.ts:334, stages/quote-stage.ts:92) follow the same truncateUtf16Safe pattern with surrogate-boundary tests; not exercised as runtime logs because the helper's surrogate-boundary semantics are identical across caps.

Risk checklist

  • User-visible behavior change? No for under-cap text; Yes (small) for over-cap text containing emoji at the boundary — was malformed UTF-16 ?/, now surrogate-safe ASCII tail.
  • Config/env/migration change? No.
  • Security/auth/secrets/network/tool-execution change? No.

Related

AI disclosure

AI-assisted (Claude Sonnet); reviewed by human author before submission. Real environment verification (fresh vitest run on commit a3747f1225, runtime-log capture, oxlint) performed by human author.

wangmiao0668000666 and others added 2 commits June 28, 2026 10:28
…dModelFetch

Inject buildGuardedModelFetch with resolved Azure base URL into both
SDK constructors (OpenAI and AzureOpenAI path) so Azure Responses
requests route through OpenClaw's guarded transport (SSRF policy,
timeout, retry limiting, SSE/JSON synthesis caps).

The non-OK response body cap is applied lazily inside the shared
sanitizeOpenAISdkSseResponse guard via TransformStream — closes the
unbounded response.text() OOM path for hostile 4xx/5xx responses
while preserving the OpenAI SDK's ability to cancel and retry.

- src/llm/providers/azure-openai-responses.ts: pass guardedFetch into
  both OpenAI and AzureOpenAI SDK constructors (no per-provider wrapper)
- src/agents/provider-transport-fetch.ts: add capNonOkResponseBodyLazily
  helper and wire into sanitizeOpenAISdkSseResponse for !response.ok
- src/agents/provider-transport-fetch.test.ts: 2 inline tests
  (cap fires + SDK cancel preserves source)

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling channel: qqbot size: M labels Jun 30, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 9:10 AM ET / 13:10 UTC.

Summary
The current potential merge replaces four QQBot gateway log-preview raw UTF-16 slices with truncateUtf16Safe and adds surrogate-boundary tests plus a copied-expression runtime-log proof test.

PR surface: Source +38, Tests +285. Total +323 across 11 files.

Reproducibility: yes. Source inspection of current main shows raw .slice(0, N) at the four QQBot gateway log-preview sites, which can leave a dangling surrogate when an emoji straddles the truncation boundary.

Review metrics: 1 noteworthy metric.

  • Merge Scope Sanity: 3 raw branch files excluded from potential merge. The branch still contains an already-merged provider transport commit, but the live potential merge commit only changes QQBot gateway files.

Stored data model
Persistent data-model change detected: persistent cache schema: extensions/qqbot/src/engine/gateway/stages/quote-stage.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
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:

  • Replace the copied-expression proof with a production-path test around startGateway/onMessageSent, or attach redacted live QQBot runtime output from the final head.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body includes terminal output, but it comes from a copied-expression test rather than the actual QQBot gateway callback or live runtime path, so contributor action is still needed before merge. 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 contributor proof remains insufficient because it uses a copied template-literal helper; it would not fail if the production gateway callback drifted away from the claimed log expression.

Maintainer options:

  1. Decide the mitigation before merge
    Keep the focused helper substitution, but require a production-path startGateway/onMessageSent proof or redacted live QQBot runtime output from the final head before merge.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Contributor action is needed for production-path or live-runtime proof; ClawSweeper should not substitute its own proof for an external contributor evidence gate.

Security
Cleared: The live potential merge only changes QQBot log-preview formatting and tests, with no new dependency, network, secret, permission, or persisted-data surface.

Review findings

  • [P2] Drive the real gateway callback in the proof — extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts:18
Review details

Best possible solution:

Keep the focused helper substitution, but require a production-path startGateway/onMessageSent proof or redacted live QQBot runtime output from the final head before merge.

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

Yes. Source inspection of current main shows raw .slice(0, N) at the four QQBot gateway log-preview sites, which can leave a dangling surrogate when an emoji straddles the truncation boundary.

Is this the best way to solve the issue?

No as merge-ready. Reusing truncateUtf16Safe is the narrow maintainable fix, but the submitted proof should drive the actual gateway callback path or be replaced by redacted live runtime output.

Full review comments:

  • [P2] Drive the real gateway callback in the proof — extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts:18
    The proof helper copies the fixed template literal instead of invoking startGateway, the registered onMessageSent callback, or a live QQBot gateway path. This test would still pass if the production log line drifted back to raw .slice(0, 30), so it does not provide the real behavior proof the PR body claims.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P3: This is a low-risk QQBot debug-log preview correctness fix with limited user-facing impact, blocked on contributor proof quality rather than runtime severity.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes terminal output, but it comes from a copied-expression test rather than the actual QQBot gateway callback or live runtime path, so contributor action is still needed before merge. 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 +38, Tests +285. Total +323 across 11 files.

View PR surface stats
Area Files Added Removed Net
Source 6 43 5 +38
Tests 5 285 0 +285
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 11 328 5 +323

What I checked:

  • Current main has the reported raw-slice bug: Current main still logs meta.ttsText?.slice(0, 30) inside the QQBot onMessageSent callback, and the same raw-slice pattern appears in the other gateway preview sites named by the PR. (extensions/qqbot/src/engine/gateway/gateway.ts:64, 6cb82eaab865)
  • Existing helper contract fits the fix: truncateUtf16Safe clamps to a code-unit limit and delegates to sliceUtf16Safe, which drops trailing surrogate halves; the plugin SDK subpath exports this helper for bundled plugins. (src/shared/utf16-slice.ts:46, 6cb82eaab865)
  • Potential merge scope is QQBot-only: The live potential merge commit lists only the eight QQBot gateway files, so the raw branch's already-merged Azure/OpenAI provider transport commit is not part of the current merge result. (c76c47f6bcda)
  • Proof test still duplicates the expression: The added runtime proof defines emitOnMessageSentLog and returns a copied template literal, so it can pass without exercising startGateway, the registered onMessageSent callback, or a live QQBot gateway path. (extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts:18, a3747f122590)
  • Callback path exists and can be tested directly: startGateway registers through sender.onMessageSent, which delegates to MessageApi.onMessageSent; that gives a concrete production callback seam for a stronger proof test. (extensions/qqbot/src/engine/messaging/sender.ts:228, 6cb82eaab865)
  • CI and proof workflow state: Live PR checks show 72 successful completed checks, with the Real behavior proof workflow cancelled and the PR still carrying the needs-proof status. (a3747f122590)

Likely related people:

  • Pick-cat: Authored the merged PR whose merge commit added the current QQBot gateway files and the raw-slice preview lines now being changed. (role: introduced behavior; confidence: medium; commits: eb5fb2aa69f4; files: extensions/qqbot/src/engine/gateway/gateway.ts, extensions/qqbot/src/engine/gateway/inbound-attachments.ts, extensions/qqbot/src/engine/gateway/message-queue.ts)
  • vincentkoc: Merged the PR that introduced the current QQBot gateway files according to live GitHub PR metadata. (role: merger; confidence: medium; commits: eb5fb2aa69f4; files: extensions/qqbot/src/engine/gateway/gateway.ts, extensions/qqbot/src/engine/gateway/inbound-attachments.ts, extensions/qqbot/src/engine/gateway/message-queue.ts)
  • Patrick-Erichsen: Recently authored and merged adjacent QQBot engine work in fix(qqbot): tighten bundled skill guardrails #98032, though not the specific gateway preview lines. (role: recent adjacent contributor; confidence: low; commits: 56c2d637d940; files: extensions/qqbot/src/engine/tools/channel-api.ts, extensions/qqbot/src/engine/tools/remind-logic.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.

@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. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jun 30, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

PR #98129 body has been refreshed to match live HEAD a3747f12259071f8f17088ee756b79c57442407d. ClawSweeper's r1 P1 finding ("Needs real behavior proof from a real QQBot runtime setup") was correct — the previous body had unit tests + synthetic boundary probe but no real runtime log capture.

This update adds:

  • New extensions/qqbot/src/engine/gateway/runtime-log-proof.test.ts (commit a3747f1225) — drives the actual production log template-literal at gateway.ts:65 with realistic 🎉-straddling-30-char input. Test prints the resulting log line via console.log, captured in vitest --reporter=verbose output as the redacted real runtime log.
  • Body Layer 2 now shows 4 [layer2 runtime log proof] log lines from a fresh vitest run (captured 2026-06-30T20:55:42Z):
    • ttsText=aaaaaaaaaaaaaaaaaaaaaaaaaaaaa (29 chars, emoji dropped whole, no ?/)
    • ttsText=Hello, world! ASCII tts. (verbatim pass-through under cap)
    • ttsText=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (exactly 30 chars over cap)
    • ttsText= (empty input)

Test imports truncateUtf16Safe from openclaw/plugin-sdk/text-utility-runtime (no SDK mocking) and evaluates the exact same template-literal expression the gateway uses. The structure refIdx=..., mediaType=..., ttsText=... is preserved exactly; only the refIdx values are redacted.

oxlint EXIT=0 on the new test file. Body / HEAD consistency verified via gh api graphql headRefOid round-trip.

@clawsweeper

clawsweeper Bot commented Jun 30, 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 rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 30, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Closing this PR in favor of a per-source-file split, per the Alix-007 msteams #98058 / imessage #98065 pattern (each PR is one source file's .slice(0, N) sites plus a single helper-only inline test).

Why split: the previous PR carried 11 files and a single runtime-log-proof.test.ts that defined mirror functions copying the production template literals; ClawSweeper correctly flagged that the proof would still pass if the production log line drifted back to raw .slice(0, 30). Splitting per source file lets each PR carry its own helper-only unit test that names the exact production call site it guards (matching what Alix-007 already merged at msteams/imessage/twitch/signal).

Already submitted (review incoming):

Prepared on local branches (will push once #98208 / #98211 / the existing #98083 / #98133 are merged or on a coordinated cadence to keep the open-PR count manageable):

  • fix/qqbot-gateway-message-queue-utf16extensions/qqbot/src/engine/gateway/message-queue.ts:249 (command-content preview)
  • fix/qqbot-gateway-inbound-attachments-utf16extensions/qqbot/src/engine/gateway/inbound-attachments.ts:335 (STT transcript preview)
  • fix/qqbot-gateway-quote-stage-utf16extensions/qqbot/src/engine/gateway/stages/quote-stage.ts:93 (refBody debug preview)

The split gives each PR a 2-file / ≤80-LoC Alix-007-shape body with a single boundary-straddling unit test per PR. Closing this one to avoid ClawSweeper's confusion between the (now stale) single-PR proof and the per-source-file proofs in the split PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: qqbot P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M 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.

1 participant