Protocol Demo Console Compare Docs GitHub ↗

Quickstart

pip install veripoint     # zero dependencies beyond the stdlib

veripoint init                 # creates .veripoint/ (ledger, snapshots, reports)
from veripoint import Veripoint, Slot
from veripoint.drivers import HTTPDriver          # or SubprocessDriver("claude -p")
from veripoint.verifiers import CommandGate, ReconcileGate

k = Veripoint(".veripoint")
r = k.run(
    goal="Reconcile October invoices against the ledger",
    driver=HTTPDriver(model="gpt-5", api_key_env="OPENAI_API_KEY"),
    slots=[
        Slot("extract invoice totals",
             verifiers=[CommandGate("python checks/invoices_parse.py")]),
        Slot("reconcile vs ledger",
             verifiers=[ReconcileGate("recon.json", {
                 "sum matches ledger": lambda d: d["sum"] == d["ledger_total"],
             })]),
    ],
)
print(r.summary_line())

Every slot runs as its own attempt cycle: restore last verified workspace → brief a fresh agent → run → verify → accept or reject. If attempts are exhausted, Veripoint formally rewinds and the session fails honestly rather than shipping poison.

Core concepts

TermMeaning
SessionOne long-running job: goal + policy + full event history.
SlotA declared unit of work plus the gates it must pass.
Attempt / ChunkOne try at a slot by the agent; the chunk is what gates judge.
CheckpointA verified-good save: workspace snapshot + accepted chunk facts.
QuarantineNormalized failure signatures of rejected approaches; fed to future briefings.
BriefingClean notes compiled from verified history only — what a restarted agent sees.
LedgerAppend-only, SHA-256 hash-chained event log outside the agent's context.

The protocol loop

  1. Restore the workspace to the newest verified checkpoint (or empty room on first slot).
  2. Brief a fresh attempt from clean notes: verified progress, key data, known-bad approaches, prior failure reasons for this slot.
  3. Run under a wall-clock budget via a driver.
  4. Verify with all gates; any exception inside a gate fails closed.
  5. Accept: snapshot the workspace, commit a checkpoint, move to the next slot.
  6. Reject: quarantine failure signatures, retry from step 1 with the failure in the briefing.
  7. Exhausted: formal rewind event; session marked failed. Resume later grants fresh budgets (bounded by restart limits).

Parallel plans (DAG)

Slots can declare dependencies with depends_on=[...]. Independent slots run concurrently (bounded by Policy.max_concurrency); dependents start only after every parent is verified.

k.run(goal="migrate billing", driver=drv, slots=[
  Slot("map endpoints", key="map", verifiers=[CommandGate("pytest tests/test_mapping.py -q")]),
  Slot("migrate charges", key="chg", depends_on=["map"], verifiers=[...]),
  Slot("migrate refunds", key="ref", depends_on=["map"], verifiers=[...]),
  Slot("cut over", key="cut", depends_on=["chg", "ref"], verifiers=[CommandGate("./smoke.sh")]),
])   # chg and ref execute in parallel

Isolation: every attempt rebuilds its branch's workspace as an overlay of its dependency checkpoints — rejected branches evaporate, poison cannot cross parallel branches, and children always see their parents' verified files. A failed slot blocks its transitive dependents (slot.blocked) while independent branches drain.

Cost accounting & budgets

Every attempt's token usage is recorded — including rejected attempts, because you pay for those too. Cost is estimated from a pricing table (longest-prefix match on model names; unknown models are tracked as explicit unpriced tokens).

k = Veripoint(".veripoint", pricing={"my-model": (3.0, 15.0)})   # USD per 1M tokens (in, out)
k.policy.session_budget_usd = 5.00     # hard caps — exceeded means no further
k.policy.slot_budget_usd = 1.50        # attempts, budget.exceeded event, FAILED session
k.policy.retention_keep_checkpoints = 20   # auto snapshot GC at session end

Inspect spend with veripoint cost SESSION; prune old snapshots anytime with veripoint gc --keep 20 [--dry-run].

Gates

Gates answer one question mechanically: can this chunk be proven good? They never ask the agent whether it did the work.

GateChecksFails closed on
CommandGate(cmd)Shell command exits 0 in the workspace (pytest, lint, custom scripts)non-zero exit, timeout, launch error
PythonGate(fn)Your callable over the chunk/workspaceany exception
FilesExistGate(paths)Files exist, non-empty (configurable min bytes)missing/empty files
ContentGate(path,…)Must-contain / must-not-contain strings, regexesmissing file or violated constraint
NoPlaceholdersGate(path)No TODO/FIXME/placeholder slop left behindany marker found
JsonSchemaGate(schema,file|chunk)Strict JSON-schema subset validation (bool≠int!)unreadable JSON, violations
ReconcileGate(file,checks)Named numeric predicates over parsed artifacts — sums, cross-totals, source recomputationcrashing check, mismatch
AllOfGate / AnyOfGateCompositionas children dictate

Shadow mode + promotion analytics

New gate? Set required=False. It records evidence and builds an agreement track-record without reject authority. Then run veripoint gates: a shadow gate "agrees" when it passed on accepted chunks and failed on rejected ones — i.e., enforcing it would never have changed a verdict. Gates with enough decided runs and high agreement are flagged PROMOTE → set required=True.

Gate packs

Curated chains for common domains — start with the code/SRE pack:

from veripoint.packs import code

Slot("ship the change", verifiers=[
    *code.pack(test_command="pytest -q",          # suite must pass
               python_paths=["src"],              # everything must compile
               sweep_globs=["**/*.py", "**/*.md"],# no TODO/FIXME slop
               runbook_path="RUNBOOK.md",         # must contain Rollback
               smoke_command="./smoke.sh"),
])

