ContextDB with Postgres, Supabase, or Hasura
ContextDB complements Postgres, Supabase, and Hasura. It does not replace them.
Keep users, orders, inventory, balances, permissions, and final writes in your system of record. Put cross-conversation memories, evidence, action decisions, confirmations, and trust policy in ContextDB.
- SYSTEM OF RECORD
- Authoritative identity, permissions, account state, and transactions
- CONTEXTDB
- Remembered evidence, policy evaluation, decisions, and confirmations
- CUSTOMER HOST
- Authentication, authorization, decision enforcement, and final mutation
Architecture
One request reads two kinds of state.
The customer host reads current business state from the database and asks
ContextDB whether remembered evidence passes the policy for this action.
ContextDB returns act, ask, or
abstain. The host remains responsible for what happens next.
customer conversation
|
v
ContextDB memory + evidence
^
| evaluate_action
|
customer host <- act | ask | abstain
^
| current account state
|
Postgres / Supabase / Hasura
^
| host-enforced mutation
+---------------- customer host
Ownership matrix
Keep truth and remembered evidence in their proper systems.
| Object | Owner | Responsibility |
|---|---|---|
| Users, accounts, and permissions | Your database and host | Authoritative identity, authentication, authorization, and account state |
| Orders, inventory, and balances | Your database | Transactional business records and current values |
| Agent memories | ContextDB | Source, confidence, provenance, validity, and action relevance |
| Action decisions | ContextDB | Outcome, reason, policy version, and evidence IDs |
| Confirmations | ContextDB | Authenticated project credential or operator context against one scoped memory, not end-user authentication or objective truth |
| Business-action receipt | Customer host, linked to ContextDB | The host reports what it says happened in the downstream system. This is not independent proof. |
- IDENTITY BOUNDARY
-
user_idis a partition key, not authentication. The customer host authenticates the end user, authorizes the requested operation, and maps that identity to the correct ContextDB partition. - EXECUTION BOUNDARY
-
The customer host enforces the result.
ContextDB does not execute the database write. The host must stop on
askorabstainand mutate only onact.
Integration boundary
Evaluate remembered evidence before the write.
Authenticate the caller, read authoritative state, and enforce application authorization in the host. Then run the client action flow. The mutation remains below the decision branch so unresolved memory cannot update the database.
recall -> remember -> evaluate_action -> confirm if required -> re-evaluate -> host action -> report_execution
evaluate_action is the Python client method. The HTTP route
and MCP tool remain named recall_for_action.
# Host precondition: authenticate, authorize, and read current state account = postgres.get_account(account_id) host.require_authorization(actor, account, "change_renewal_date") # 1. Recall context, then 2. write one sourced durable detail await contextdb.recall(account.user_id, "renewal context") saved = await contextdb.remember( account.user_id, f"Might want renewal date {requested_date}", source="user_stated", confidence=0.4, action_relevant=True, idempotency_key=f"renewal-intent-{request_id}", ) # 3. Evaluate evidence for the proposed action decision = await contextdb.evaluate_action( account.user_id, "change the renewal date" ) # 4. If required, retain host attestation, confirm, and 5. re-evaluate if decision.outcome == "ask": attestation = await host.authenticate_and_retain_attestation(actor, account) if not attestation.explicit_yes: await contextdb.report_execution( account.user_id, decision.decision_id, "account.change_renewal_date", "skipped", idempotency_key=f"receipt-{decision.decision_id}", ) return request_confirmation() if saved.id not in decision.pending_confirmation_ids: await contextdb.report_execution( account.user_id, decision.decision_id, "account.change_renewal_date", "skipped", idempotency_key=f"receipt-{decision.decision_id}", ) return stop_and_escalate() await contextdb.confirm( account.user_id, saved.id, idempotency_key=f"confirm-{saved.id}", ) decision = await contextdb.evaluate_action( account.user_id, "change the renewal date" ) if decision.outcome != "act": await contextdb.report_execution( account.user_id, decision.decision_id, "account.change_renewal_date", "skipped", idempotency_key=f"receipt-{decision.decision_id}", ) return stop_and_escalate() # 6. Host action, then 7. report what the host observed try: change = postgres.change_renewal_date( account_id, requested_date, expected_version=account.version ) except CurrentStateChanged: await contextdb.report_execution( account.user_id, decision.decision_id, "account.change_renewal_date", "failed", idempotency_key=f"receipt-{decision.decision_id}", error_code="current_state_changed", ) raise await contextdb.report_execution( account.user_id, decision.decision_id, "account.change_renewal_date", "succeeded", idempotency_key=f"receipt-{decision.decision_id}", external_ref=change.id, )
API and MCP identify the project credential, not the end user. The customer
host authenticates that person and retains the end-user attestation before
calling confirm. ContextDB records caller and project context
against one scoped memory. It does not prove objective truth.
Add one memory decision before one database write.
Keep the current stack and test the boundary with the local SDK.