Repository navigation
chore(main): release 9.0.0-beta.4 - #1465
Conversation
|
Ladon does not review bot-authored PRs. |
6cc61e0 to
01bbf24
Compare
6bda3ba to
d138462
Compare
aec9a2c to
28c609b
Compare
|
Hold this release PR until #1534 merges. #1534 reverts #1502, the experimental AdCP 3.3 agent identity code, on Right after #1534 merges, record the revert on |
|
Could #1475 land in this beta? The Embedded Sales Agent (scope3data/embedded-sales-agent#652) is blocked on two things, and beta.4 fixes only one:
Both are needed before ESA can leave 8.1.x. As ESA tracks 8.1.x, any further 8.1.x backport also needs to be present in the 9.0 beta it moves to. |
This reverts commit 3961d1c, the squash merge of #1502, feat(identity): add experimental AdCP 3.3 agent identity. #1502 added experimental AdCP 3.3 agent identity code written to open drafts. main releases the 9.x line on AdCP 3.2.x, so the drafts would ship in 9.0.0-beta.4 (#1465) and every later 9.x release. Per adcp-client-python#1525, draft-spec work lives on next, which already carries #1502 and releases 10.0.0-alpha.N pre-releases. Conflict resolution: src/adcp/client.py. #1532 added the product_property_policy parameter to ADCPClient and ADCPMultiAgentClient next to #1502's experimental_agent_identity parameter. The resolution keeps product_property_policy, its docstrings, its attribute, and its forwarding to per-agent clients, and removes only the experimental_agent_identity parameter, docstrings, attribute, and forwarding. No later main commit uses code that #1502 added. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
7a90273 to
b17c960
Compare
|
🤖 Created releases: 🌻 |
… directory (#1543) * chore(main): release 9.0.0-beta.4 (#1465) * chore(main): release 9.0.0-beta.4 * chore: normalize prerelease version to PEP 440 --------- Co-authored-by: aao-ipr-bot[bot] <279263549+aao-ipr-bot[bot]@users.noreply.github.com> * docs(releasing): write the main, release/N.x, and next branch rules (#1535) Record the branch model from adcp-client-python#1525 in RELEASING.md: which branch carries which spec line, how fixes move between them (backports, regular main to next merges, forward-port and backport labels), how next cuts 10.0.0-alpha.N pre-releases from its own release-please setup, the one-time procedure that keeps #1502 on next after main reverts it, and how next merges into main at ratification. CONTRIBUTING.md points feature branches at the right base. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(governance): require crit markers with their claims, and run the signing tests CI skips (#1539) * test(webhooks): pass operation_id to send_mcp in the webhook sender tests operation_id became a required keyword of WebhookSender.send_mcp in #1066. Twenty-five calls in test_webhook_sender_e2e.py, test_webhook_sender_alt_auth.py, and test_webhook_sender_from_pem.py still omitted it, so 24 tests raised TypeError before they reached the behavior they test. CI doesn't install fastapi, so the modules skip there and nothing reported it (#1524). Each call now passes operation_id. * test(webhooks): give the proxy-env test's fake client the stream method the sender calls Since #1066 the sender posts through client.stream, which bounds the response body it keeps. The fake httpx.AsyncClient in test_owned_client_ignores_https_proxy_env still had only post, so the test failed with AttributeError once the operation_id fix let it run. The fake now yields its response from stream. * test(webhooks): retry with the first delivery's timestamp in the dedupe test An idempotency key binds the payload. test_retry_with_same_idempotency_key_dedupes called send_mcp twice with the same key and no timestamp, so each call stamped its own time, the second body differed, and the receiver answered 409 instead of a duplicate 200. send_mcp's docstring names the conflict. Both calls now pass one timestamp, so the retry repeats the first body and the receiver dedupes it. * test(signing): sign the digest-off FastAPI case with the 3.1 profile Since #1038 the 3.2 signer refuses a non-empty body without content-digest, as AdCP 3.2 request signing requires. The either-False case of test_signed_request_verifies_end_to_end asked the 3.2 signer for exactly that and raised ValueError before it reached the verifier. The case now signs with the 3.1 profile, where content-digest is optional, which is what the either policy accepts; the required case still signs with 3.2. * test(webhooks): re-sign the retry in the HTTP dedupe test test_duplicate_retry_dedupes_over_real_http posted the same body twice with the same Signature and nonce, so the receiver refused the second POST with 401 webhook_signature_replayed before it reached deduplication. A sender's retry repeats the body under a fresh signature, as WebhookSender.resend does. Each POST now carries its own signature, and the second one gets 200 with duplicate=true. * ci: install fastapi and svix with the dev extra Every CI job installs the package with .[dev] or .[dev,pg], and neither extra resolved fastapi or svix. Five signing test modules skip whole on pytest.importorskip("fastapi"), and test_standard_webhooks.py skips its two svix interop tests, so CI never ran them and their failures went unseen (#1524). The dev extra now carries both packages, so each job that runs the signing suite runs these files too. Closes #1524 * fix(governance): require each critical marker, its crit entry, and its claim together security.mdx checklist step 4 (AdCP 3.2.1 to 3.2.5) requires, for authorized_commitment, authorized_task, and authorized_payload_hash, "each boolean protected-header marker, its crit entry, and its payload claim to appear together", and the unknown-extension rule says verifiers "MUST also reject when the critical marker and its corresponding claim do not appear together". verify_governance_authorization compared the claim only against a crit entry with a true marker, so it accepted a marker for a claim the payload doesn't carry: a crit entry with a false marker, a marker with no crit entry, or a false marker alone. The check now requires the three to be present together, with the marker true. test_critical_marker_crit_entry_and_claim_appear_together re-signs the accepted vector with each header, so only the crit check can refuse it; it failed before this change. * fix(governance): answer a non-string token alg with governance_token_invalid verify_governance_authorization tested the header's alg for membership in a set. A JSON list or object there is unhashable, so the verifier raised TypeError instead of refusing the token. It now refuses an alg that isn't a string as governance_token_invalid, the code the other malformed-header cases get. test_a_non_string_alg_is_an_invalid_token failed before this change. * fix(signing): decode base64url strictly JWS and JWK members are base64url: the RFC 4648 section 5 alphabet with the padding omitted (RFC 7515 section 2). RFC 4648 section 3.3 says implementations MUST reject encoded data that contains characters outside the base alphabet. b64url_decode used the standard library's lenient decoder, which accepted padding and the standard alphabet's + and /, dropped other characters, and ignored trailing bits. Verifier step 8 decodes the signer's JWK through public_key_from_jwk, so the request and webhook verifiers accepted a JWK whose x member had "!!" inserted. b64url_decode now refuses padding, + and /, and decodes the rest with base64.b64decode(altchars=b"-_", validate=True), which refuses any other character. It also refuses non-zero trailing bits (RFC 4648 section 3.5), so each value has the one spelling b64url_encode produces. Every caller already handles the ValueError it raises. test_jwk_members_are_strict_base64url failed before this change. * feat(identity): verify JWS artifacts on the issuer's Web Bot Auth key directory Implements specs/agent-identity-3-3.md R4 as amended by adcontextprotocol/adcp#8299 (WG-approved 2026-10-19). A governance context, designated-task response signing or rights attestation whose issuer origin O is listed by the trust record derived from O is verified with a key from O's key directory: alg EdDSA, kid the JWK thumbprint, no use/key_ops/adcp_use checks, revocation by O's list. Historical governance verification uses the governance key archive at O. A trust record that cannot be read never selects the 3.2 profile; issuers no trust record lists stay on it. adcp.signing.jws_artifacts adds select_jws_artifact_profile, verify_wba_jws_artifact, WbaJwsArtifactVerifier, HttpGovernanceKeyArchive and compact_jws_from_envelope, reusing TrustRecordEvaluator, DiscoveredSignerKeys and OriginRevocationChecker. verify_governance_authorization takes web_bot_auth= and keeps every other check; verify_historical_governance_context verifies retained tokens through the archive. Outages on the new path are governance_jwks_unavailable. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(identity): treat any key lookup failure as an outage on the JWS artifact path A custom key directory or governance key archive that raises anything other than JwsArtifactError now yields jws_key_unavailable (governance_jwks_unavailable) instead of escaping the verifier. An archive entry whose alg is not a string is skipped rather than raising TypeError, and a key the cached archive lacks is refetched at most every 30 seconds, so a key rotated into the archive is not reported unknown for a whole cache period. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: aao-ipr-bot[bot] <279263549+aao-ipr-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Constantine Mirin <konstantin.mirin@gmail.com>
🤖 I have created a release beep boop
9.0.0-beta.4 (2026-10-18)
⚠ BREAKING CHANGES
Features
Bug Fixes
Performance Improvements
Reverts
This PR was generated with Release Please. See documentation.