Datafied AI · Built on Aquameta · PostgreSQL-native

Your AI agents
need a data model.

Not a dashboard. Not a log file. A data model.

Every AI interaction — prompt, response, tool call, side effect — is a first-class immutable record in your PostgreSQL database. The audit trail is a JOIN. Authorization is a policy row. The causal chain from session to changed row is one query.

Built on Aquameta — the all-database platform where everything is data.

Get early access Aquameta open source ↗
The problem
Today — AI governance is bolted on
  • Audit trail spans five dashboards, none joinable
  • "What did the agent do?" requires log correlation
  • Tool calls execute before evidence exists
  • Context assembly is a black box
  • State lives in the provider's threads and vector stores
  • Switching providers means migrating proprietary data
  • Identity is application-layer, not enforced by the engine
Aquameta.ai — governance inside the transaction
  • Causal chain is one SQL query across your own database
  • Every prompt, tool call, and effect is a row
  • Evidence commits atomically with the state transition
  • Context assembly is a versioned SQL function
  • All state lives in your PostgreSQL — providers are compute
  • Swap providers by changing one row in ai.agent
  • Identity is current_user — enforced by the engine
The audit trail
psql aquameta — ai.causal_chain
-- Who initiated it, what model decided, what tool ran, what changed. -- One query. No external system.
aquameta=# select
    pi.role_name                         -- identity: PostgreSQL role, not an app token
    p.model,                            -- which LLM made the decision
    az.authorized,                     -- was it within policy at the time
    tc.tool_name, tc.arguments,         -- what the model requested
    e.op, e.row_id                     -- what actually changed in the database
from  ai.effect                    e
join  ai.tool_call                tc  on tc.id        = e.tool_call_id
join  ai.response                 r   on r.id         = tc.response_id
join  ai.prompt                   p   on p.id         = r.prompt_id
join  ai.prompt_identity          pi  on pi.prompt_id  = p.id
join  ai.authorization_snapshot   az  on az.prompt_id  = p.id
where pi.initiated_at > now() - '7 days'::interval
order by pi.initiated_at desc;

role_name | model | auth | tool_name | op | row_id -----------+-------------------+------+---------------+--------+-------------------- alice | claude-sonnet-4-6 | t | execute_sql | insert | widget.widget/ae3f alice | claude-sonnet-4-6 | t | bundle_commit | update | bundle.commit/91cc bob | claude-sonnet-4-6 | f | drop_table | — | (denied, no effect) (3 rows)
aquameta=#
How it works
01 — IDENTITY

Identity is current_user

Every AI interaction is bound to a PostgreSQL role at insert time via column default — not an application parameter, not a token, not a claim. It cannot be spoofed. RLS policies apply automatically. No separate identity fabric required.

02 — AUTHORIZATION

Policy is a row

Allow/deny matrices for providers, tool sets, and individual tools live in tables. Authorization decisions are snapshotted at evaluation time — including the exact policy rows that drove the decision. Future policy changes don't rewrite history.

03 — EVIDENCE

Evidence commits with the action

Tool executions record their effects atomically. If the evidence can't be written, the action doesn't happen. The causal chain — session → prompt → response → tool call → row change — is a view, not a reconstruction across five log sources.

04 — CONTEXT

The prompt is a compiled view

Context assembly is a versioned SQL function over your own governed data — memory, RAG, conversation history, workflow state. Every block that reached the model is recorded with its permission basis. "What did the agent see?" is a query, not a guess.

The LLM is a compute utility.
Aquameta owns the state.

Provider-managed threads, vector stores, and assistant definitions are convenient today and a moat tomorrow. When your audit trail lives in OpenAI's infrastructure, you have a dashboard, not ownership. When your embeddings live in a proprietary vector store, switching providers means a migration from a system with no standard export format.

Aquameta's position: use the primitive API — a messages array in, a completion out. All context assembly, memory, tool execution, and state management happens in your PostgreSQL. The LLM is interchangeable. Your data model is the platform.

Foundation

Aquameta.ai is built on Aquameta — the open source all-database platform where schema, code, UI, and version control are all rows in PostgreSQL. The same primitives that make UI components queryable make AI interactions auditable. meta.row_id, bundle VCS, RLS-as-identity — the governance layer is a natural extension of the platform, not a bolt-on.

aquameta.org