Skip to content

2.0.0 — wallet-auth types + AgentScoreError.details + create_session args + drop verify_webhook_signature#16

Merged
vvillait88 merged 30 commits intomainfrom
wallet-auth-hardening
Apr 29, 2026
Merged

2.0.0 — wallet-auth types + AgentScoreError.details + create_session args + drop verify_webhook_signature#16
vvillait88 merged 30 commits intomainfrom
wallet-auth-hardening

Conversation

@vvillait88
Copy link
Copy Markdown
Contributor

@vvillait88 vvillait88 commented Apr 24, 2026

Summary

agentscore-py@2.0.0 — wallet-auth hardening types + structured error access + speculative-helper drop. Breaking because of the webhook removal. Mirror of @agent-score/sdk@2.0.0 (node-sdk #21).

New (additive)

  • DenialCode Literal extended: wallet_signer_mismatch, wallet_auth_requires_wallet_signing, token_expired, invalid_credential.
  • NextStepsAction extended: send_existing_identity, mint_new_credential, use_operator_token, regenerate_payment_from_linked_wallet, deliver_verify_url_and_poll, switch_token_or_restart_session.
  • AgentMemoryHint, WalletSignerMismatchBody, WalletAuthRequiresSigningBody + per-shape NextSteps TypedDicts.
  • AssessResponse.linked_wallets (NotRequired).
  • SessionCreateResponse.agent_memory (NotRequired) + CredentialCreateResponse.agent_memory (NotRequired).
  • Fixed CredentialCreateResponse.expires_at: was str | None, now required str (always present post-mint).
  • AgentScoreError.details: dict[str, Any] — carries response-body fields beyond {code, message} so consumers can branch on verify_url, linked_wallets, claimed_operator, actual_signer, expected_signer, reasons, agent_memory.
  • create_session(address=..., operator_token=...) + acreate_session accept optional pre-association.
  • AgentScoreError.status attribute added (alias of status_code) for cross-language parity with the node SDK's .status.

Removed (BREAKING)

  • verify_webhook_signature removed. Same rationale as node-sdk: no internal consumer, zero outbound webhook emitter in core/api, the right primitive when needed is standardwebhooks (Svix). Exporting one preemptively was speculative surface.

Versioning

Bumped to 2.0.0. Honest semver — the webhook removal is breaking even though no consumer exercised it.

Test plan

  • 135 tests passing (98% coverage)
  • ruff + ty clean
  • Tag v2.0.0 after merge → publish workflow fires (PyPI trusted publishing)

Coordinated release

Plan doc: core/internal_docs/wallet-auth-hardening-plan.md.

Sibling PRs: node-sdk #21 (mirror), mcp #24, martin-estate #44, core #190. Merge order: this + node-sdk + core land first → publish → commerce 1.0.0 publishes → mcp + martin-estate auto-clear.

🤖 Generated with Claude Code

vvillait88 and others added 28 commits April 23, 2026 18:38
Mirror of node-sdk 1.9.0 type additions for python-sdk:

- DenialCode Literal includes wallet_signer_mismatch,
  wallet_auth_requires_wallet_signing (TEC-226) + token_expired,
  token_revoked (TEC-218); existing codes preserved
- NextStepsAction Literal includes send_existing_identity,
  mint_new_credential, use_operator_token,
  regenerate_payment_from_linked_wallet
- WalletSignerMismatchBody, WalletAuthRequiresSigningBody
  TypedDicts for TEC-226 denial shapes
- AgentMemoryHint + AgentMemoryIdentityPaths for TEC-227
- SessionCreateResponse gains optional agent_memory

Pure type surface; no runtime behavior change. Bumps to 1.9.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of node-sdk — python TypedDict gains optional linked_wallets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Strip ticket IDs and version-introduction annotations from comments.
- CredentialCreateResponse.expires_at is always present post-mint — mark
  it required (not `str | None`). Add optional `agent_memory` field so
  the type matches the API's first-credential emission behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tier A = published libraries on the critical path; uniform bar is 95. Actual
coverage is already 98.14%, bump codifies the new floor.

See MEMORY/feedback_coverage_standards.md for the full tier table.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Identity-model section now calls out linked_wallets[] +
resolved_operator on assess responses, agent_memory on create_session
and create_credential responses, and the next_steps.action enum on
poll_session — so future sessions start with an accurate mental
model of each method's response shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gate-emitted denials now ship these action codes inside agent_instructions:
probe_identity_then_session, resign_or_switch_to_operator_token,
switch_to_operator_token, and deliver_verify_url_and_poll (POST /v1/sessions).
Add them to the NextStepsAction Literal plus the GET-poll session state
actions so typed Python agents see recognized enum members.

Drop the stale send_existing_identity (never implemented server-side; the
current contract is probe_identity_then_session).

Test: test_types.py asserts the new values are present in get_args output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
revoke_credential and arevoke_credential were typed as -> dict, which node-sdk
types as CredentialRevokeResponse ({ id, revoked: true }). Adds the TypedDict
to agentscore/types.py, exports it from the public __init__.py, and tightens
the return annotations. Type checkers (ty, mypy) can now enforce the response
shape where previously they saw an opaque dict.

Also enrich README with wallet resolution section (resolved_operator +
linked_wallets) and mention that create_session responses carry structured
next_steps + agent_memory.

No runtime behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…shapes

Mirror of node-sdk fix. WalletSignerMismatchBody and WalletAuthRequiresSigningBody
required next_steps with a locked-literal action, which only covered the
merchant-override shape. Gate-default merchants emit agent_instructions
(JSON string) instead.

Update both:
- next_steps no longer required; action broadened from Literal to
  NextStepsAction.
- Add optional agent_instructions: str.

Also add SessionCreateNextSteps TypedDict and thread it through
SessionCreateResponse so POST /v1/sessions' structured next_steps
(action=deliver_verify_url_and_poll, poll_interval_seconds, steps)
is visible in the typed response.

Tighten SessionPollNextSteps.action from str to NextStepsAction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four concrete divergences found in the symmetry audit, now closed:

1. AssociateWalletResponse.agent_memory — mirror of node-sdk fix. API emits
   agent_memory on first wallet capture; SDK now surfaces it as optional.

2. AssessResponse.identity_method typed as Literal["wallet",
   "operator_token"] — was loose str. Matches node-sdk's union.

3. AccountVerification TypedDict added and wired into
   CredentialListResponse.account_verification — was NotRequired[dict] with
   zero type safety. node-sdk had a typed AccountVerification interface;
   now python does too.

4. CredentialCreateErrorResponse added — typed 409 response for KYC-required
   credential mints. node-sdk had this; python was missing it. Exported
   from agentscore namespace.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ain)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of node-sdk. API unifies revoked + TTL-expired under token_expired
