INGEST
Turn a source into screened, hashed memory with provenance.
ANTIDOTE records what your agent remembered, what it decided, and what happened next. When trust fails, you repair the influence chain instead of hiding the evidence.

The live case turns one poisoned claim into an inspectable causal map. Every node exists because the runtime recorded an influence.
EXPLORE THE LIVE CASEAgents do not act from prompts alone. They act from remembered claims. When one claim fails, deleting one row does not repair the decisions, derived memories, or external actions it already shaped. ANTIDOTE records the influence before the incident, then repairs the whole chain after it.
Route memory operations through five API steps. The agent continues to reason and act through its current framework.
Turn a source into screened, hashed memory with provenance.
Return trusted memories and record one retrieval event per hit.
Store the exact memory IDs which influenced the decision.
Attach an intended external action to its parent decision.
Preview the blast radius, then repair related state in one transaction.
If an action matters, record its parent decision. If a decision matters, record the memory IDs which shaped it. This creates the graph ANTIDOTE repairs.
Start from this repository with Node.js 22 or newer. Demo mode needs no database, cloud account, or model credentials.
npm run setup
npm run dev
# open http://localhost:3000Copies the environment template, installs dependencies, and applies migrations when a database URL exists.
Starts the Next.js application and its API routes on localhost.
Open the case map, run the autonomous demo, simulate revocation, then execute repair.
In-memory system of record, seeded incident, deterministic extraction and embeddings, no credentials.
DEMO_MODE=trueCockroachDB system of record with tenant-scoped API keys, OpenCode Go or Bedrock reasoning, S3 evidence, and read-only forensic MCP.
DEMO_MODE=falseThe repository exposes REST endpoints, an OpenAPI contract, and a buildable TypeScript SDK. Use them from a server-side agent runtime.
const baseUrl = process.env.ANTIDOTE_URL ?? "http://localhost:3000";
const apiKey = process.env.ANTIDOTE_API_KEY;
async function antidote<T>(path: string, body: unknown): Promise<T> {
const response = await fetch(`${baseUrl}${path}`, {
method: "POST",
headers: {
"content-type": "application/json",
...(apiKey ? { authorization: `Bearer ${apiKey}` } : {}),
},
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`ANTIDOTE request failed: ${response.status}`);
}
return response.json() as Promise<T>;
}
const ingested = await antidote<{
memories: Array<{ id: string }>;
}>("/api/ingest", {
sourceUri: "urn:agent:policy:payments-v3",
content: "Payments above $10,000 need two approvers.",
actor: "policy-sync",
idempotencyKey: "payments-policy-v3",
});
const recalled = await antidote<{
results: Array<{ memory: { id: string }; eventId: string }>;
}>("/api/retrieve", {
agentId: "finance-agent-07",
query: "What approval is required for a $24,000 payment?",
k: 5,
context: { runId: "run-2026-08-12-001" },
});
const memoryIds = recalled.results.map((result) => result.memory.id);
if (memoryIds.length === 0) throw new Error("No trusted memory returned");
const decision = await antidote<{ id: string }>("/api/decisions", {
agentId: "finance-agent-07",
memoryIds,
summary: "Request a second approver before payment",
idempotencyKey: "decision-payment-24000-v1",
});
const action = await antidote<{ id: string; status: string }>(
`/api/decisions/${decision.id}/actions`,
{
actionType: "approval.requested",
payload: { amount: 24000, currency: "USD" },
summary: "Second approval requested",
externalRef: "approval-queue/REQ-184",
idempotencyKey: "action-payment-24000-v1",
},
);
console.log({ ingested: ingested.memories.length, decision, action });/api/ingestScreen and store source memory
/api/retrieveRecall memory and log retrievals
/api/decisionsRecord memory inputs
/api/decisions/:id/actionsRecord an intended side effect
/api/decisions/:id/derivedRecord derived memory
/api/lineage?memoryId=…Read the causal chain
/api/revocationsSimulate or execute recovery
/api/dependenciesWalk the dependency graph
The first call computes the blast radius without mutation. The second call runs recovery against the same causal graph.
const preview = await antidote<{
mode: "simulation";
affected: {
memories: number;
decisions: number;
actions: number;
agents: number;
};
}>("/api/revocations", {
memoryId: "mem_184",
execute: false,
reason: "Source failed verification",
actor: "security-agent-09",
});
console.table(preview.affected);
// Put operator approval or policy approval here.
const repair = await antidote("/api/revocations", {
memoryId: "mem_184",
execute: true,
reason: "Source failed verification",
actor: "security-agent-09",
});Revoke the compromised root. Quarantine derived descendants.
Invalidate decisions whose recorded inputs include affected memory.
Cancel pending actions. Flag irreversible actions for operator review.
Queue affected agent cases for clean-memory re-evaluation.
Start with CockroachDB. Add model and evidence services after database persistence passes its live integration suite.
Stores memory nodes, causal edges, retrievals, decisions, actions, audits, attack memory, and repair state.
npm run migrate
cockroach sql --url "$DATABASE_URL" -f db/roles.sql
# optional demo records
cockroach sql --url "$DATABASE_URL" -f db/seed.sqlOpenCode Go or Bedrock provides model-backed extraction and verdicts. S3 stores immutable source and repair evidence.
DEMO_MODE=false
DATABASE_URL=postgresql://user:password@host:26257/defaultdb?sslmode=verify-full
ANTIDOTE_TENANT_ID=tenant-acme
ANTIDOTE_API_KEYS=[{"keyHash":"sha256-hex","tenantId":"tenant-acme","principal":"agent-prod","role":"writer"}]
OPENCODE_GO_API_KEY=
OPENCODE_GO_MODEL=deepseek-v4-flash
EVIDENCE_BUCKET=
COCKROACH_MCP_URL=
COCKROACH_MCP_API_KEY=Live cluster proof required per deployment.
One reasoning provider and credentials required.
SAM deployment proof required.
Read-only database access for Security and Forensics agents.
The release matrix proves the local request flow. Production proof also needs live CockroachDB, API authentication, model-backed reasoning, and clean-memory worker execution.
npm run check
npm run smoke
npm run verify:release
# full live proof
ANTIDOTE_URL="https://your-host" npm run verify:liveLive routes require tenant-scoped bearer keys and role checks. Keep raw keys in a server-side secret manager. Do not send them to untrusted browser code.