Worked example · one request, every layer

Follow one sentence all the way to a result.

Everything above this page describes the pipeline in the abstract. This page runs one concrete request through it, layer by layer, so you can see exactly what data exists at each stage — and exactly where authorization is checked.

Want to run this instead of reading it? The exact "top supplier" request on this page — plus the case where candidates tie and Foundgine asks the agent to choose instead of guessing — is wired into a reproducible, seeded benchmark against a real PostgreSQL database: see the Supply Chain E2E page for the working code.

The request

"Show me overdue purchase orders from our top supplier in Texas, and how many days late each one is."

This sentence is typed by a purchasing manager into an AI agent connected to a Supply Chain application through Foundgine.MCP. It is deliberately imprecise: "top supplier" is not a database key, and "overdue" is not a column. Foundgine's job is to turn that sentence into one authorized, provider-independent execution — without ever letting the model write SQL or decide what the caller is allowed to see.

DomainSupply Chain sample (PurchaseOrder, Supplier)CallerAI agent acting for a purchasing-manager user, tenant-7
123456789101112
1
Step 1 · Caller

The raw sentence arrives

Untrusted caller → Foundgine

Foundgine treats the agent exactly like an API client or a GraphQL client: an untrusted caller. Nothing about the sentence is trusted yet — not the words, not the implied filters, not the fact that it came from an internal tool.

Incoming payload
{
  "caller": "ai-agent",
  "channel": "mcp",
  "actor": { "id": "agent-42", "tenantId": "tenant-7" },
  "message": "Show me overdue purchase orders from
              our top supplier in Texas, and how many
              days late each one is."
}
Produced payload
{
  "status": "received",
  "next": "capability discovery (advisory)"
}
2
Step 2 · Intent

The model produces structured intent, not SQL

Sentence → Structured intent

The agent calls foundgine_capabilities to see what it may ask for — that description is advisory, never a credential (see AI agents). It then emits structured intent. Two words in the sentence stay unresolved on purpose: "top supplier" and "overdue" are recorded as language, not as IDs or booleans, because the model does not get to decide what those mean.

Incoming payload
{
  "capabilities": ["purchaseOrder.query", "supplier.query"]
}
Produced payload
{
  "operation": "query",
  "resource": "purchaseOrder",
  "select": ["id", "expectedDate", "receivedDate"],
  "where": { "status": "overdue" },
  "supplierRank": { "state": "TX", "rank": "top" }
}
3
Step 3 · Semantic Model

Words become application meaning

Structured intent → Semantic Model (Foundgine.Semantics)

purchaseOrder, supplier and the Supplier relationship are looked up against the application-defined semantic model, not against database tables. "overdue" is resolved here too: the model defines it as a named predicate, not something the caller can redefine.

Incoming payload
{
  "resource": "purchaseOrder",
  "relation": "supplier",
  "namedPredicate": "overdue"
}
Produced payload
{
  "resolvedModel": {
    "root": "PurchaseOrder",
    "relationship": "PurchaseOrder.Supplier",
    "predicate": "PurchaseOrder.IsOverdue",
    "fields": ["PurchaseOrder.Id",
               "PurchaseOrder.ExpectedDate",
               "PurchaseOrder.ReceivedDate"]
  }
}
4
Step 4 · Semantic Operation Graph

The request becomes one graph, including the ambiguous part

Semantic Model → Semantic Operation Graph

Foundgine builds one graph for the whole request. Because "top supplier" cannot be resolved from the semantic model alone, the graph carries an explicit candidate node that must be settled by retrieval before the rest of the graph can be authorized or planned.

Incoming payload
{
  "resolvedModel": { "root": "PurchaseOrder" },
  "supplierRank": { "state": "TX", "rank": "top" }
}
Produced payload
{
  "graph": {
    "candidateNode": "Supplier(state=TX, rank=top:1)",
    "scanNode": "PurchaseOrder(supplierId=$candidate)",
    "filterNode": "PurchaseOrder.IsOverdue"
  }
}
5
Step 5 · Retrieval