Anti-Goodhart stance

Prefer reconciliation checks that recompute claims independently from sources (e.g., re-derive totals from raw inputs) over checks that trust the agent's own outputs. A claim that can't cite reality is not evidence of work.

Drivers

DriverUse for
SubprocessDriver(cmd)Any CLI agent: claude -p, codex exec, aider… Runs with cwd = workspace; $VERIPOINT_BRIEF/$VERIPOINT_WORKSPACE env vars point at the briefing.
HTTPDriver(...)OpenAI-compatible APIs (OpenAI, OpenRouter, Ollama at localhost:11434/v1, vLLM) and Anthropic. The model must reply with a JSON chunk report (summary, data, files).
MockDriver(script)Deterministic tests & demos; script behavior per (slot, attempt).
your own callableImplement propose(req) → ChunkResult; embed Veripoint in any framework loop via k.submit_chunk().

All drivers are stateless between attempts. Veripoint owns the memory — that's what makes restarts clean.

CLI reference

veripoint init                          # create store
veripoint run job.py                    # execute a job script + print summary
veripoint status                        # sessions table (status, saves, spend)
veripoint log [session]                 # hash-chained event timeline
veripoint show SEQ                      # inspect one event payload
veripoint checkpoints [session]         # list verified saves
veripoint diff CP_A CP_B [--json]       # time-travel diff: files + facts as-of
veripoint rewind CP_ID [session]        # restore workspace to a save (history kept)
veripoint brief [session]               # preview the next attempt's clean notes
veripoint gates [session]               # per-gate analytics + shadow promotion report
veripoint retry SESSION --job f.py --driver SPEC   # resume failed session
veripoint cost [session]                # token/cost breakdown per attempt
veripoint gc [--keep N] [--dry-run]     # prune snapshot archives + orphan blobs
veripoint doctor                        # sqlite integrity + hash-chain + blob audit
veripoint report [session]              # write markdown audit report
veripoint serve [--port 7644]           # local dashboard UI
veripoint mcp --job job.py              # MCP server for Claude Code/Cursor/etc.

Rewind & clean notes

Rewind has two halves:

$ veripoint brief ses_8f21 --objective "retry the cutover"
# Veripoint BRIEFING — billing-migration

GOAL: Migrate billing service to v2 API
...
## VERIFIED PROGRESS
- [step 0] map endpoints — 41 mappings, tests pass | workspace files: 6
## KNOWN-BAD APPROACHES (do NOT repeat)
- command|exit code # != expected # — failed 2x. Reason: [command] pytest …
## YOUR TASK (attempt 3)
retry the cutover
### Why earlier attempts failed verification
- attempt 1: [command] exit code 1 != expected 0 …

Integrations

MCP server — Claude Code, Cursor, any MCP client

# .mcp.json in your project
{ "mcpServers": { "veripoint": {
    "command": "veripoint",
    "args": ["mcp", "--job", "veripoint_job.py", "--workspace", "."] } } }

The agent gets eight tools (briefing, submit_work, rewind…) and every claim is gate-checked. Gates live in an operator-authored job file — the agent cannot weaken its own acceptance criteria.

Claude Code / Codex / aider (CLI agents)

SubprocessDriver("claude -p --output-format json")
SubprocessDriver("codex exec \"$(cat $VERIPOINT_BRIEF)\"")

Ollama (fully local)

HTTPDriver(base_url="http://localhost:11434/v1", model="qwen3-coder", api_key="ollama")

LangGraph / CrewAI / your own loop

Use embedded mode: create a session, then submit one slot at a time from inside your graph node or crew step. Your framework keeps doing orchestration; Veripoint owns truth.

s = k.new_session("migration", goal="...", driver=my_driver)
out = k.submit_chunk(s.id, slot_idx=0, slot=my_slot, driver=my_driver)
if not out["ok"]: ...   # Veripoint already quarantined + logged everything

Benchmark

Deterministic micro-benchmark over five silent-defect scenarios × 5 seeds. Agents are scripted simulations — it validates protocol mechanics (catch, recover, correctness), not model quality. Reproduce: python3 scripts/benchmark.py --seeds 5.

scenariobaseline ships wrongVeripoint caught & recoveredVeripoint failed openly
dropped-rows5/55/50/5
swapped-fields5/55/50/5
stale-source5/55/50/5
placeholder-slop5/55/50/5
transient-crash0/55/50/5
total20/2525/250/25

API surface

CallReturns
Veripoint(root, pricing={...}).run(goal, slots, driver)RunReport (success, attempts, rejects, rewinds, blocked/parallel slots, spend via store)
k.run_plan(goal, slots) / await k.arun_plan(...)Explicit DAG execution; auto-detected by run() when depends_on present
k.resume(session_id, slots, driver)Continues from verified checkpoints; grants fresh attempt budget (DAG-aware)
k.diff(cp_a_id, cp_b_id)Time-travel delta: files added/removed/modified + facts as-of both slots
k.submit_chunk(session, idx, slot, driver)Embedded single-slot execution
k.brief_for(session_id, objective)The compiled clean-notes string
store.verify_chain() / store.gc(keep=N)Tamper audit / snapshot retention with orphan-blob sweep
store.cost_summary(sid) / store.gate_stats(sid)Spend aggregates incl. unpriced tokens / per-gate analytics
Slot(objective, key=…, depends_on=[…], verifiers=[…])Declaration unit; optional max_attempts; DAG edges