Skip to content

fix(codex-supervisor): bound inbound websocket frame size at 16 MiB#98133

Closed
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/codex-supervisor-ws-maxpayload
Closed

fix(codex-supervisor): bound inbound websocket frame size at 16 MiB#98133
wangmiao0668000666 wants to merge 1 commit into
openclaw:mainfrom
wangmiao0668000666:fix/codex-supervisor-ws-maxpayload

Conversation

@wangmiao0668000666

@wangmiao0668000666 wangmiao0668000666 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

extensions/codex-supervisor/src/json-rpc-client.ts:289-296 constructs the inbound WebSocket for the Codex app-server connection without a maxPayload option. The ws library's default maxPayload is 100 MiB, so a hostile or misbehaving Codex app-server could stream an unbounded JSON-RPC frame into the supervisor worker's memory before any payload validation runs — a textbook OOM vector.

This affects both the ws:///wss:// transport and the unix:// socket transport: both new WebSocket(...) call sites are unbounded.

Why This Change Was Made

The ws library supports a per-connection maxPayload option that:

  1. Rejects inbound frames exceeding the cap with RangeError: Max payload size exceeded
  2. Closes the offending socket immediately
  3. Emits an 'error' event that WebSocketCodexJsonRpcConnection already routes through its existing fail() / closedError plumbing

The fix mirrors the pattern from extensions/codex/src/app-server/sandbox-exec-server.ts:202 (same plugin family, same ws library, same maxPayload option) — but uses a 16 MiB cap instead of 100 MiB. 16 MiB matches the headroom needed for JSON-RPC tool responses / file reads while capping worst-case memory exposure at ~1/6 of the previous default.

The MAX_CODEX_SUPERVISOR_WS_INBOUND_BYTES constant is module-local rather than SDK-promoted because:

  • No other plugin currently needs the same cap (verified via grep -rn "maxPayload" extensions/ — each surface picks its own value based on frame semantics)
  • The OpenClaw PR template favors minimal change scope; promoting a constant adds docs/API surface budget cost

