ADR-0157: metadata-generated typed module data SDK - #412
Open
nikstern wants to merge 1 commit into
Open
Conversation
nikstern
marked this pull request as ready for review
July 24, 2026 20:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ADR-0099 removed the TCP hop for same-process module calls, but modules still behave like hand-written OData clients. They must:
That plumbing is repeated across modules and makes internal correctness depend on HTTP conventions.
Decision
Generate a typed SDK for each WASM module from the exact CSDL and IOA metadata that Temper verifies and deploys. The generated SDK calls a direct, versioned WASM host ABI instead of loopback OData.
OData remains the public external API. Both OData handlers and the generated SDK call the same governed application service, so Cedar authorization, transition verification, guards, relations, persistence, projections, audit events, and tenant isolation stay on one path.
Illustrative change:
Generated application code does not construct URLs, headers, OData envelopes, or status-code policies.
Concrete v1 contract
Build and schema binding
Least-privilege module grants
Each app.toml WASM module declaration lists its allowed operations, entities, actions, query fields, File operations, and budgets. Trigger declarations may select a module but cannot widen its grant.
The generator emits only the granted methods, and the host checks the same grant again at runtime.
Authorization
Tenant, principal, module identity, and capability grants live in a host-only invocation snapshot. They are never accepted from guest parameters or headers.
External callers retain their resolved Cedar principal. Internal workflows must explicitly use a named service principal. Missing authority fails closed rather than becoming system access.
Reads and writes
Successful writes return a per-entity commit token containing the committed sequence. A later keyed read can require at least that sequence.
The server either:
Neither the server nor generated SDK polls or sleeps waiting for projection catch-up.
Structured errors
SDK calls return typed errors such as:
Only the OData adapter maps these errors to HTTP status codes.
Batches and files
What does not change
Rollout
Important tradeoffs
Validation