"Top supplier in Texas" gets an answer — but no authority

Candidate node → Ranked candidates + evidence

A Foundgine.Sql retrieval strategy (relational lookup, ranked by total order value) resolves the candidate node to a real supplier. This step only produces candidates and evidence. It cannot grant access to anything — the result still has to pass through resolution and authorization below.

Incoming payload
{
  "strategy": "relational",
  "filter": { "state": "TX" },
  "orderBy": "totalOrderValue desc",
  "limit": 1
}
Produced payload
{
  "candidates": [
    { "id": "sup-118", "name": "Lonestar Components",
      "totalOrderValue": 482000 }
  ],
  "evidence": { "strategy": "relational", "rank": 1 }
}
6
Step 6 · Resolution

The graph is finalized against a real target

Candidates + Semantic Operation Graph → Resolved, valid request

The candidate supplier is bound into the graph, and Foundgine validates that every field, relationship and predicate the request touches is real, typed and traversable. If "top supplier" had matched nothing, or matched ambiguously, resolution would stop here and tell the agent its own words were ambiguous — it would not guess (see Grounding decisions).

Incoming payload
{
  "candidateSupplierId": "sup-118",
  "requestedFields": ["PurchaseOrder.Id",
                       "PurchaseOrder.ExpectedDate",
                       "PurchaseOrder.ReceivedDate"]
}
Produced payload
{
  "valid": true,
  "boundSupplierId": "sup-118",
  "dependencies": ["PurchaseOrder", "Supplier"]
}
7
Step 7 · Authorization

The decision that everything downstream must honor

Resolved request → Authorized request + evidence

This is where "is this caller allowed to do this" gets answered — once, centrally, regardless of which tool or transport the agent used. Here it constrains the request to the caller's tenant and strips a field the requester's role cannot see.

Incoming payload
{
  "subject": { "id": "agent-42", "tenantId": "tenant-7",
               "role": "purchasing-viewer" },
  "requested": { "resource": "PurchaseOrder",
                 "fields": ["Id", "ExpectedDate",
                            "ReceivedDate",
                            "Supplier.NegotiatedCost"] }
}
Produced payload
{
  "decision": "allow",
  "deniedFields": ["Supplier.NegotiatedCost"],
  "constraints": [
    { "field": "PurchaseOrder.TenantId",
      "operator": "eq", "value": "tenant-7" }
  ]
}
8
Step 8 · Plan Binding

The authorization decision is welded to the plan

Authorized graph → Provider-independent plan + AuthorizationBinding

Foundgine turns the authorized graph into a logical plan that still knows nothing about PostgreSQL. Critically, the plan carries an AuthorizationBinding — a fingerprint of the step 7 decision. Any later optimization can change the plan's shape, but it cannot change what was authorized.

Incoming payload
{
  "scan": "PurchaseOrder",
  "join": { "to": "Supplier", "id": "sup-118" },
  "filters": ["PurchaseOrder.IsOverdue",
              "PurchaseOrder.TenantId = tenant-7"],
  "projection": ["Id", "ExpectedDate", "ReceivedDate"]
}
Produced payload
{
  "plan": { "scan": "PurchaseOrder",
            "supplierId": "sup-118",
            "projection": ["Id", "ExpectedDate",
                            "ReceivedDate"] },
  "authorizationBinding": {
    "fingerprint": "auth:9f21c...",
    "deniedFields": ["Supplier.NegotiatedCost"]
  }
}
9
Step 9 · Execution IR

The controlled intermediate form at the provider boundary

Bound plan → ExecutionIR

Foundgine.Execution lowers the plan into ExecutionIR: an explicit, inspectable operator tree that still carries the authorization binding forward. This is the last representation before any provider-specific syntax appears.

