Agent docs

Consuming a module from an app

What a request for "call module X from our app" brings along: identity, the tenant, the job…

What a request for "call module X from our app" brings along: identity, the tenant, the job envelope, reading back, learning about changes, and what to keep on the app's side. Written for the console, walmart-mvp, speedway, and App V5 alike, since the contract's promise is that they all do it the same way.

Audience: an agent or a person wiring an app to a module, on any cloud.

What the app brings along#

  1. A client credential per environment at the issuer, with the tenants it may act for and the scopes it needs. The app exchanges it for a short-lived token and never forwards a user's session or JWT (../canon/02-identity-and-tenancy.md). Until the issuer exists, a per-module key with the same request shape.
  2. A tenant on every request, from the app's own org or workspace model. walmart's X-Org-Id validated against membership, speedway's workspace scoping, are exactly the source; the app puts it on the request as X-Tenant-Id.
  3. A callback receiver if it does not want to poll: one route, verifies the HMAC signature, dedups on the event id, and is idempotent (../contracts/module-surface.md, "Callback events"). Plus a reconciliation sweep that lists open jobs from the module by state, so a lost callback is a delay.
  4. A read of the manifest at integration time (and cached at runtime), to validate what it sends, generate the capability's settings UI from params, and build each item's input against item.

Submitting#

Build the job envelope from the app's own records: client_job_id set to the app's id for this work (a workflow run and stage, a Firestore run doc id, a Postgres job id) so the create is idempotent and the app can join outcomes back without a lookup table; item_id set to the app's item ids for the same reason; attribution carrying the user and the workflow run; callback_url and callback_events in settings if the app has a receiver. The app's store stays the truth for its UI; the module's store is the truth for module-side outcomes; the ids are the join (../canon/03-jobs-and-state.md, "Caller-owned, module-mirrored").

Submit is O(1) and returns accepted or expanding; the app shows that state rather than running.

Reading back#

  • Status and counts for the progress UI, polled or pushed.
  • Outcomes paginated by type: results to write into the app's records, errors to show, needs_review items to put in the app's queue with the reason and evidence, skipped to note.
  • The per-item log route for the detail page a person opens when one item looks wrong; no shell, no bucket.
  • Stats for the job page: throughput, ETA, error breakdown, cost.
  • Usage events (or the stats rollup) for credits.

The app's own side#

  • The customer's bar over confidence and judged_by; holding an item the module called done is the app's call (../canon/10-human-in-the-loop.md).
  • The review queue, resolution, waive, and the teaching loop.
  • Re-submitting resolved items as a new job with parent_job_id.
  • Plans, credits, and enforcement before submit; the module only enforces hard ceilings.
  • Per-tenant configuration passed as params and item fields, never stored in the module.
  • Which variant to ask for per tenant (settings), when the manifest offers a choice.

Local development of the app#

The module runs in-process or as a local process with zero env (../canon/13-local-dev-and-debugging.md); the app points at localhost with the local verifier's static token, and nothing in the app's integration changes between local and prod except the base URL and the credential.

Do-nots#

  • Do not forward a user's credential to a module. Exchange the app's own.
  • Do not submit without a tenant, or with a tenant the app has not verified the user belongs to.
  • Do not invent a mapping table between app ids and module ids; pass the app's ids as client_job_id and item_id.
  • Do not show running for an accepted job.
  • Do not treat a callback as the only signal; sweep.
  • Do not put the customer's bar or per-tenant config in the module.
@versable-git/ui · reference, canon, and method, read in place