Client lifecycle
- Create one
PraxaClientper Gateway configuration and reuse it. - Keep the client in a trusted server process, not a browser or mobile bundle.
- Supply a renewable token function rather than freezing one access token for the process lifetime.
- Reject a non-HTTPS Gateway origin and keep staging and production origins explicit.
- Bound attempts, per-request time, total operation time, and application concurrency independently.
Authentication and tenancy
- Request only the OAuth scopes needed by the operation.
- Derive tenant and principal from the authenticated application session.
- Never accept a tenant, owner, purpose, or scope assertion from an untrusted request body.
- Refresh an expired token once through the reviewed token broker; do not loop
indefinitely on
401. - Exercise revoked, under-scoped, and foreign-tenant cases before release.
Replay-safe mutations
Create the idempotency key when the user or job commits the logical action. Persist it with a digest of the exact request body and reuse both after an ambiguous failure.
Do not generate a fresh key inside a generic retry callback. That turns one
logical operation into multiple mutations.
Events and terminal state
- Persist an SSE event before advancing its cursor.
- Deduplicate by event identity or sequence, not payload text.
- Resume with the last durably processed event ID.
- Reconcile with
getMission()after reconnect, timeout, or cancellation. - Treat create responses and progress events as intermediate evidence.
- Branch explicitly on every terminal state, including unknown or failed outcomes represented by your application.
Agent tools
- Build tools from package-owned definitions rather than copying schemas.
- Filter registration by granted scope and product policy.
- Keep approval before the committing tool call.
- Bind execution to the same
PraxaClientand principal context used for authorization. - Return customer-safe tool results to the model; keep raw errors and secrets out of prompts.
- Test direct tool invocation as well as model-selected invocation.
Memory federation
- Instantiate provider clients in the backend and pass them to
@praxa/sdk/memoryadapters. - Provide explicit tenant and subject namespace resolution.
- Keep the provider capability read-only; no provider write path exists in the package.
- Inspect aggregate
ok,partial, orfailedstatus and each source status. - Preserve provenance and contradictions for caller policy.
- Exclude checkpoints and other execution state from portable memory kinds.
Observability
Record safe correlation data:- application request ID;
- hashed idempotency identity;
- run ID and event cursor;
- route operation ID;
- HTTP status and problem code;
- attempt count and bounded latency; and
- installed package and contract fingerprint.
Upgrades
- Pin the package version and lockfile.
- Assert
PRAXA_CONTRACT_VERSION,PRAXA_OPENAPI_VERSION, andPRAXA_OPENAPI_SHA256in CI. - Review route, schema, retry, and event changes.
- Run fake-transport contract tests.
- Run negative authorization and replay tests in staging.
- Exercise a disposable live mission and terminal readback.
- Roll out gradually with a documented package rollback.
Production checklist
Turn these practices into a release gate with automated and live evidence.
SDK troubleshooting
Diagnose configuration, auth, retry, conflict, stream, and contract drift.