to avoid leaking revoke intent. SDK Literal reflects the unified set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror of node-sdk. API no longer emits this action; token_expired now
points to deliver_verify_url_and_poll (auto-session in 401 body).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-uv v7→v8.1.0, drop || true

Mirrors the cleanup landed in agentscore/pay (commit 8c3be79):

- actions/cache@v5: Node 24 runtime, satisfied by GitHub-hosted +
  Blacksmith runners.
- osv-scanner v2.3.5: 3 patch releases; switched to `scan source`
  subcommand syntax.
- astral-sh/setup-uv@v8.1.0: pinned to exact tag because v8.x stops
  publishing floating major/minor tags as a supply-chain hardening
  measure (per the v8.0.0 release notes).
- Removed `|| true` after osv-scanner and pip-audit. Verified locally
  every lockfile here returns 0 issues, so CI passes today.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…are ARM)

The previous _linux_amd64 download silently exec-failed; the prior
`|| true` masked it. Now that the swallow is removed, the architecture
mismatch surfaces. Blacksmith pool is ARM, osv-scanner publishes both
_amd64 and _arm64 binaries — switching to the right one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…de-sdk

Adds _send_sync / _send_async wrappers that wrap every method (sync + async,
8 each). On 429 they sleep retry-after seconds (capped at 10s, default 1s)
and re-issue the request once before raising. Matches node-sdk semantics so
multi-language agents see the same rate-limit recovery behavior.

Tests cover both paths: retry-then-success, retry-also-429-then-raise,
default-wait-when-retry-after-missing, and the 10s cap on excessive values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes audit items #12, #17.

verify_webhook_signature: generic HMAC-SHA256 webhook signature verifier,
Stripe-pattern (`t=<unix>,v1=<hex>` header). Useful both when AgentScore
eventually ships outbound webhooks and as a generic helper for merchants
verifying any HMAC-signed webhook source.

Returns VerifyWebhookSignatureResult with `reason` set on failure
(no_signatures / no_timestamp / timestamp_too_old / timestamp_in_future /
signature_mismatch / malformed_header) so callers can differentiate
transient vs permanent failures. Uses hmac.compare_digest for
constant-time comparison.