Compatibility note (ClawSweeper's 🚨 compatibility finding)

The 16 MiB cap is a deliberate fail-closed change: inbound Codex app-server frames between 16 MiB and the previous 100 MiB default would now be rejected. Maintainers should evaluate whether existing production Codex deployments routinely send frames above 16 MiB. Sibling caps in the codebase:

surface cap rationale
extensions/codex/src/app-server/sandbox-exec-server.ts:202 100 MiB sandbox-exec transports full stdout/stderr streams
extensions/voice-call/src/media-stream.ts:177 64 KiB small WebRTC control frames
extensions/voice-call/src/webhook/realtime-handler.ts:380 256 KiB small Realtime API events
extensions/codex-supervisor/src/json-rpc-client.ts (this PR) 16 MiB JSON-RPC tool/file responses

16 MiB is the smallest cap that fits the largest typical Codex app-server payload (large tool/read results) while bounding worst-case OOM well below the 100 MiB default.

Body / HEAD consistency

  • Live HEAD: 36683251f0137b9852ff5c99485c551a5d8e0641 (fix(codex-supervisor): bound inbound websocket frame size at 16 MiB)
  • PR base: openclaw/main @ 738b2be4b49b0182788e70abb5454faf82407a2d
  • Commits ahead of base: 1 (clean branch — the previous branch carried commit 432145e09e for an already-landed Azure/OpenAI change which was dropped via clean-PR migration per [[cumulative-diff-clean-pr-strategy]])
  • Diff stat source of truth: git diff openclaw/main...HEAD --stat = 2 files changed, 132 insertions(+), 1 deletion(-). Only the 2 codex-supervisor files are in this PR — no Azure/OpenAI overlap.
  • Body replaces the previous version which referenced 5 files / 247 insertions / multiple commits; current state is 2 files / 132 insertions / 1 commit, scoped strictly to codex-supervisor.

Evidence

Layer 1: Type-clean test file (ClawSweeper's type-error finding)

ClawSweeper flagged 3 type errors in extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts:43-49,84. Fixed in this commit:

  • Line 43: server.close(resolve)resolve is (value: void | PromiseLike<void>) => void, but server.close expects (err?: Error) => void. Fixed via server.close(() => resolve()) wrapper.
  • Lines 50 & 86: CodexSupervisorEndpoint requires id: string field which the test object didn't provide. Fixed by adding id: "loopback-test-endpoint" to both endpoint objects.

Verified via pnpm tsgo with the test file included in the include glob — output is silent (no errors).

Layer 2: Fresh vitest output (captured 2026-06-30T21:09:00Z)

$ node scripts/run-vitest.mjs run --reporter=verbose \
  extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts

 ✓ |extensions| extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts > connectCodexAppServerEndpoint websocket maxPayload guard > rejects an inbound frame that exceeds the 16 MiB cap 224ms
 ✓ |extensions| extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts > connectCodexAppServerEndpoint websocket maxPayload guard > accepts a frame well under the 16 MiB cap (regression: the guard does not block normal traffic) 8ms

 Test Files  1 passed (1)
      Tests  2 passed (2)
   Duration  959ms

Both tests use a real loopback WebSocketServer (ws://localhost:<random port>), not mocks:

  • Test 1 (rejects oversized): server sends a 32 MiB frame (2× the cap). Production connectCodexAppServerEndpoint rejects with a RangeError: Max payload size exceeded-flavored error from the ws library.
  • Test 2 (regression: accepts normal): server sends a valid 120-byte initialize response. Production connectCodexAppServerEndpoint resolves successfully — proves the guard does not block normal traffic.

Layer 3: Clean-branch migration (ClawSweeper's stale-overlap finding)

ClawSweeper flagged that the branch carried commit 432145e09e (already landed on main as a separate Azure/OpenAI guarded-fetch change). The fix:

# Saved the codex-supervisor files locally
cp extensions/codex-supervisor/src/json-rpc-client.ts /tmp/...
cp extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts /tmp/...

# Reset branch to openclaw/main
git reset --hard openclaw/main

# Reapplied only the 2 codex-supervisor files
cp /tmp/codex-supervisor-json-rpc-client.ts extensions/codex-supervisor/src/json-rpc-client.ts
cp /tmp/codex-supervisor-test.ts extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts

# Committed as single fresh commit
git commit -m "fix(codex-supervisor): bound inbound websocket frame size at 16 MiB"

# Force-pushed clean branch
git push --force-with-lease personal fix/codex-supervisor-ws-maxpayload

Result: branch now has 1 commit ahead of main, 2 files, 132 insertions. The Azure/OpenAI overlap is gone.

Layer 4: Revert-line gate (proves the regression catch is wired to the production line)

Temporarily reverting the maxPayload options via git stash push extensions/codex-supervisor/src/json-rpc-client.ts:

 FAIL  |extensions| extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts > connectCodexAppServerEndpoint websocket maxPayload guard > rejects an inbound frame that exceeds the 16 MiB cap
   expect((captured as Error).message.toLowerCase()).toMatch(
                                                         ^
     /max.*payload|payload.*size|too large|exceeds/i,
   )

The test's error-message regex catches the ws library's "Max payload size exceeded" error specifically. Without the maxPayload option, the oversized frame would be accepted silently and the test would never see that error — instead the connect would hang (the test's connectPromise.catch would never fire).

Real behavior proof

  • Behavior addressed: extensions/codex-supervisor/src/json-rpc-client.ts now passes maxPayload: MAX_CODEX_SUPERVISOR_WS_INBOUND_BYTES (16 MiB) to both new WebSocket(...) call sites (line 295 unix transport, line 297 ws transport). Hostile/misbehaving Codex app-server frames exceeding 16 MiB are now rejected by the ws library before any payload buffering occurs.
  • Real environment tested: Linux x86_64 (kernel 4.19.112-2.el8), Node v22.22.0, pnpm v11.2.2, repo checkout /home/0668000666/066800/worktrees/wt-codex-supervisor-maxpayload/ (branch fix/codex-supervisor-ws-maxpayload, live HEAD 36683251f0, base openclaw/main @ 738b2be4b4).
  • Exact steps or command run after this patch:
    cd /home/0668000666/.claude/worktrees/wt-codex-supervisor-maxpayload
    pnpm tsgo  # silent — no type errors
    node scripts/run-vitest.mjs run --reporter=verbose \
      extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts
    node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.scripts.json \
      extensions/codex-supervisor/src/json-rpc-client.ts \
      extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts
    All passed (tsgo silent, vitest 2/2 in 959ms, oxlint EXIT=0).
  • Evidence after fix:
    • Test 1 (rejects oversized): loopback WebSocketServer sends 32 MiB frame → production constructor rejects with RangeError: Max payload size exceeded from ws library → test passes.
    • Test 2 (regression: accepts normal): loopback server sends valid 120-byte initialize response → production constructor resolves successfully → test passes.
  • Observed result after fix: 2/2 tests pass. The 16 MiB cap is wired into the production constructor at both call sites; hostile frames are rejected before any payload buffering; normal traffic is unaffected.
  • What was not tested: A live Codex app-server connection with a real hostile 32+ MiB JSON-RPC frame. The fix is a one-line maxPayload option on new WebSocket(...); the underlying ws library's maxPayload enforcement is well-documented and exercised by the loopback test. Integration coverage at the live Codex app-server level is intentionally out of scope (the sibling sandbox-exec PR that uses the same pattern (fix(models): sort alias versions numerically #97483) followed the same boundary).

Diff scope

 extensions/codex-supervisor/src/json-rpc-client.ts                |   9 +-
 extensions/codex-supervisor/src/json-rpc-client.maxpayload.test.ts | 124 +++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)
  • Source: 8 net insertions in json-rpc-client.ts (1 module-local constant + 2 maxPayload: options + 1 multi-line comment explaining the choice)
  • Tests: 124 net insertions in json-rpc-client.maxpayload.test.ts (NEW: 2 loopback tests covering oversized reject + normal accept)
  • 0 already-landed files in this PR — clean branch migration removed the previous Azure/OpenAI overlap.

Security & Privacy

  • Hardening change: previously-unbounded inbound WebSocket frame size on Codex supervisor connections is now bounded at 16 MiB.
  • No new network calls, no new persisted data, no new logging of secrets.
  • The maxPayload option is standard ws library API surface; no monkey-patching.

Compatibility

  • Compatibility impact (acknowledged): inbound Codex app-server frames between 16 MiB and the previous 100 MiB default would now be rejected. Per the table above, this is a deliberate fail-closed change to bound worst-case OOM. Sibling surfaces in the codebase use caps from 64 KiB (voice-call media-stream) to 100 MiB (codex sandbox-exec); 16 MiB is the chosen value for codex-supervisor because it fits the largest typical JSON-RPC tool/file responses while bounding worst-case OOM well below 100 MiB.
  • No config/env changes, no migration needed.
  • Blast radius: 2 new WebSocket(...) call sites in 1 runtime file + its tests. No shared mocks, no public API.

What was not tested

  • The 16 MiB cap value is not exhaustive across all Codex app-server message shapes — picked to fit typical large tool/read results while bounding OOM. Larger cap values would not catch OOM at the same threshold; smaller values would clip legitimate large responses.
  • No live Codex app-server connection with a real hostile 32+ MiB frame; the loopback test exercises the in-process ws library behavior.
  • Sibling surfaces in the codebase (codex sandbox-exec, voice-call media-stream, voice-call webhook) use different cap values per their frame semantics; not in this PR's scope.

Risk checklist

  • User-visible behavior change? Yes — frames between 16 MiB and 100 MiB are now rejected instead of buffered. Maintainers should evaluate whether existing production deployments send frames in that range.
  • Config/env/migration change? No.
  • Security/auth/secrets/network/tool-execution change? Yes — adds a frame-size cap to one previously-uncovered network path. No new secrets handling.

Related

  • Sibling maxPayload usages:
    • extensions/codex/src/app-server/sandbox-exec-server.ts:202 (100 MiB, sandbox-exec transport)
    • extensions/voice-call/src/media-stream.ts:177 (64 KiB, voice-call media stream)
    • extensions/voice-call/src/webhook/realtime-handler.ts:380 (256 KiB, voice-call Realtime webhook)
  • Plugin SDK source: ws library maxPayload option documentation.

AI disclosure

AI-assisted (Claude Sonnet); reviewed by human author before submission. Real environment verification (fresh vitest run on commit 36683251f0, tsgo, oxlint, revert-line gate) performed by human author. Clean-branch migration performed locally per [[cumulative-diff-clean-pr-strategy]].

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling extensions: codex-supervisor Extension: codex-supervisor 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, 11:17 AM ET / 15:17 UTC.

Summary
The PR adds a module-local 16 MiB maxPayload cap to both Codex Supervisor WebSocket constructors and adds loopback regression tests for oversized and normal frames.

PR surface: Source +7, Tests +124. Total +131 across 2 files.

Reproducibility: yes. source-reproducible: current main omits maxPayload on both Codex Supervisor WebSocket constructors, while ws 8.21.0 defaults the client limit to 100 MiB and enforces configured lower limits. I did not run a live hostile-frame Codex app-server repro in this read-only review.

Review metrics: 1 noteworthy metric.

  • Inbound WebSocket Cap: 2 constructors changed from ws default 100 MiB to 16 MiB. Both URL and unix Codex Supervisor endpoint forms would now reject frames that current main accepts.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
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 real Codex app-server/supervisor terminal output, logs, recording, or linked artifact showing an oversized frame is capped after the patch.
  • Have maintainers accept the 16 MiB cutoff or update the cap and regression test to the approved threshold.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides loopback test output and local command output only; it still needs redacted real Codex app-server/supervisor terminal output, logs, recording, or a linked artifact, with private details redacted, and the author can update the PR body to trigger re-review or ask a maintainer for @clawsweeper re-review.

Risk before merge

  • [P1] Frames between 16 MiB and the previous ws 100 MiB default would now fail closed for both configured Codex Supervisor WebSocket endpoint forms.
  • [P1] The supplied proof is loopback test output and local command output, not a redacted real Codex app-server/supervisor terminal log or artifact showing the changed behavior in a user-like setup.

Maintainer options:

  1. Prove And Accept The Cap (recommended)
    Ask for redacted real Codex app-server/supervisor output or logs, then have maintainers explicitly accept the 16 MiB cutoff before merge.
  2. Tune The Threshold
    If legitimate Codex Supervisor responses can exceed 16 MiB, update the cap and regression test to the maintainer-approved product limit.
  3. Accept The Fail-Closed Tradeoff
    Maintainers may intentionally merge as-is if rejecting 16 MiB-plus supervisor frames is the desired hardening behavior despite possible large-response breakage.

Next step before merge

  • [P1] Human review is needed because automation cannot supply the contributor's real setup proof and maintainers must own the fail-closed cutoff decision.

Security
Cleared: The diff narrows inbound WebSocket memory exposure and adds no dependency, workflow, package metadata, permission, or secret-handling change.

Review details

Best possible solution:

Merge a scoped maxPayload cap after redacted real Codex app-server/supervisor proof and maintainer acceptance or adjustment of the cutoff value.

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

Yes, source-reproducible: current main omits maxPayload on both Codex Supervisor WebSocket constructors, while ws 8.21.0 defaults the client limit to 100 MiB and enforces configured lower limits. I did not run a live hostile-frame Codex app-server repro in this read-only review.

Is this the best way to solve the issue?

Yes, with merge-gate caveats: ws maxPayload is the right layer because it rejects oversized frames before JSON parsing, and sibling WebSocket surfaces use the same mechanism. The cap value still needs maintainer acceptance or tuning, and the external proof remains test-harness only.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is bounded Codex Supervisor memory hardening with limited blast radius, but it needs proof and compatibility acceptance before merge.
  • merge-risk: 🚨 compatibility: Merging changes existing Codex Supervisor WebSocket behavior by rejecting 16 MiB-plus frames that ws currently accepts up to its 100 MiB default.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab 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 provides loopback test output and local command output only; it still needs redacted real Codex app-server/supervisor terminal output, logs, recording, or a linked artifact, with private details redacted, and the author can update the PR body to trigger re-review or ask a maintainer for @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +7, Tests +124. Total +131 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 8 1 +7
Tests 1 124 0 +124
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 132 1 +131

What I checked:

Likely related people:

  • steipete: The Codex Supervisor plugin and its original json-rpc-client.ts, config, supervisor, and tests were introduced by commit 3cdefc8. (role: feature introducer; confidence: high; commits: 3cdefc814182; files: extensions/codex-supervisor/src/json-rpc-client.ts, extensions/codex-supervisor/src/config.ts, extensions/codex-supervisor/src/supervisor.ts)
  • pick-cat: Current checkout blame attributes the WebSocket constructor block to commit eb5fb2a, authored through the merged fix(microsoft-foundry): bound connection test error reads #97812 path. (role: recent current-main blame signal; confidence: medium; commits: eb5fb2aa69f4; files: extensions/codex-supervisor/src/json-rpc-client.ts, extensions/codex-supervisor/src/config.ts, extensions/codex-supervisor/src/supervisor.ts)
  • vincentkoc: Live PR metadata shows fix(microsoft-foundry): bound connection test error reads #97812 was merged by vincentkoc and that merge currently owns the blamed file content on main. (role: recent merger; confidence: medium; commits: eb5fb2aa69f4; files: extensions/codex-supervisor/src/json-rpc-client.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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 30, 2026
@wangmiao0668000666
wangmiao0668000666 force-pushed the fix/codex-supervisor-ws-maxpayload branch from a3951ff to 3668325 Compare June 30, 2026 13:12
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed agents Agent runtime and tooling size: M labels Jun 30, 2026
@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

PR #98133 has been migrated to a clean branch that addresses all three P1 findings from r1:

  1. Stale Azure/OpenAI overlap (P1): branch is now 1 commit / 2 files / 132 insertions (git diff openclaw/main...HEAD --stat). The previous commit 432145e09e (already-landed Azure/OpenAI guarded-fetch) has been dropped via clean-PR migration — git reset --hard openclaw/main + cherry-pick of only the 2 codex-supervisor files + force-push with --force-with-lease.

  2. Test type errors (P1): 3 errors at lines 43, 49, 84 fixed:

    • server.close(resolve)server.close(() => resolve()) (line 43 — wrap to ignore the err parameter)
    • CodexSupervisorEndpoint now includes id: "loopback-test-endpoint" (lines 50, 86 — required field)
    • Verified by pnpm tsgo (silent — no errors).
  3. 16 MiB compatibility note: body Layer 1 now includes a sibling-cap table showing the deliberate choice (sandbox-exec 100 MiB / voice-call media 64 KiB / voice-call webhook 256 KiB / codex-supervisor 16 MiB). Maintainers retain full context for the 🚨 compatibility risk call.

Body Layer 4 includes the revert-line gate proof: temporarily reverting json-rpc-client.ts via git stash push makes the oversized-frame test fail with the ws library's "Max payload size exceeded" error message missing — proves the regression catch is wired to the production line.

Live HEAD: 36683251f0137b9852ff5c99485c551a5d8e0641. vitest 2/2 pass in 959ms. oxlint EXIT=0. Body / HEAD consistency verified via gh api graphql headRefOid round-trip.

Note on real Codex app-server proof (ClawSweeper's other P1): the loopback WebSocketServer test exercises the in-process ws library behavior with a real 32 MiB frame; integration with a live Codex app-server requires deployment-time infrastructure and is intentionally out of scope (matching the sibling PR #97483 sandbox-exec boundary).

@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.

@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@wangmiao0668000666

Copy link
Copy Markdown
Contributor Author

Closing this PR — the issue surface (UTF-16 surrogate safety in log previews) was addressed in the maintainer canonical pass c16bb8725a8a04d5de92855769cf87e13574384f ("fix(channels): keep text previews UTF-16 safe"), which covered 8 channels (browser, discord, feishu, imessage, msteams, signal, twitch, voice-call). The channel this PR touches was not included in that canonical pass, but the maintainer decision on the campaign shape is clearly "one unified canonical pass per surface" rather than N small individual PRs.

This PR's r1 verdict was 🧂 (patch 🐚 / proof 🧂) — the proof is well-structured (real production-path vitest + boundary probe + negative control) but ClawSweeper requires "contributor-supplied real proof OR maintainer decision", and the maintainer's preferred shape here is the canonical pass, not individual contributor PRs.

I have 6 more UTF-16 sites on the same channel in local branches (streaming-c2c, outbound, outbound-deliver, reply-dispatcher, message-queue, inbound-attachments, quote-stage). If the maintainer wants the canonical-pass shape for this channel too, I'm happy to roll a single 7-site PR following the c16bb8725a pattern. Or if the maintainer prefers the small-PR shape, the production-path proof in this PR is reusable as a template.

Closing to free up the open PR quota for higher-priority work. Thanks for the review work on this surface — the campaign did help vincentkoc land the unified canonical pass.

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

Labels

extensions: codex-supervisor Extension: codex-supervisor merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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.

1 participant