[AAASM-4951] 🐛 (sdk): Redact URL userinfo + wrap sealed-but-writable tool seams#315
Conversation
A wrapped transport error can carry a `scheme://user:pass@host` URL whose userinfo is credential material; the prior passes (Bearer/JWT/sk-/?token=) did not cover it, leaking the password into the registration-failure warning path. Add a userinfo scrub pass and note it in the coverage comment. Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…through Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…itable Object.seal() sets extensible:false but leaves existing data properties writable:true, so `tool.invoke = wrapper` succeeds on a sealed tool — yet the old guard gated every case on Object.isExtensible and returned false, skipping wrapping and silently downgrading enforcement. Split the two shapes: an existing writable/settable slot is assignable regardless of extensibility; only the add-property (absent-slot) case needs Object.isExtensible. Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror the isSeamWritable split in wrapFunctionToolInvoke's duplicated inline writability check so a sealed @openai/agents function tool is wrapped and governed instead of skipped-with-warning. Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Assert a sealed (non-extensible, writable-invoke) tool gets its seam replaced and a policy DENY is enforced, across both the langchain wrapper and the @openai/agents inline path. The existing frozen-tool tests still assert the skip-with-warning path is untouched. Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Claude Code reviewScope: SDK core only — no browser/UI surface, so no FE/design-fidelity review applies here. Item 1 — URL userinfo redaction (
Item 2 — sealed-but-writable seam (
Validation: No behavior change for callers; both fixes are strictly more-correct on previously-unhandled inputs. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Codecov flagged the `descriptor === undefined` side of the inline writability check (a tool whose own `invoke` slot is absent — inherited from the prototype) as an uncovered partial branch. Add a focused test that calls `wrapFunctionToolInvoke` with an inherited-invoke, non-extensible tool and asserts it is skipped-with-warning (no own `invoke` added), exercising the add-property side of the Object.isExtensible gate. Refs AAASM-4951 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
🤖 Claude Code review — update (CodeCov fixed)
Now: codecov/patch = pass; branch coverage 89.15% → 90.36%; typecheck + ESLint clean; full suite 631 tests pass. All checks green. |



Target
Task summary:
Two low-severity SDK-core hardening fixes (AAASM-4951):
redactErrorMessagemissed URL userinfo credentials. The scrubbercovered Bearer/Authorization/JWT/
sk-/?token=shapes but notscheme://user:pass@host/..., so a wrapped transport error carrying auserinfo-credentialed URL leaked the password into the
registration-failure warning path. Added a userinfo scrub pass
(
//<user>:<pass>@->//<redacted>@) and updated the coverage comment.Seam guard skipped a sealed-but-writable tool.
isSeamWritablerequired
Object.isExtensible(target)for every case.Object.seal()sets
extensible:falsebut leaves existing data propswritable:true,so
tool.invoke = wrapperwould in fact succeed on a sealed tool - yetthe guard returned
falseand skipped wrapping (an over-conservativefalse-negative that silently downgraded enforcement while a loud warning
fired). Now an existing writable/settable slot is treated as writable
regardless of extensibility; only the add-property (absent-slot) case is
gated on
Object.isExtensible. The same fix is applied to the duplicatedinline check in
hooks/openai-agents.ts(wrapFunctionToolInvoke). Agenuinely frozen tool (non-extensible, non-writable slot) still
skips-with-warning.
Task tickets:
Key point change (optional):
isSeamWritable: absent slot -> gated onObject.isExtensible; existingwritable/settable slot -> writable regardless of extensibility.
Effecting Scope
SDK core only - no browser/UI surface. No public API change.
Description
src/core/redact.ts- add URL userinfo scrub pass inredactErrorMessage; update coverage comment.src/core/tool-seam-guard.ts- splitisSeamWritableso extensibility only gates the absent-slot (add-property) case.src/hooks/openai-agents.ts- mirror the same split in the inline writability check.@openai/agentspaths; existing frozen-tool skip-with-warning tests unchanged.How to verify
pnpm install && pnpm typecheck && pnpm lint && pnpm test- all green (630 passed, 2 skipped).Closes AAASM-4951
🤖 Generated with Claude Code