Skip to content

chore: release package#754

Merged
bokelley merged 1 commit intomainfrom
changeset-release/main
Apr 22, 2026
Merged

chore: release package#754
bokelley merged 1 commit intomainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Apr 22, 2026

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@adcp/client@5.9.1

Patch Changes

  • b1497f9: ci: consolidate pipeline and drop redundant jobs

    CI-only change, no runtime/library behaviour affected. Published package contents are unchanged.

    • ci.yml: collapse test / quality / security into a single job. Each was re-running checkout + setup-node + npm ci, wasting ~1–2 min of setup per PR. Also removes the clean && build:lib re-build in the old quality job and the redundant build step (alias of build:lib).
    • ci.yml: drop publish-dry-run. release.yml's prepublishOnly already validates packaging on the actual release PR.
    • ci.yml: drop dead develop branch from the push trigger.
    • schema-sync.yml: drop the PR-triggered validate-schemas job — ci.yml already syncs schemas and diffs generated files on every PR. Scheduled auto-update job preserved.
    • commitlint.yml: use npm ci instead of npm install --save-dev; the @commitlint/* packages are already in devDependencies.
  • 933eb2d: Two response-layer fixes for agents built from partial skill coverage:

    buildCreativeResponse / buildCreativeMultiResponse no longer crash on missing fields. The default summary previously dereferenced data.creative_manifest.format_id.id without guards — handlers that drop format_id (required by creative-manifest.json) crashed the dispatcher with Cannot read properties of undefined (reading 'id'), swallowing the real schema violation behind an opaque SERVICE_UNAVAILABLE. Now the summary optional-chains through the field chain and falls back to a generic string, so the response reaches wire-level validation and the buyer sees the actual missing-field error.

    replayed: false is no longer injected on fresh executions. protocol-envelope.json permits the field to be "omitted when the request was executed fresh"; emitting false violates strict task response schemas that declare additionalProperties: false (create-property-list-response, etc.). Fresh responses now drop any prior replayed marker; replays still carry replayed: true. The existing test/lib/idempotency-client.test.js "replayed omitted is surfaced as undefined" test aligns with this shift.

    Surfaced by matrix v10: six creative_generative pairs crashed with the dereference, and every property_lists pair hit the additionalProperties violation.

  • 5eb2ae9: fix(testing): context.no_secret_echo walks structured TestOptions.auth, and registerAssertion accepts { override: true }

    • The default context.no_secret_echo assertion in @adcp/client/testing
      previously treated options.auth as a string and added the whole
      discriminated-union object to its secret set. String.includes(obj)
      against [object Object] matched nothing, so the assertion was
      effectively a no-op for every consumer passing structured auth (bearer,
      basic, oauth, oauth_client_credentials). It now extracts the leaf
      secrets across every variant:

      • bearer: token
      • basic: username, password, and the base64 user:pass blob an
        Authorization: Basic header would carry
      • oauth: tokens.access_token, tokens.refresh_token,
        client.client_secret (confidential clients)
      • oauth_client_credentials: credentials.client_id and
        credentials.client_secret — resolving $ENV:VAR references to their
        runtime values so echoes of the real secret (not the reference string)
        are caught — plus tokens.access_token / tokens.refresh_token

      A minimum-length guard (8 chars) skips substring matching on fixture
      values that would otherwise collide with benign JSON.

    • registerAssertion(spec, { override: true }) now replaces an existing
      registration instead of throwing. Lets consumers swap in a stricter
      version of an SDK default (e.g. their own context.no_secret_echo)
      without calling clearAssertionRegistry() and re-registering every other
      default. Default behaviour ({ override: false } / no options) is
      unchanged and still throws on duplicate ids.

  • afc01f1: Widen two bundled default assertions per security-review feedback on spec(compliance): drop redundant assertion modules, use bundled 5.9 defaults (#2639) adcp#2769.

    idempotency.conflict_no_payload_leak — flip the denylist-of-5-fields to an allowlist of 7 envelope keys (code, message, status, retry_after, correlation_id, request_id, operation_id). The previous implementation only flagged payload, stored_payload, request_body, original_request, original_response — a seller inlining budget, start_time, product_id, or account_id at the adcp_error root slipped past, turning idempotency-key reuse into a read oracle for stolen-key attackers. Allowlisting closes the hole: anything a seller adds beyond the 7 envelope fields now fails the assertion.

    context.no_secret_echo — scan the full response body recursively (not just .context), add a bearer-token literal regex (/\bbearer\s+[A-Za-z0-9._~+/=-]{10,}/i), add recursive suspect-property-name match (authorization, api_key, apikey, bearer, x-api-key), and pick up options.test_kit.auth.api_key as a verbatim-secret source. The previous scope (response.context only, verbatim options.auth_token/.auth/.secrets[] only) missed the common cases where sellers echo credentials into error.message, audit.incoming_auth, nested debug fields, or as header-shaped properties. All caller-supplied secrets gate on a minimum length (8 chars) to avoid false positives on placeholder values.

    Both changes are patch-level — the assertion ids, public registration API, and passing-case behavior are unchanged; the narrowing on main was fresh in 5.9 and had no adopters broad enough for the strictening to break in practice.

    governance.denial_blocks_mutation is unchanged.

    16 new unit tests cover both widenings: allowlist hits (valid envelope passes), denylist vestigial names still fail, non-allowlisted field leaks (including stable sorted error output), plus bearer literals, verbatim options.auth_token echo, options.secrets[] echo, test_kit.auth.api_key echo, suspect property names at any depth, array walking, short-value false-positive guard, and prose-"bearer" ignore.

@github-actions github-actions Bot force-pushed the changeset-release/main branch 2 times, most recently from eb3c36d to e9fd7f1 Compare April 22, 2026 01:46
@github-actions github-actions Bot force-pushed the changeset-release/main branch from e9fd7f1 to 85a3556 Compare April 22, 2026 01:47
@bokelley bokelley merged commit 9acd1b3 into main Apr 22, 2026
2 checks passed
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