Back to directory
amsminn avatar
amsminn / vericontext

vericontext

Deterministic, hash-based verification for docs that reference code. Fail-closed. Zero fuzzy matching.

8

Stars

4

Forks

0

Watchers

MIT

License

vericontext

Docs lie. Hashes don't.

SHA-256 citations for docs that reference code.
One stale citation breaks the whole document. By design.

npm version License: MIT TypeScript Node>= 20

English · 한국어


The Problem

AI agents scatter README.md and AGENTS.md across directories. It works great until the code changes and the docs don't. Files move, functions get rewritten, but the docs still say "handler logic lives in src/handler.ts at L30-L45."

Over time, docs become liars. Agents that trust stale docs make worse decisions.

VeriContext embeds a SHA-256 content hash into every code citation at write time. Verify later: hash matches or it doesn't. No fuzzy matching. No "close enough."

Write time:    "handler logic" [ [vctx:src/handler.ts#L30-L45@a1b2c3d4] ]
After change:  vericontext verify → ❌ hash_mismatch (a1b2c3d4 ≠ f5e6d7c8)

One broken citation → entire doc fails. Fail-closed by design.

What It Looks Like

Citations live in HTML comments — invisible in GitHub, VSCode, or any Markdown renderer.

Raw Markdown:

The auth module handles login.
<!-- [ [vctx:src/auth.ts#L1-L50@abcd1234] ] -->

├── src/          <!-- [ [vctx-exists-dir:src/] ] -->
├── tests/        <!-- [ [vctx-exists-dir:tests/] ] -->

Rendered:

The auth module handles login.

├── src/ ├── tests/

vericontext verify finds and checks every citation. If src/auth.ts changes, the hash breaks, the doc fails.

Setup

Claude Code

claude plugin marketplace add amsminn/vericontext
claude plugin install vericontext@vericontext

Codex

codex plugin marketplace add amsminn/vericontext
codex plugin add vericontext@vericontext

Before either hook does anything, the CLI has to be resolvable. The plugin brings the skill and the hooks, not the vericontext binary they call. Hooks resolve a CLI in this order: $VERICONTEXT_BIN, then vericontext on PATH (npm install -g vericontext), then npx -y vericontext@<the version the plugin pins> as a no-install fallback. If none of those resolve, every hook loads, runs, and silently does nothing — no error, no output, indistinguishable from "no stale citations found."

The version the plugin pins is published, so the npx fallback works with no install of any kind. A global install is only worth it to avoid npx's first-run download. Whenever you're unsure which case you're in, settle it yourself:

npx vericontext verify workspace --root . --all --json

The plugin installs the skill and three hooks: a citation reminder when a document is edited, rule propagation to documentation subagents, and workspace verification at the end of every turn. On Claude Code, that's it — no other config, once the CLI prerequisite above is met.

On Codex, there's a second, separate prerequisite on top of the CLI one above, or none of that runs. Codex trust-gates plugin hooks per hook source, separately from installing the plugin: right after codex plugin add, every hook — including end-of-turn verification — is silently skipped, no error, no prompt, under codex exec or any other non-interactive invocation. To turn it on, open one interactive codex session in the project directory. This works whether or not the directory itself is already trusted — measured both ways: the moment Codex has an unapproved hook, it shows a "Hooks need review" screen with three choices ("Review hooks", "Trust all and continue", "Continue without trusting") before you can do anything else in that session; pick "Trust all and continue" (or review individually). If the directory was not yet trusted, this screen follows right after that separate directory-trust prompt; if it was already trusted, this screen appears on its own, immediately — you do not need to untrust and retrust the directory. What was actually verified: granting trust this way once, then immediately running a plain codex exec with no extra flags, was enough for the Stop hook to fire with no further action — the approval is written to ~/.codex/config.toml, a user-level file, not something scoped to the session that granted it, so it should carry forward to later sessions too. (That is the extent of what was measured — one approval followed by one subsequent non-interactive run — not an exhaustive test of every hook event or every future session.) There is no codex plugin-level trust command. The only non-interactive way to run hooks before granting trust is codex exec --dangerously-bypass-hook-trust, which Codex documents as for automation that already vets its hook sources, and which does not persist trust for later runs.

Other agents (Cursor, Windsurf, Antigravity, OpenCode, …)
npx skills add amsminn/vericontext --skill vericontext

The skill carries the citation rules but no hooks, so enforcement is advisory. Run verification yourself at the end of a task:

npx vericontext verify workspace --root . --all --json

The repository carries two marketplace manifests — .claude-plugin/marketplace.json and .agents/plugins/marketplace.json. That is not a duplicate: each harness reads only its own official path and ignores the other.

How It Works

Three operations, one principle: hash it or it doesn't count.

  cite           claim           verify
┌────────┐    ┌────────────┐    ┌───────────────────────┐
│  file  │──→ │ [[vctx:..  │    │ for each token:       │
│ +lines │    │  @hash8]]  │    │   recompute hash      │
└────────┘    └────────────┘    │   match? → ok : fail  │
                                │ any fail → doc fails  │
                                └───────────────────────┘
  1. Cite — snapshot a file range with its SHA-256 hash (first 8 hex chars)
  2. Claim — declare structure facts: exists-dir, missing
  3. Verify — check every citation and claim. One failure → whole doc fails

Token Syntax

Type Token Example
Code citation [ [vctx:path#Lstart-Lend@hash8] ] [ [vctx:src/cli.ts#L1-L10@a1b2c3d4] ]
Directory exists [ [vctx-exists-dir:path/] ] [ [vctx-exists-dir:src/] ]
Path missing [ [vctx-missing:path] ] [ [vctx-missing:tmp-output/] ]

Files always get hashed. Any mention of a file — its role, code, or existence — uses vericontext cite to hash the full file. Only directories use exists-dir claims.

CLI Reference

npm install -g vericontext    # or use npx

cite — generate a code citation

npx vericontext cite --root <dir> --path <file> --start-line <n> --end-line <n> [--json]

claim — generate a structure claim

npx vericontext claim --root <dir> --kind <kind> --path <path> [--json]

--kind: exists | exists-file | exists-dir | missing

verify workspace — verify all claims in a document

npx vericontext verify workspace --root <dir> (--in-path <doc> | --text <text>) [--json]
npx vericontext verify workspace --root <dir> --all [--json]

--all verifies every .md under <dir> that carries a vctx token. Coverage depends on whether git ls-files can answer for <dir>:

  • When it can (a git work tree, and the git invocation succeeds): coverage follows git ls-files --exclude-standard, so it honors not just the project's own .gitignore but also repository-local .git/info/exclude and the user's global git excludes file — a .md file none of your committed .gitignore rules mention can still be skipped if your personal global excludes cover it. It stops at nested repository boundaries (submodules, vendored checkouts), and always excludes node_modules, .git, dist, build, and coverage even if they're tracked.
  • When it can't — not a git work tree, git not installed, or git ls-files fails for any other reason (not just those two cases) — it falls back to a plain filesystem walk that excludes only those five directories; none of git's exclusion rules apply there.

Symlinks are skipped in both modes, for deterministic hashing. Mutually exclusive with --in-path and --text. Exit 1 if any document fails.

Exit code Meaning
0 All valid
1 One or more failures
Error reasons
Reason Meaning
hash_mismatch Content changed since citation
file_missing File does not exist
path_escape Path escapes root jail
range_invalid Line range out of bounds
binary_file Binary file detected
symlink_skipped Symlink skipped for determinism
invalid_input Malformed input

GitHub Actions

- name: Verify docs
  run: npx -y vericontext verify workspace --root . --in-path README.md --json

Pre-commit Hook

# .husky/pre-commit
npx vericontext verify workspace --root . --in-path README.md --json

Self-Verifying Docs

This README contains hidden VeriContext claims. Verify it:

npx vericontext verify workspace --root . --in-path README.md --json

To see how claims look in raw source, view this file with cat README.md or click "Raw" on GitHub.

Contributing

See CONTRIBUTING.md.

License

MIT

Releases

Jul 26, 2026

v0.3.0 — now a plugin

Download .zip

vericontext now installs as a plugin on Claude Code and Codex. Three releases landed in quick succession, so this covers everything breaking since 0.1.4. Upgrading — find your case, ignore the rest Yo...