Incoming payload
{
  "plan": "PurchaseOrder scan + supplier=sup-118
           + tenant filter + IsOverdue",
  "authorizationBinding": "auth:9f21c..."
}
Produced payload
{
  "ir": {
    "op": "Scan", "entity": "PurchaseOrder",
    "filters": ["SupplierId = sup-118",
                "TenantId = tenant-7", "IsOverdue"],
    "project": ["Id", "ExpectedDate", "ReceivedDate"],
    "authorizationBinding": "auth:9f21c..."
  }
}
10
Step 10 · Provider

Only now does PostgreSQL enter the picture

ExecutionIR → Provider plan + security proof

Foundgine.Sql compiles the ExecutionIR into a parameterized command. Before anything runs, the final execution gate checks that the compiled plan's fingerprint still matches the AuthorizationBinding from step 8 — if authority changed in between, execution fails closed instead of running a stale decision.

Incoming payload
{
  "provider": "PostgreSQL",
  "ir": { "entity": "PurchaseOrder",
          "authorizationBinding": "auth:9f21c..." }
}
Produced payload
{
  "command": { "kind": "parameterized SQL",
    "parameters": { "supplier_0": "sup-118",
                     "tenant_0": "tenant-7" } },
  "securityProof": { "fingerprintMatches": true,
                      "gate": "passed" }
}
11
Step 11 · Execution

The database runs the command it was given

Provider plan → PostgreSQL → rows

The provider executes the parameterized command. The agent never held database credentials, never wrote SQL, and never saw a raw connection string — the only thing that crossed the boundary was the authorized, security-proofed command from step 10.

Incoming payload
{
  "parameters": { "supplier_0": "sup-118",
                   "tenant_0": "tenant-7" }
}
Produced payload
{
  "rows": [
    { "id": "po-7734", "expectedDate": "2026-08-12",
      "receivedDate": null },
    { "id": "po-7791", "expectedDate": "2026-08-20",
      "receivedDate": null }
  ]
}
12
Step 12 · Evidence

The agent gets an answer it can also verify

Rows → Caller, with evidence

The rows are shaped back into the answer (days-late computed from expectedDate), and returned together with execution evidence: what was authorized, which fields were denied, which provider ran it, and how many rows came back. The agent can now answer in plain language — but everything it says is traceable back to one authorization decision.

Incoming payload
{
  "rows": 2, "authorization": "allow"
}
Produced payload
{
  "data": [
    { "id": "po-7734", "daysLate": 19 },
    { "id": "po-7791", "daysLate": 11 }
  ],
  "evidence": { "authorized": true,
    "supplier": "Lonestar Components (sup-118)",
    "deniedFields": ["Supplier.NegotiatedCost"],
    "provider": "PostgreSQL", "rowCount": 2 }
}
The key idea: the agent supplied one sentence. Foundgine supplied the meaning, the ambiguity resolution, the authorization decision and the execution — and none of those four things ever lived in the model's output. Change the caller to an API client or a GraphQL client and steps 1–2 change shape; steps 3–12 do not.

Where each step lives in the codebase

Steps Package
1–2 · Caller, Intent Foundgine.MCP / Foundgine.AI / Foundgine.Intent.Json
3–4 · Semantic Model, Operation Graph Foundgine.Semantics
5 · Retrieval Foundgine.Sql retrieval strategies
6–7 · Resolution, Authorization Foundgine.Semantics
8–9 · Plan Binding, Execution IR Foundgine.Planning / Foundgine.Execution
10–11 · Provider, Execution Foundgine.Sql / Foundgine.InMemory
12 · Evidence Foundgine.Execution

This is one instance of the same canonical pipeline described on the Architecture page — see the full canonical architecture diagram there for the general-case shape, including parallel retrieval strategies.

Next

Read AI agents for the general boundary this example lives inside, or Security for how authorization and provider conformance are enforced. See this exact "top supplier" case wired into a reproducible, seeded benchmark — including the case where candidates tie and Foundgine asks the agent to choose instead of guessing — on the Supply Chain E2E page.