Skip to content

fix(sdk): accept typed binary return signatures - #136

Merged
andrei-hasna merged 2 commits into
mainfrom
fix/54bce667-sdk-binary-transform
Aug 9, 2026
Merged

fix(sdk): accept typed binary return signatures#136
andrei-hasna merged 2 commits into
mainfrom
fix/54bce667-sdk-binary-transform

Conversation

@andrei-hasna

@andrei-hasna andrei-hasna commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • rewrite generated return types only inside OpenAPI operations already classified as binary
  • preserve the current optional attachment encoding query and deterministic generated SDK output
  • add a regression that proves the raw typed-object return is handled and a non-binary JSON operation is unchanged

Validation

  • bun test scripts/generate-sdk.test.ts
  • bun run sdk:generate
  • bun test scripts/generate-sdk.test.ts src/sdk/*.test.ts
  • bun run typecheck
  • bun run build
  • staged and commit-range gitleaks scans: no leaks found

Todos: 54bce667-44e2-4995-96d7-dd1227265bb1


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@andrei-hasna

Copy link
Copy Markdown
Contributor Author

[REVIEW] NO_GO — #136 @ 4dcddea — lens: correctness+isolation+wiring, reviewer codewith-sol-reviewer (1 of 1)

P0: None found.

P1 — scripts/generate-sdk.ts / generated src/sdk/index.ts: downloadMessageAttachment now exposes query?: { encoding?: "base64" }, but the binary rewrite unconditionally sets responseType: "arrayBuffer" and Promise<ArrayBuffer>. The existing server contract is bifurcated: src/server/api.ts returns a JSON {name,mime_type,size,content_base64} envelope when encoding=base64, and raw bytes only when the query is omitted. An exact-head executable reproduction loaded the candidate SDK and supplied that valid JSON response; its output was:

CONTROL requested_base64=true

ACTUAL return_type=ArrayBuffer

ACTUAL decoded_bytes="{\"name\":\"evidence.txt\",\"mime_type\":\"text/plain\",\"size\":3,\"content_base64\":\"YWJj\"}"

Thus a currently supported SDK call returns an opaque buffer containing JSON text instead of the documented JSON envelope. The new test checks only the omitted-query/raw-binary path, so CI cannot catch this. Preserve conditional JSON decoding (or provide separate typed methods) and add a runtime regression for encoding=base64.

P2/P3: None material to the merge decision.

Could not verify a live authenticated attachment download or run the full suite locally because the exact head was not checked out and the review was read-only. GitHub reports ci and swift (macOS) successful for this exact head; neither exercises the failing base64 SDK path.

@andrei-hasna

Copy link
Copy Markdown
Contributor Author

[REVIEW] NO_GO — #136 @ 4dcddea — lens: correctness+security+gates, reviewer Aruns (1 of 1)

Candidate read:

  • git log --oneline origin/main..HEAD: one commit, 4dcddea fix(sdk): accept typed binary return signatures.
  • git diff origin/main...HEAD --stat: 3 files changed, 64 insertions, 4 deletions.
  • Read the full diff and surrounding generator, generated SDK request path, OpenAPI attachment operation, server attachment handler, API-store caller, SDK attachment test, and server/OpenAPI tests.

Commands and exact results:

  • Setup only: bun install — exit 0; 166 packages installed.
  • Declared typecheck gate: bun run typecheck — exit 0; 0 diagnostics.
  • Declared test gate: bun run test — exit 0; 1788 pass, 0 fail, 6237 expect() calls, 120 files.
  • Targeted typed-path probe — exit 0. Literal output included:
    • REQUEST https://example.invalid/v1/messages/7/attachments/evidence.txt?encoding=base64
    • RETURN ArrayBuffer=true bytes=81
    • BODY {"name":"evidence.txt","mime_type":"text/plain","size":3,"content_base64":"YWJj"}

Blocking P0/P1 findings:

  1. P1, high confidence — the newly exposed typed encoding: "base64" path violates the OpenAPI response contract. scripts/generate-sdk.ts rewrites every binary-capable operation to Promise<ArrayBuffer> and always supplies responseType: "arrayBuffer"; src/sdk/index.ts simultaneously preserves the encoding?: "base64" query parameter. A caller can therefore request the documented JSON base64 envelope through the typed SDK, but receives an ArrayBuffer containing serialized JSON bytes. This is a currently reachable public SDK path and silently returns the wrong representation. Remedy: preserve binary behavior for the default call while returning the typed JSON envelope when encoding: "base64", with runtime regression coverage for both branches.

Non-blocking follow-ups: none.

@andrei-hasna

Copy link
Copy Markdown
Contributor Author

[REVIEW] GO — #136 @ 181226b — lens: correctness+security+gates, reviewer Aruns (1 of 1)

Focused re-review of the named P1 and its direct regressions:

  • The SDK request helper now decodes application/json responses normally even for binary-capable operations, while non-JSON successful responses still use arrayBuffer().
  • Generated overloads preserve Promise<ArrayBuffer> for omitted/empty encoding and return the typed base64 JSON envelope for { encoding: "base64" }.
  • Added runtime regression coverage for both response branches and generator assertions for both public overloads plus the union-typed implementation.

Exact candidate and validation:

  • Local HEAD and PR head both read 181226bef3ba642585f93b081a8a4087e1db9d04.
  • bun run sdk:generate — exit 0; 30 operations generated.
  • Focused pre-fix regression: bun run test -- scripts/generate-sdk.test.ts src/sdk/attachments.test.ts — exit 1; 1 pass, 2 fail.
  • Focused post-fix regression: same command — exit 0; 3 pass, 0 fail, 12 expect() calls.
  • bun run typecheck — exit 0; 0 diagnostics.
  • bun run test — exit 0; 1789 pass, 0 fail, 6241 expect() calls, 120 files.
  • Staged security scan: shield review — exit 0; No security issues found in staged changes.
  • Runtime control output:
    • RAW ArrayBuffer=true body=abc
    • ENCODED ArrayBuffer=false name=evidence.txt content_base64=YWJj

Blocking P0/P1 findings: none. The prior P1 is fixed on the current head.
Non-blocking follow-ups: none.

Rewrite the generated return type only inside OpenAPI operations already classified as binary, while preserving generated query parameters and guarding both positive and non-binary cases.

Agent: cossus
@andrei-hasna
andrei-hasna force-pushed the fix/54bce667-sdk-binary-transform branch from 181226b to 17e5c6e Compare August 9, 2026 18:34
@andrei-hasna

Copy link
Copy Markdown
Contributor Author

[REVIEW] GO — #136 @ 17e5c6e — lens: correctness+security+gates, reviewer Aruns (1 of 1)

Focused re-review after rebasing onto current origin/main (7414fcb0656d7df454e711447a15ff30e48b7228):

  • PR head and local HEAD both read 17e5c6e27ea666231061fbfe97113409e70857fa.
  • The named P1 remains fixed: raw/default downloads return ArrayBuffer; { encoding: "base64" } returns the typed JSON envelope.
  • The only base delta was PR fix(channel): reject missing member lists #137's channel/server validation change; it does not overlap the SDK generator or attachment client files.

Exact rebased-candidate validation:

  • bun run typecheck — exit 0; 0 diagnostics.
  • bun run test -- scripts/generate-sdk.test.ts src/sdk/attachments.test.ts — exit 0; 3 pass, 0 fail, 12 expect() calls.
  • bun run test — exit 0; 1794 pass, 0 fail, 6262 expect() calls, 120 files.
  • The pre-commit staged scan remained clean: shield review — exit 0; No security issues found in staged changes.
  • A final whole-worktree shield scan . --scanner secrets returned exit 1 for 15 pre-existing findings, all outside the four-file PR diff; none is introduced or changed by this candidate.

Blocking P0/P1 findings: none.
Non-blocking follow-ups: none for this PR.

@andrei-hasna
andrei-hasna merged commit 7683229 into main Aug 9, 2026
3 checks passed
@andrei-hasna
andrei-hasna deleted the fix/54bce667-sdk-binary-transform branch August 9, 2026 18:38
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.

1 participant