Migration
What to change when you upgrade across a release that breaks the API. The SDKs keep no compatibility shims: an old shape is refused, not translated. Each section names the release that introduced the change; the changelog has the full list.
0.9 โ 0.10โ
A security review of both SDKs changed these contracts:
AccountDirectory.authenticate(credentials, context)takes aSignInContext(client_id,session_id;clientId,sessionIdin TypeScript). The company limits Mediated Sign-In attempts itself; a directory must also throttle its own checks.CompanyConfigwithoperationsneedswrite_scopes(amongscopes): without one it raises. Setoperations=Falsefor a company without Operations. An operation records the scopes confirming it requires (ProposedOperation.scopes, elsewrite_scopes).Turn.supports_operations(supportsOperations) says whether the agent negotiated Operations; a company agent must not promise an operation to one that did not.- The default
pap.company.replayCacheisStoreReplayCache(idstore), in the company store. A contributed store must accept thereplayandsign_in_attemptskinds (check_store/checkStorechecks them).createCompanyDefaultsPluginandCompanyDefaultsPlugintake the store to use. - Stored records changed: operations keep
scopes, Mediated sign-insattempt_keys. Records written by 0.9 are refused, not translated: drain pending sign-ins and proposals before upgrading. - The web cookie is
__Host-poppy_session. Browsers holding the oldpoppy_sessionopen the page again from the agent. - TypeScript
./server:isPublicIpAddressisisGlobalAddress;createResolvingFetchis the Node company's defaultfetch. - Assertions live at most 120 seconds and carry a
jtiof at least 16 characters (DPoP proofs too); theiraudmay be the issuer, the token endpoint, or the endpoint called. - Conversations frame each agent reply with
workingandidlestate events: read the last message orauthorizationevent, not the last event. - An operation past
proposedhas noexpires_atmember (nevernull). pap operations approvetakes the user's answer at a terminal or from the host'spap.approvalSurface, never piped input; approvals stored by 0.9 are refused atconfirm: approve again.
0.8 โ 0.9โ
- Removed contribution points that nothing used.
pap.protocolProfile(PROTOCOL_PROFILES,ProtocolProfile/ProtocolProfiles),pap.extensionHandler(EXTENSION_HANDLERS/ExtensionHandlers,ExtensionHandler), andpap.keyStore(KEY_STORES/KeyStores,KeyStore,KeyReference) are gone: no SDK code ever read them. Read the draft the SDK implements fromPROTOCOL_PROFILE,PROTOCOL_REVISIONandOPERATIONS_VERSION; negotiate extensions withnegotiate_extensions/negotiateExtensions; keep keys behind yourpap.signerandpap.dpopProofProvider. A host that contributed to a removed point contributes nothing in its place. - Optional points fail closed on ambiguity. The cache, clock, random
source, retry policy and rate-limit budget where the SDK can do without
them, and the company's
pap.company.apiandpap.company.mcp, now refuse two contributions at the same winning order (ambiguous โฆ contributions), as every other point does. Give your replacement a lowerorderthan the default (100).optional_contribution/optionalContributionresolve such a point. - Operation executors replace by order. For one action, the
lowest-order
pap.company.operationExecutorperforms it; two at that order leave the operationin_progress. Before, any second executor for an action did. - TypeScript company: Bearer tokens and MCP. The TypeScript reference
company now serves
pap.company.mcp(CompanyMcps,CompanyMcp,ToolResult,ToolResults) at/mcpwith Bearer Session Tokens, as the Python one does.IssuedSessionrecords carrytokenType(Bearer, absent for DPoP), and a Session keeps its DPoP and Bearer tokens side by side. - TypeScript company: renewal with the assertion is signed out. A Session renewed with the Session assertion gets a signed-out token, as in Python and ยง4.2; a signed-in Session is renewed with its Account Token.
0.7 โ 0.8โ
MemoryReplayCachetakes the company's clock and forgets expired identifiers; the verifiers now remember a DPoP proof until itsiatleaves the acceptance window and an assertion untilexpplus the 30-second skew. A replay cache of your own must keep identifiers at least as long as theexpires_atit is given.check_replay_cache/checkReplayCachecheck it.SharedRateLimitBudgetrefuses a turn beyondmax_waitat once withrate_limitedinstead of queueing past it.- The built-in consent page binds the browser: read the user's decision with
CompanyService.consent_decision(request)(consentDecision), which accepts only a same-origin POST carrying the page's cookie and token.
0.6 โ 0.7โ
Nothing breaks. personal_agent_protocol.ui.PapSignIn needs
datalayer_reactor 1.1, through the new ui extra.
0.5 โ 0.6โ
- The company store is an async keyed store.
pap.company.storeholds versioned JSON records:get,put,create(only if absent),replace(compare-and-set on a version),take(read and delete at once), anddelete, each by kind and key with an optional expiry. The dict-of-recordsCompanyStore(Maps in TypeScript) is gone: port a database store to these six operations and runcheck_store/checkStoreagainst it. - Company methods are async.
approve_device,deny_device,approve_authorization,deny_authorization,authorization_request,revise,settle,forget_events, anddisconnect(and their TypeScript names) return coroutines or promises: await them. Read an operation as the company keeps it withoperation_record(operationRecord); the in-memoryCompanyService.extensionsmap is gone.
0.4 โ 0.5โ
- Direct Sign-In keeps the Account Token in
pap.tokenStore. The result's token no longer carriesrefresh_token; readaccount_token_reference(accountTokenReference) and use it withAccountTokenClient, as for Device and Mediated Sign-In. - TypeScript Session, conversation and operation errors carry a 429's
Retry-Afterasdetails.retry_after(Sessions usedretryAfter).