# GNL > A thin correctness layer over the Vercel AI SDK: journal-backed durability, exactly-once tool calls, deterministic replay and time-travel. The runtime footprint is 32.4 KiB, BYO-DB (SQLite/Postgres/your own storage), no telemetry and no phone-home — your journal always stays on your own infrastructure. GNL keeps the same agent loop: `runDurable` stands in for `generateText`/`streamText` and additionally takes a `journal` and a `runId`. If the process crashes, calling it again with the same `runId` resumes deterministically from where it stopped, and tool calls that already completed never run again. Three layers: Core (free — @gnldev/durable, @gnldev/server, @gnldev/auth, @gnldev/evals), Studio (@gnldev/studio — inspection and management, free), Enterprise (@gnldev/auth-ee — signed license, RBAC/SSO/multi-organization/budgets). Honest execution (measured live on real Postgres with 2048-dim vectors, 6 September 2026): when a tool result is answered from the journal instead of executing, the model would naturally announce a fresh success for work that did not run — measured live, three "order created" narrations against a real side-effect counter that stopped at 2. `replayDisclosure: 'explain'` injects a transient note into the step AFTER the consume (never into the journal, thread memory or any later turn), so the model narrates it honestly: "the operation was not performed again — this is the record of the earlier one." The model stays blind at decision time, informed only while narrating. Repeats: an accidental one (double-click, retry window) is absorbed without a question; a deliberate one becomes a human question EVERY time, and the question carries its context ("this work was already completed earlier (ord-1) — did you mean to repeat it?"), including a spelling difference such as "LAMBA-1" vs "lamba-1", and it calls out differing amounts separately. The approval box shows the EXACT arguments the tool would run with — in a live case the user said 250 and the model passed 100, and that is how a human caught it. The score never decides — deterministic fields decide, a human has the last word. Measured cost: exact dedup 0.25 ms per read; semantic recall is thread-local and linear — 36 ms at 100 records, ~650 ms at 2000. It grows with the side-effect jobs in ONE conversation, not with users or tenants. Stated limit: a single conversation with thousands of side-effect jobs pushes the scan toward a second — the deliberate v1 boundary (in-process brute force, thread scope); an external vector index (v2) is deliberately gated on data. 1612 passing tests in the @gnldev/durable package alone. ## Pages - [Tutorial](https://gnl.dev/tutorial): build a durable on-call agent from scratch — an agent that reads a runbook, asks a human before restarting production, and pages the on-call engineer exactly once even when the alert re-fires as a new run. Nine steps, every package, no API key. Includes the two measurements that make it worth reading: a PII redactor that was installed and still let a database password through, and why "page once" needs two separate guards. - [Examples](https://gnl.dev/examples): six runnable examples in the repository — an on-call triage agent, a support desk with an approval gate, three reproduced double-side-effect incidents, provider-side exactly-once against a mock Stripe, a React useChat client, and a self-verifying showcase. None of them need an API key; every one runs against a deterministic mock model. - [Compare](https://gnl.dev/compare): where GNL sits against hand-rolling durability yourself or adopting a full agent framework — the feature matrix, the measured evidence behind each claim, what GNL deliberately does not do, and what the frameworks do better. No competing product is named. ## Docs - [Agent registry (createGnl)](https://gnl.dev/docs/agent-registry): Central entry point that defines agents/tools/workflows in one config and runs them durably. - [Storage adapters](https://gnl.dev/docs/storage-adapters): Pluggable storage: SqliteStorage, PostgresStorage, InMemoryStorage. - [Automatic REST API + OpenAPI + SSE](https://gnl.dev/docs/rest-api-openapi): Turns createGnl into a durable HTTP API + SSE stream in one line. - [Chat UI: client, useChat & AG-UI](https://gnl.dev/docs/chat-ui): A typed REST/SSE client, Vercel AI SDK useChat compatibility and an AG-UI adapter. - [Exactly-once tools](https://gnl.dev/docs/exactly-once-tools): Side-effecting tools run exactly once per runId. - [Deterministic replay & crash recovery](https://gnl.dev/docs/deterministic-replay): An interrupted run resumes deterministically from where it left off. - [Saga / compensation (unwind)](https://gnl.dev/docs/saga-compensation): Roll back already-executed side effects in reverse order with per-tool compensate hooks. - [Human-approved tools (guard)](https://gnl.dev/docs/human-in-loop-approvals): Guard suspends risky calls; resumed on approval. - [Safe-by-default duplicate guard](https://gnl.dev/docs/duplicate-guard): Catches a repeated side-effecting call with identical args; a reflect nudge or a hard block. - [Semantic duplicate-candidate gate](https://gnl.dev/docs/semantic-duplicate-gate): Finds earlier side-effect work that looks similar in meaning, and puts it in front of a human only when the deterministic fields agree. - [Taint-aware guard (prompt-injection)](https://gnl.dev/docs/taint-guard): Blocks a side effect once untrusted (attacker-authorable) content has entered the run. - [Input/output processors](https://gnl.dev/docs/processors): PII redaction, moderation, token limits, tool filtering and the untrusted-content marker. - [Durable workflows](https://gnl.dev/docs/durable-workflows): Multi-step workflows are suspend/resume-safe. - [Background work: queue, scheduler & events](https://gnl.dev/docs/background-jobs): Run agent work outside a request — durable jobs, cron triggers and an event bus, each exactly-once at its own boundary. - [Cross-run cache](https://gnl.dev/docs/cache): Reuse a computed result across separate runs — best-effort by design, so a cache outage is not an outage. - [Model routing & fallback](https://gnl.dev/docs/model-fallback): Deterministically falls back to the first working model in the candidate list. - [Cost & pricing observability](https://gnl.dev/docs/cost-observability): Computes per-run token/cost/trace from the journal. - [Per-run limits & cost cap](https://gnl.dev/docs/run-limits): Stop a runaway run on a per-run token/cost/tool-call ceiling with RunLimits. - [Open-core auth (roleAuth)](https://gnl.dev/docs/open-core-auth): Free bearer/role-based identity & authorization; gates REST+Studio. - [Studio — inspector & management plane](https://gnl.dev/docs/studio-inspector): Journal observation UI+API: timeline/trace/cost/Playground/management. - [Time-travel & fork](https://gnl.dev/docs/time-travel-fork): Reconstruct state from any step, or fork into a new branch. - [Replay-based regression](https://gnl.dev/docs/replay-regression): Re-run a recorded run against a new model or prompt, then diff the decision points. - [Data-driven guard/policy](https://gnl.dev/docs/guard-policy): Allow/deny/suspend guard driven by __policy__ in the journal; no deploy needed. - [Evaluation: scorers & LLM-judge](https://gnl.dev/docs/evals-scorers): Deterministically scores runs from the journal trace. - [Eval gate (promotion governance)](https://gnl.dev/docs/eval-gate): No promotion without passing the suite (412). - [Agent versioning](https://gnl.dev/docs/agent-versioning): Keep agent versions in the journal, activate with promote. - [Retention TTL sweep](https://gnl.dev/docs/retention-ttl): Bulk-clean old runs by age (sweepRuns). - [GDPR / PII deletion (purge)](https://gnl.dev/docs/gdpr-purge): Permanently erase a run/thread's journal trace (purgeRun/purgeThread). - [Signed license (Enterprise)](https://gnl.dev/docs/signed-license): Verifies an Ed25519-signed license; fail-closed boot. - [Multi-organization (organization isolation)](https://gnl.dev/docs/multi-organization): Every request is scoped to an isolated organization journal; identity-bound, 403 on mismatch. - [Budget & quota (402)](https://gnl.dev/docs/budget-quota): Per-organization token/cost limit; new runs get 402 when exceeded. - [RBAC (role-based access control)](https://gnl.dev/docs/rbac): Resource/action authorization via a role→permission mapping. - [SSO (OAuth/OIDC/SAML/JWT)](https://gnl.dev/docs/sso): Resolves an enterprise identity provider into a Principal. - [User management (journal-backed)](https://gnl.dev/docs/user-store): Token→Principal; hashed in the journal; Studio Users. - [Audit log](https://gnl.dev/docs/audit-log): Authorization decisions + admin actions are permanent, with a non-spoofable actor. - [Dynamic agent networks](https://gnl.dev/docs/agent-networks): A router LLM selects sub-agents; decisions are frozen via CAS, so the router isn't called again on resume. - [Remote agents (A2A)](https://gnl.dev/docs/a2a): Call an agent on another server as a tool — exactly-once across the network, optionally signed. - [Conversation memory (provenance-backed)](https://gnl.dev/docs/memory): Recall, working memory and replayable compaction — with a record of what memory actually injected. - [RAG pipeline (chunking + pgvector + GraphRAG)](https://gnl.dev/docs/rag-pipeline): Deterministic chunking, persistent pgvector, and GraphRAG; exactly-once RAG inside durable. - [Semantic tool search (toolSearch)](https://gnl.dev/docs/tool-search): A processor that selects the topK tools via embeddings; the selection is journaled → embedding never runs again on resume. - [MCP client, server & firewall](https://gnl.dev/docs/mcp): Use external MCP tools durably, expose your own over MCP, and gate both with a firewall. - [Observability integrations (OTLP presets)](https://gnl.dev/docs/observability-integrations): Langfuse/LangSmith/Braintrust/Honeycomb/Datadog/Collector via one-line OTLP + live mode. ## Full - [llms-full.txt](https://gnl.dev/llms-full.txt): the extended version — install/import, the core API names and one minimal code example for every feature.