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
ContextDB advises. The customer host enforces authorization, the decision outcome, and the final write to the system of record.

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_id is 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 ask or abstain and mutate only on act.

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.