Skip to content

Verified Record of Events and Knowledge

Done is a claim.
Verified is a fact.

Vrek is an API-first system of record for humans and agents doing work together — planning it, deciding it, building it and evidencing it. One graph, one API, provenance on every node.

Pick the one you are

The same graph answers four fairly different questions, and a page that answers all of them at once answers none of them well. Each track is six moves, walked one at a time, and every move is shown three ways — in the shell, in a chat client over MCP, and in the browser console — because the surface is the thing that differs between these readers, and the objects underneath it do not.

None of them quite you? The rest of this page is the general argument, and every track links back into it.

Not two systems bolted together

Jira and Confluence are two systems of record-keeping bolted together. Vrek is one graph: the work, the knowledge, the decisions, the evidence and the principals — human or agent — are the same objects, reachable through one API, with provenance and freshness as properties of every node.

Software is the first domain, not the only one. Requirements gathering and analysis run the same loop, and what an agent is told on connect belongs to the workspace rather than to a file in a repository.

A question, not a guess
When an agent would otherwise guess, it asks — and the work leaves the ready set until a human answers.
Evidence, not assertion
A status is a claim. A verification records who checked it, when, and how you would re-check.
Documents as views
A doc is blocks, not prose. Node and query blocks resolve on read, so they cannot go stale.
Append-only
Nothing is edited or deleted. A correction is a new event, and fsck re-verifies the whole chain.

The loop, in general

vrek status <id> done records that somebody said it was done. Until a verification passes, vrek report and vrek unverified both show the claim as a claim. That distinction is the point of the product.

the working loop
# what can be picked up, with each item's footprint
$ vrek ready
$ vrek status iss-3bg971s in_progress

# would you have guessed? ask instead — this blocks the work
$ vrek ask "Postgres or SQLite for the shared server?" \
$     --option "postgres|a service to run on day one" \
$     --option "sqlite|single binary, one writer" \
$     --blocks iss-3bg971s --owner mike
claim, then evidence the claim
# a claim
$ vrek status iss-3bg971s done

# the fact behind it
$ vrek verify iss-3bg971s "integration suite passes" \
$     --result pass --evidence "npm test, 916 tests"

# shipped / blocked on you / claimed / ready
$ vrek report

pending is honest

A check written but never executed is --result pending, never pass. Resolve it afterwards; correcting a result appends a new event naming who corrected it, and the original stays in the log.

deferred ≠ blocked

Work put off on purpose is vrek defer with a wake date and a reason. blocked asserts something is in the way, which is a different fact.

Walked step by step, against the surface you would use: developer · devops & platform · product owner · architect & tech lead.

The log is checkable

Every event carries the events it was appended after and a hash over its canonical form, so the hash covers the history reaching it: altering any ancestor changes every descendant.

fsck reports three different things and does not confuse them. A hash mismatch is tampering. A missing parent or orphaned actor is a broken reference. Unchained means an event predates hashing and cannot be checked at all — unverifiable is not a failure, corruption is.

verify the recorded history
$ vrek fsck
chain intact: every hash recomputes and every parent resolves

# the projection rebuilds from the log, so it is not the record
$ vrek init && vrek import .vrek/log.ndjson

One core, five surfaces

All of them call the same Workspace class. A capability reachable from one and not the others is a bug, and gets filed as one.

SurfaceEntry point
CLIvrek
MCP over stdiovrek-mcp
HTTPvrek-api
MCP over HTTPPOST /mcp
MCP resourcesvrek://doc/<id>

Over stdio the actor comes from VREK_ACTOR, so it is asserted rather than authenticated — fine for one trusted writer, and it fails silently the moment that stops being true. For anything shared, MCP over HTTP with bearer tokens is the transport, and an unauthenticated call is refused rather than quietly attributed to somebody. The platform track walks that setup.

Install

Node 24 or above. The runtime depends on nothing outside Node's standard library, so this is the whole dependency list.

one package, three binaries
$ npm install -g @mmainguy/vrek

Or one file, no Node — in two builds

The Go build is a single binary with the console compiled in. It passes the same conformance suite as the npm package: vrek is the CLI, vrek mcp the MCP server, and vrek serve the HTTP API and console. Every release is built twice from the same source, and the two differ in exactly one thing.

Plain vrek · about 16 MB

The CLI, the MCP server, the HTTP API and the console: everything the npm package is, in one file.

Free.

Full vrek-full · about 29 MB

Everything in the plain build, plus vrek serve --tailscale: a server that joins your tailnet as a node of its own, needs no tailscaled, serves under its own ts.net certificate, and records every caller as the person or device the tailnet says it is.

Offered with an engagement.

The plain build

macOS and Linux, after downloading
$ chmod +x vrek
# macOS only: the binary is not notarized
$ xattr -d com.apple.quarantine vrek
$ mv vrek /usr/local/bin/

The file saves as vrek whichever platform and version the link names, so those four lines are the install on every one. Checksums are in SHA256SUMS, and every release stays available under its number, for example /download/0.28.0/darwin-arm64/vrek. On Windows, SmartScreen will ask before the first run: the binary is not signed.

The full build, and why it is not a free download

A hub on a tailnet is the start of something rather than a file to run: which device is which principal, what the tailnet policy grants, how two hubs keep one workspace. That is engagement work, and the full build is offered with it: set up, with the policy and the identity rules written for your tailnet, and supported. The code is MIT either way. The right to build the full binary from source is yours, and nothing here says otherwise; what an engagement buys is the built, supported binary and the setup around it.

To talk about one, get in touch. While that path is being set up the full build's downloads are open, under the same checksums: darwin-arm64, darwin-amd64, linux-amd64, linux-arm64, windows-amd64, windows-arm64. A plain build answers vrek serve --tailscale by naming the full one, so you cannot pick the wrong file by accident.

Then start a workspace

a new project
$ cd ~/some-directory
$ vrek init
$ vrek name "My Project"

# writes .mcp.json so an agent connects
$ vrek register --model claude-opus-5
$ vrek add "the first thing" --touches src/
$ vrek ready
a clone that already has a log
$ vrek init
$ vrek import .vrek/log.ndjson
$ vrek report

That second block is the step a clone always needs and the one that is easy to miss: every command answers no Vrek workspace found until you import. Export after any session that changed the workspace, commit the log beside the code, and it travels.

It tracks its own development

.vrek/ in the Vrek repository is a live workspace, not a demo fixture. These numbers were read out of it on 11 October 2026.

5,050
events in the log
hash-chained, none rewritten
253
issues done
82 open, 3 in progress
442
verifications passing
27 pending, 1 failing
8
principals
humans and agents, same table

Not built

  • —OIDC sign-in for people who are not on a tailnet
  • —Replication between hubs: two servers keep one workspace by export and import, by hand
  • —Postgres for a shared server
  • —Three-way merge on import
  • —Erasure mechanisms
  • —The git projection, deferred to 2027

Known limitations

Because a guarantee should say where it stops holding.

  • —Whole-graph reports take 10–15 s at 70k nodes, and dependency walks recurse on the call stack
  • —The tailnet door records a person's login, an email, as their handle unless a policy grant names one
  • —Every CLI command waits on an update check at exit, up to 5 s with no network

All of them are recorded in the workspace — vrek ready lists them with the rest, rather than leaving them in prose nobody queries.