Parent: #452
Two paired changes that together unlock principal-keyed account governance.
(a) Account v3 wire fields
Extend the SDK's Account shape to carry:
setup (pending_approval lifecycle): {url?, message, expires_at?}
governance_agents
account_scope: operator | brand | operator_brand | agent
payment_terms
credit_limit
rate_card
to_wire_account() projection strips billing_entity.bank (write-only on emit).
Already partially present; finish.
(b) AccountStore.upsert(ctx) / list(ctx) / sync_governance(ctx)
Pass ResolveContext (auth_info, tool_name, agent) to upsert and list per JS account-store-upsert-list-ctx.md.
Promote sync_governance to typed AccountStore.sync_governance(entries, ctx) with framework-side credential write-only-strip on emit (per JS account-store-sync-governance.md). Specifically: governance_agents[i].authentication.credentials is stripped on the way out.
Why this matters
Security-relevant: enables principal-keyed gates for BILLING_NOT_PERMITTED_FOR_AGENT per #449's spec. Pre-this, no way to scope accounts.list per-principal — implementations either over-disclose or reject.
It's also the dependency #5 (create_tenant_store) needs to bake a per-entry tenant gate into the framework.
JS source
.changeset/account-store-upsert-list-ctx.md and .changeset/account-store-sync-governance.md (6.7).
Acceptance criteria
Account shape extensions with Pydantic models for setup, governance_agents, account_scope, payment_terms, credit_limit, rate_card.
to_wire_account() strips billing_entity.bank.
AccountStore.upsert, AccountStore.list, AccountStore.sync_governance all receive ResolveContext as a typed parameter.
- Credential-strip on
sync_governance emit covered by tests.
- Tests for each new wire field round-tripping through validation.
Parent: #452
Two paired changes that together unlock principal-keyed account governance.
(a) Account v3 wire fields
Extend the SDK's
Accountshape to carry:setup(pending_approval lifecycle):{url?, message, expires_at?}governance_agentsaccount_scope:operator | brand | operator_brand | agentpayment_termscredit_limitrate_cardto_wire_account()projection stripsbilling_entity.bank(write-only on emit).Already partially present; finish.
(b) AccountStore.upsert(ctx) / list(ctx) / sync_governance(ctx)
Pass
ResolveContext(auth_info, tool_name, agent) toupsertandlistper JSaccount-store-upsert-list-ctx.md.Promote
sync_governanceto typedAccountStore.sync_governance(entries, ctx)with framework-side credential write-only-strip on emit (per JSaccount-store-sync-governance.md). Specifically:governance_agents[i].authentication.credentialsis stripped on the way out.Why this matters
Security-relevant: enables principal-keyed gates for
BILLING_NOT_PERMITTED_FOR_AGENTper #449's spec. Pre-this, no way to scopeaccounts.listper-principal — implementations either over-disclose or reject.It's also the dependency #5 (
create_tenant_store) needs to bake a per-entry tenant gate into the framework.JS source
.changeset/account-store-upsert-list-ctx.mdand.changeset/account-store-sync-governance.md(6.7).Acceptance criteria
Accountshape extensions with Pydantic models forsetup,governance_agents,account_scope,payment_terms,credit_limit,rate_card.to_wire_account()stripsbilling_entity.bank.AccountStore.upsert,AccountStore.list,AccountStore.sync_governanceall receiveResolveContextas a typed parameter.sync_governanceemit covered by tests.