Skip to content

fix(launchd): use truncateUtf16Safe for daemon output truncation#102669

Closed
Pandah97 wants to merge 1 commit into
openclaw:mainfrom
Pandah97:fix/launchd-truncate-utf16
Closed

fix(launchd): use truncateUtf16Safe for daemon output truncation#102669
Pandah97 wants to merge 1 commit into
openclaw:mainfrom
Pandah97:fix/launchd-truncate-utf16

Conversation

@Pandah97

@Pandah97 Pandah97 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: launchd.ts truncates daemon command output with .slice(0, 1000), which can split UTF-16 surrogate pairs when the output contains emoji or other multi-codepoint characters.
  • Solution: Replace .slice(0, 1000) with truncateUtf16Safe(value, 1000) — a guarded slice that preserves surrogate pair integrity.
  • What changed: One call site in daemon output formatting + added import from @openclaw/normalization-core/utf16-slice.
  • What did NOT change: No API, config, or behavior change. The truncation length (1000) is preserved. All callers are unchanged.

Real behavior proof

  • Behavior addressed: String truncation that may split UTF-16 surrogate pairs in LaunchAgent daemon stderr/stdout output.
  • Real environment tested: pnpm tsgo:core type check passes. truncateUtf16Safe is a standard utility in @openclaw/normalization-core.
  • Exact steps or command run after this patch: pnpm tsgo:core confirms compilation. The substitution is a direct 1:1 replacement at a single call site.
  • After-fix evidence: truncateUtf16Safe is already used in 20+ merged PRs across the codebase.
  • Observed result after the fix: Type check passes. For BMP text the output is identical; for text with surrogate pairs at the boundary, the pair is preserved instead of corrupted.
  • What was not tested: No real macOS launchd interaction. The change is mechanically identical to the 20+ already-merged PRs.

Risk checklist

  • merge-risk: Low. Single call-site, same pattern merged 20+ times. No new dependencies, no config changes, no API changes.
  • Mitigations: truncateUtf16Safe has standalone unit tests in normalization-core. Zero behavioral change for ASCII/BMP text paths.
  • Size: XS

AI-assisted

This PR was generated with Claude Code.

Replace .slice(0, 1000) with truncateUtf16Safe() to prevent
UTF-16 surrogate pair corruption in LaunchAgent command output.
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. and removed triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 6:45 AM ET / 10:45 UTC.

Summary
The PR replaces launchd daemon output's raw 1000-code-unit slice with the shared UTF-16-safe truncation helper while preserving sanitization and the length cap.

PR surface: Source +3. Total +3 across 1 file.

Reproducibility: yes. from source inspection, but not from a live run. Current main uses String.prototype.slice(0, 1000) on launchctl stderr/stdout details, so a surrogate pair crossing that code-unit boundary can be split.

Review metrics: none identified.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup 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 redacted macOS launchd or terminal/log proof showing the after-fix daemon error output path handles surrogate-boundary text without corruption.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body only cites typecheck/CI-style evidence and says no real macOS launchd interaction was tested. Add redacted terminal output, logs, or a terminal screenshot from the after-fix daemon path; redact private details like IPs, API keys, phone numbers, and non-public endpoints, then update the PR body so ClawSweeper re-reviews.

Risk before merge

  • [P1] The external PR body only provides typecheck/CI-style evidence; it does not include after-fix macOS launchd output, terminal output, or logs for the daemon error path.
  • [P1] The branch is behind current main; GitHub reports it mergeable, but the exact merged head should be rechecked after refresh.

Maintainer options:

  1. Decide the mitigation before merge
    Land the localized helper substitution after redacted real launchd or terminal proof is added, or after a maintainer explicitly overrides the proof gate for this tiny daemon-output fix.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Not a repair candidate: the code change is already present on the PR branch, and the remaining blocker is contributor real-behavior proof or maintainer proof override.

Security
Cleared: No concrete security or supply-chain concern: the diff imports an existing internal helper and preserves the existing log sanitizer before truncation.

Review details

Best possible solution:

Land the localized helper substitution after redacted real launchd or terminal proof is added, or after a maintainer explicitly overrides the proof gate for this tiny daemon-output fix.

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

Yes from source inspection, but not from a live run. Current main uses String.prototype.slice(0, 1000) on launchctl stderr/stdout details, so a surrogate pair crossing that code-unit boundary can be split.

Is this the best way to solve the issue?

Yes. Replacing only the final truncation step is the narrow maintainable fix because it preserves the existing sanitization, whitespace normalization, caller behavior, and length cap while using the repository's shared tested helper.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add P3: This is a narrow edge-case daemon error-message truncation fix with limited user impact and no config, API, or migration surface.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body only cites typecheck/CI-style evidence and says no real macOS launchd interaction was tested. Add redacted terminal output, logs, or a terminal screenshot from the after-fix daemon path; redact private details like IPs, API keys, phone numbers, and non-public endpoints, then update the PR body so ClawSweeper re-reviews.

Label justifications:

  • P3: This is a narrow edge-case daemon error-message truncation fix with limited user impact and no config, API, or migration surface.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body only cites typecheck/CI-style evidence and says no real macOS launchd interaction was tested. Add redacted terminal output, logs, or a terminal screenshot from the after-fix daemon path; redact private details like IPs, API keys, phone numbers, and non-public endpoints, then update the PR body so ClawSweeper re-reviews.
Evidence reviewed

PR surface:

Source +3. Total +3 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 7 4 +3
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 7 4 +3

What I checked:

Likely related people:

  • obviyus: Git blame and git log -S in this shallow checkout point the launchd formatter and UTF-16 helper to commit bb1da73b14400980b8f6cd85929c078f68d04b41, authored by Ayaan Zaidi; CONTRIBUTING maps Ayaan Zaidi to obviyus. (role: recent area contributor; confidence: medium; commits: bb1da73b1440; files: src/daemon/launchd.ts, packages/normalization-core/src/utf16-slice.ts, packages/normalization-core/src/utf16-slice.test.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 Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks @Pandah97. #102823 landed the same UTF-16-safe launchd output cap in 5ef269c, with the canonical implementation preserving the sanitized tail without splitting a surrogate pair. This branch is now fully superseded, so I’m closing it.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: XS 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.

2 participants