Skip to content

refactor(webex): converge on the shared nonce minter and byte chunker - #5708

Merged
bolichen97 merged 1 commit into
mainfrom
fix/webex-shared-helper-dedup
Aug 26, 2026
Merged

refactor(webex): converge on the shared nonce minter and byte chunker#5708
bolichen97 merged 1 commit into
mainfrom
fix/webex-shared-helper-dedup

Conversation

@bolichen97

@bolichen97 bolichen97 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Three duplications of a shared messaging helper, all in code #5218 just landed. Found by auditing that branch's own new code against the messaging layer rather than by a review finding.

The options card minted its own nonce

webex/renderer.py used a local secrets.token_hex(8), while every other channel with a clickable control — Discord, Teams (×2), Telegram — and both shared registries (PendingApprovals.reserve, PickerRegistry.mint) reach messaging.renderer.new_approval_nonce().

Being honest about severity: entropy is identical (both 8 bytes / 64 bits), so no token was weaker and this is not a live security hole. What it violates is that helper's stated contract:

Every channel with a clickable approval has to mint one, compare it on resolve, and retire it with the prompt — and three independent copies of that is how one of them ends up with a weaker token or none at all.

The alphabet and length do differ (16 hex chars vs ~11 urlsafe), and the shared 8-byte choice exists because it has to fit Telegram's 64-byte callback_data — a constraint the next person to touch a local copy has no way to know.

Worst of it: the file disagreed with itself. The approval card on this same renderer already routes through the shared minter via PendingApprovals.reserve, with a comment saying so; the options card 380 lines later rolled its own.

outbound_mimetype was dead on arrival

No caller anywhere in src/ — only its own three tests, which gave it false life (coverage, plus "it's tested, so something must use it").

It was also dead for a good reason: it derived the content type from the path extension, which is what the outbound-files contract forbids —

Only a real raster is sent. Type comes from the leading bytes via messaging/raster.py, never an extension.

— and the upload path correctly uses item.mime, the sniffed type. Removed, with its tests and two now-unused imports.

chunk_utf8 re-implemented the shared primitive, minus its guards

webex/client.py::chunk_utf8 duplicated messaging.split.chunk_utf8_bytes loop-for-loop, and was missing both of the shared version's termination guards:

shared chunk_utf8_bytes the Webex copy
max_bytes <= 0 return [text] spins forever
a code point wider than the budget falls back to remaining[0] spins forever

So the copy was the strictly worse one, and its failure mode is a hang rather than an exception. Not reachable today — the single caller passes the 7000-byte default — so this is a latent hazard, not a live bug.

The local wrapper is now gone entirely and renderer.py calls chunk_utf8_bytes(content, WEBEX_MAX_TEXT) directly. An earlier revision kept it as a one-line delegating wrapper on a claimed symmetry with truncate_utf8 above it; that symmetry does not hold and the claim is withdrawn — truncate_utf8 earns its wrapper with three same-file consumers (client.py:447, :494, :522), while this one had zero, its single consumer lives in renderer.py and always took the default, and test_webex_client.py was already importing and exercising the shared primitive, so the local copy had no test of its own. The guard and fence-blindness rationale moved to the one call site where the choice is actually made.

Semantics preserved deliberately: still the fence-blind primitive, not split_markdown_bytes. Webex's answer path re-seals its own fences and is pinned that way by test_channel_table_rendering.TestDeliveryFraming.

Riding along, declared

test_webex_attachments.py is not purely a deletion. Removing outbound_mimetype took the file's only tests with it, so the same commit adds TestProcessWebexAttachments (3 tests) plus a bodies= download capability on the file's FakeClient — backfilling the only coverage of the ingest wiring at transport_dispatch.py:458. Test-only and coverage-positive, but an addition inside a subtraction PR, so it is stated here rather than left to be discovered in the diff. Its two temp-producing tests keep cleanup(result.temp_paths) in a finally so a failed assertion cannot leave downloaded bytes behind.

Not in scope

The [OPTIONS:] trailer parse is duplicated across seven sites (Discord, Telegram, Teams, WeCom, Slack, Webex, and render_options_as_text itself). That is a real convergence but it touches six channels, so it goes in its own PR rather than riding along here.

Verified locally: 504 webex-selected tests pass, plus the framing/split pins (test_channel_table_rendering.py, test_webex_client.py, test_messaging_split.py, test_webex_attachments.py — 316 passed); mypy (1104 files), flake8, isort and the black baseline ratchet all clean. Rebased onto current main; one commit.

@bolichen97
bolichen97 requested a review from a team as a code owner August 24, 2026 23:07
@bolichen97
bolichen97 requested a review from CrysisDeu August 24, 2026 23:07
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Aug 24, 2026
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — ✅ PASS

Design-level review of 12bdca3c48ac30ee652502a076d5c100238a637b — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

Three verified convergences onto owned primitives; behavior preserved in every reachable case (empty-input [], opaque nonce round-trip), and the ride-along tests are declared.

[DESIGN-REVIEWED] 12bdca3

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed 12bdca3c48ac30ee652502a076d5c100238a637b — this comment is updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] 12bdca3

