Executable contract-first for agent-built APIs
AI can generate code. The hard part is proving everyone is still building the same thing.
The contract is that proof — reviewed before code, re-run after launch.
Intent → decisions → executable contract → implementation → evidence
01
Intent
What the team is trying to build.
02
Decisions
Auth, status codes, state rules, error behavior.
03
Executable contract
The agreement captured as runnable cases.
04
Implementation
The agent builds against the confirmed boundary.
05
Evidence
CI and Cloud keep checking the agreement still holds.
The contract is not a second spec. It is the agreement your team reviews, the boundary your agent builds against, and the evidence CI keeps checking.
A reviewer asking 'can a viewer do this?' turns into a case in the file — not a comment that gets lost.
Red before the API exists, green as it lands, then re-run on every commit. One file, before and after launch.
Each run feeds a readable projection and Cloud history, so you can show the agreement still holds.
Why executable matters
It is agreement first, regression suite second — the same file before the API exists and long after launch.
Project rules
Business rules, role boundaries, and state semantics that span the whole API. Written once in GLUBEAN.md, referenced by every contract.
Generated projection
A dated report regenerated from the contracts — covered, deferred, and missing cases at a glance. Reviewers read it; nobody maintains it by hand.
Why it holds
Because the contract runs, a stale agreement turns red instead of staying convincing on paper — and there is no second spec to forget to update.
Worked example: team invites
The contract turns ambiguous review comments into recorded decisions, then keeps checking them after launch.
Reviewer
The case list
Reads the decisions the agent recorded — 201 / 409 / 403 laid out as cases, plus the generated surface report. Confirms what was decided, not how the agent got there.
Agent
The executable contract
Implements against the confirmed boundary instead of re-deriving intent from a prompt. Runs red until the endpoint lands, then green.
CI + Cloud
The run history
Runs the same contract on every commit and preserves the history — so a case that breaks in production shows up next to the one that broke in staging.
From ambiguity to decisions
Can a viewer invite? Does a duplicate overwrite or 409? Is an expired token 400, 404, or 410? Before code, the fuzzy questions get answered — and the answers become the rules below.
Example: team invites
Only admin may create team invites.
Invite states are pending, accepted, expired, and revoked.
Duplicate pending invite for the same email returns 409.
Expired invite token returns 410.
Build against the contract
Implementation no longer guesses from prompts. It lines up with the endpoint and lifecycle rules already declared in code.
POST /team/invites → 201 with { id, email, role, state: 'pending', expiresAt } when called with an admin key.
POST /team/invites → 409 when a pending invite for the same email already exists.
POST /team/invites → 403 when the client holds a viewer-scoped key.
After launch: a drift detector for intent
The contract does not disappear once the API works. It keeps proving the agreement still holds — and when something breaks, Cloud shows which agreement failed, not just which test turned red.
`glubean run contracts/` is your regression suite — the same file that started red on day one.
`glubean projection` regenerates the surface report on every commit, so it never lies.
When staging or production breaks, Cloud shows which agreement failed — not just which test turned red.
Executable contracts and readable projection
The agreement lives in code as artifacts you can run: project-level business rules in GLUBEAN.md, shared schemas and clients, executable contracts, and a projection the CLI regenerates into readable surface maps.
Contract artifacts
This is a representative slice, not the full contract surface. Real API suites usually add more contract files, flow verification, and richer projection output over time.
import { contract } from "@glubean/sdk";
import { teamApi, viewerTeamApi } from "../config/team";
import { InviteSchema } from "../schemas/team";
// Scoped instance: inject the admin client + declare the auth scheme once.
const adminTeam = contract.http.with("team-admin", {
client: teamApi,
security: "bearer",
});
export const inviteMember = adminTeam("invite-member", {
description: "Team invites must stay explicit about role rules and token state.",
endpoint: "POST /team/invites",
cases: {
created: {
description: "admin can invite a member by email",
request: {
body: { email: "new@example.com", role: "member" },
},
expect: {
status: 201,
schema: InviteSchema,
},
},
duplicatePending: {
description: "duplicate pending invite returns 409",
request: {
body: { email: "existing@example.com", role: "member" },
},
expect: { status: 409 },
},
viewerBlocked: {
// Per-case client override proves the viewer key is rejected.
description: "viewer key cannot create invites",
client: viewerTeamApi,
request: {
body: { email: "new@example.com", role: "member" },
},
expect: { status: 403 },
},
},
});contract.http.with() creates a scoped instance that injects the admin client and auth scheme once; each case is a recorded decision the agent must implement against.
What this is not
Not docs plus generated code plus hand-written tests. One executable boundary replaces the drift.
Not a product/ or docs/ folder that drifts from the real API within a sprint.
Not a Postman collection living outside version control and outside code review.
Not prompt-only generation where next week's agent re-derives coverage from scratch.