AgentScoreError.status property mirrors .status_code — polyglot codebases
can use err.status regardless of which SDK raised the error. Both
attributes return the same int.

11 new tests; coverage holds at 97.30% (Tier A).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors core/docs/integrations/python.mdx additions so README readers see
the helper alongside the existing AgentScore API methods. Also documents
the AgentScoreError.status property aliasing .status_code for polyglot
codebase parity with node-sdk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Python parity with the test-mode helper currently shipping in @agent-score/pay
and @agent-score/mcp. Recognizes the seven reserved AgentScore EVM test
fixtures (0x0000…0001 through 0x0000…0007) so dev/test interactions can be
labeled distinctly without burning real KYC credits.

Lives in agentscore.test_mode and is re-exported from the package root.

6 new tests, coverage holds at 97.35%.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Run ruff format to satisfy CI's format-check step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
uv has no equivalent of npm's \`prepare\` lifecycle, so contributors still
need to run \`uv run lefthook install\` once after \`uv sync\`. Documented
in CLAUDE.md alongside the other setup commands. Adding the PyPI wheel to
dev deps means the binary is fetched as part of the standard sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pulled in via \`uv sync --upgrade\`. No direct deps changed; all production
+ dev deps were already at the latest in-range version. Tests + 97.35%
coverage stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…identity hints on create_session

Python parity with the same node-sdk additions (commit 75ba394 in node-sdk).
Two non-breaking surface extensions:

1. AgentScoreError grows a ``details: dict[str, Any]`` field populated from
   non-``error`` keys of the response body. Consumers can branch on
   ``verify_url``, ``linked_wallets``, ``claimed_operator``, ``actual_signer``,
   ``reasons``, etc. for granular denial recovery — previously the SDK
   dropped them and only surfaced ``code`` + ``message``. Defaults to ``{}``
   so existing constructor calls keep working.

2. ``create_session`` / ``acreate_session`` accept optional ``address`` +
   ``operator_token`` so a session can be pre-associated with a known wallet
   or be a KYC refresh for an existing ``opc_...``. The ``/v1/sessions`` API
   has accepted these all along; the SDK was just not forwarding them.

Coverage stays at 97.41% (Tier A bar 95%). 146 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the node-sdk drop. Removes the speculative HMAC-SHA256 webhook verifier:
- agentscore/webhooks.py — deleted
- tests/test_webhooks.py — deleted
- agentscore/__init__.py — exports removed
- README.md — webhook section scrubbed

Same rationale as the node side (commit will reference the node-sdk hash):
zero outbound webhook emitter in core/api, zero internal consumers, no API
endpoint signs anything. The only inbound-webhook handler is the Stripe
Identity flow in core/website (uses stripe SDK, not this lib).

When AgentScore ships outbound events later, the right move is the official
``standardwebhooks`` PyPI lib (Svix interop spec) rather than re-rolling.

Coverage stays at 98.16% (Tier A bar 95%).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ity hints

Mirrors node-sdk doc additions. Both were already shipped in code (e.code +
e.details, create_session(address=..., operator_token=...)) but missing
from the README.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Parity with node-sdk@2.0.0. Same reasoning: wallet-auth-hardening line
includes breaking removals (verify_webhook_signature gone), so 2.0.0 is
honest semver.

Backward-compat test comments scrubbed of the 1.9.0 reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vvillait88 vvillait88 changed the title 1.9.0 — wallet-auth hardening types (signer binding + granular denials + agent_memory) 2.0.0 — wallet-auth hardening types (signer binding + granular denials + agent_memory) Apr 27, 2026
@vvillait88 vvillait88 changed the title 2.0.0 — wallet-auth hardening types (signer binding + granular denials + agent_memory) 2.0.0 — wallet-auth types + AgentScoreError.details + create_session args + drop verify_webhook_signature Apr 27, 2026
vvillait88 and others added 2 commits April 27, 2026 03:06
Three comments referenced "mirrors node-sdk's behavior" / "mirrors node-sdk's AgentScoreError.details". Rephrased to describe the behavior on its own — python-sdk stands alone as the Python flavor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vvillait88 vvillait88 merged commit 09a9d68 into main Apr 29, 2026
6 checks passed
@vvillait88 vvillait88 deleted the wallet-auth-hardening branch April 29, 2026 11:57
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