Verdict parsed from the review's SHA-scoped output markers for commit 12bdca3c48ac30ee652502a076d5c100238a637b.

False positive or not applicable? A repository writer can comment:
/ai-review override fable 12bdca3c48ac30ee652502a076d5c100238a637b: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of 12bdca3c48ac30ee652502a076d5c100238a637b and found no blocking issues.

This comment is updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] 12bdca3

False positive or not applicable? A repository writer can comment:
/ai-review override gpt 12bdca3c48ac30ee652502a076d5c100238a637b: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — ✅ PASS

Premise-level review of 12bdca3c48ac30ee652502a076d5c100238a637b — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All claims verified. This is a pure-subtraction PR: three duplications removed in favor of existing shared mechanisms, with one declared test-only rider. Final review:

First-Principles-Verdict: PASS

Every item deletes a second spelling of a mechanism that already exists in messaging/, and the one rider is declared, test-only, and replaces coverage the deletion removed.

What this change ships

Intent: make Webex use the shared messaging helpers instead of three private copies — a FIX (of duplication), not an addition.

  1. Options card nonce now comes from the shared minter — justified (6 other call sites already use new_approval_nonce; nonce is opaque, compared by compare_digest at cards.py:176, so the alphabet change has zero format consumers)
  2. outbound_mimetype deleted with its tests — justified (grepped repo-wide: 0 consumers remain; only its own tests ever called it, and it derived type from extension against the sniff-only contract)
  3. Local chunk_utf8 deleted; renderer calls shared chunk_utf8_bytes directly — justified (shared version at split.py:350 carries both termination guards the copy lacked; 0 remaining references in src/ or test/)
  4. TestProcessWebexAttachments (3 tests) + FakeClient.bodies= — rides along, declared in the description; test-only, backfills the ingest coverage the deletion took
  5. truncate_utf8 docstring rewritten to name the shared splitter — rides along, trivial

Watch

The description defers the [OPTIONS:] trailer convergence; I count 6 renderer call sites of split_options_trailer plus the shared default — the deferral is real and correctly sized out of this PR, not an omission.

[FIRST-PRINCIPLES-REVIEWED] 12bdca3

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 24, 2026
@bolichen97
bolichen97 force-pushed the fix/webex-shared-helper-dedup branch from bb4682a to 5798baa Compare August 25, 2026 00:49
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision merge conflict Branch has merge conflicts with its base — author must resolve before merge and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 25, 2026
@bolichen97
bolichen97 enabled auto-merge (squash) August 25, 2026 09:03
@bolichen97
bolichen97 force-pushed the fix/webex-shared-helper-dedup branch from 5798baa to 7690f49 Compare August 26, 2026 01:35
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: passed Eligible automated validation passed for the current revision readiness: checking Automated validation is still running labels Aug 26, 2026
@bolichen97
bolichen97 force-pushed the fix/webex-shared-helper-dedup branch from 7690f49 to 9df7db9 Compare August 26, 2026 01:45
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Aug 26, 2026
Three duplications of a shared helper, found by auditing #5218's own new
code against the messaging layer.

The options card minted its nonce with a local secrets.token_hex(8) while
every other channel and both shared registries reach new_approval_nonce().
Entropy is the same 64 bits, so no token was weaker -- but the shared
minter's own contract says a second generator is what eventually diverges,
and the approval card on this same renderer already routes through it, so
the file disagreed with itself.

outbound_mimetype had no caller outside its own tests. It derived a type
from the path extension, which the outbound-files contract forbids (the
type comes from the sniffed bytes); the upload path correctly uses
item.mime, so the helper was dead on arrival and its tests gave it false
life. Deleting it dropped webex/attachments.py below the per-file coverage
floor, which is the honest signal that its coverage was resting on a
function nothing called: process_webex_attachments had no test at all. It
has three now -- a text file through the shared ingest, the empty case, and
the audio path that is the reason this channel passes handle_audio=True --
and the file is at 100%.

chunk_utf8 re-implemented messaging.split.chunk_utf8_bytes and was missing
both of its termination guards, so a non-positive budget or a code point
wider than the budget spins forever. Not reachable from its one caller,
which passes the 7000-byte default. It now delegates, the arrangement
truncate_utf8 beside it already had; test_webex_client.py was already
exercising the shared primitive rather than this copy.
@bolichen97
bolichen97 force-pushed the fix/webex-shared-helper-dedup branch from 9df7db9 to 12bdca3 Compare August 26, 2026 01:59
@bolichen97 bolichen97 removed the merge conflict Branch has merge conflicts with its base — author must resolve before merge label Aug 26, 2026
@github-actions github-actions Bot added readiness: passed Eligible automated validation passed for the current revision and removed readiness: checking Automated validation is still running labels Aug 26, 2026
@bolichen97
bolichen97 merged commit e04078c into main Aug 26, 2026
76 of 80 checks passed
@bolichen97
bolichen97 deleted the fix/webex-shared-helper-dedup branch August 26, 2026 02:41
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants