An anti-hallucination layer for AI coding agents.

Before the AI runs a command or writes a file, your own machine checks it. When a program, script, git branch or package the AI made up isn't there, the action is stopped before it runs.

Install Check Pricing

Works with AI coding agents, on Windows or Linux. Node 18 or newer. Which agents, and what's checked in each: the guide.

It adds Check's hooks to each AI coding agent it finds on your machine (keeping your own hooks) and a folder at ~/.check with the hook script. Nothing goes into your project. From then on, every command and file write passes through Check before it runs, and your machine answers wherever it can.

1. Get your key at the console (14 days free). 2. No Node.js? Install it from nodejs.org. 3. Run this line in a terminal, yourself, not through your AI, and paste your key when it asks. 4. Restart your AI agent. Step by step: the guide.

Windows (PowerShell) or Linux

npx @golproductions/check@latest --install
Windows or Linux: macOS isn't tested yet, so it won't install there. Your GOL API Key comes from the console: 14 days free from when you create it, then a prepaid balance on the same key. Check keeps itself current: the gate updates in the background, at most once an hour, from our server.
01

How it works.

Three steps, every command and every file write.

01The AI writes a command.
Or a file. Before it runs, Check sees it.
02Your machine answers.
Does this program exist? Is this package real? Is this branch actually there?Your own shell, git and parsers answer. Not a model, not us.
03Stopped, with the reason.
If not, the command never runs and the AI is told why. It tries again with something that works.

A real catch.

From our own key, 5 October 2026. Claude was cleaning up after a job on this website. Its command used pkill, a standard Linux tool it assumed would be there. On this Windows machine, it isn't.

Bash(W="/c/Users/user/Desktop/GOLProductions/website-v2"; A="/d/work/my-app"; rm -f "$W/_mock.js" "$W/_shotc.html" "$W/_shotq.html" "$W/_shotq.js" "$A/public/_shot.html" "$A/public/_shot.js"; pkill -f "wrangler dev --port 8795" 2>/dev/null; taskkill //F //IM workerd.exe >/dev/null 2>&1; for f in "$W"/assets/assistant/*.js "$W"/assets/guard-*.js "$A/src/index.js"; do node --check "$f" || echo "FAIL $f"; done; for f in "$W"/functions/api/app/*.js "$W"/functions/api/app/assistant/*.js; do cp "$f" "$TEMP/c.mjs"; node --check "$TEMP/c.mjs" || echo "FAIL $f"; done; echo checked; cd "$W" && git status --short | grep -v "^ M .*\.html$" | head -30; cd "$A" && git status --short)
Error: PreToolUse:Bash hook error: check: bash on this machine said: type: pkill: not found

Recreated from the session in Claude Code’s style. The command and the error are verbatim, except the username, replaced with “user” for privacy. Check stopped the whole command before any part of it ran, so it couldn’t half-finish: delete some files, fail on the missing tool, and leave the server running. Claude’s next attempt dropped pkill and stopped the server with PowerShell instead.

02

What it checks today.

Each answer comes from your machine or the package registry, never a guess.

Commands
Blocks a Bash or PowerShell command that won't parse, and code passed to node -e or python -c, or fed to node or python - through a heredoc, that won't parse, before it runs.
Git Bash's backslashes
Git Bash quietly turns \\ into \ before a command runs. When that would leave code passed to node -e or python -c unable to parse, Check stops it first. A change that still parses runs: whether the doubled backslashes were meant is a judgment, not a fact. When a command fails and Git Bash changed it, Check says exactly what changed.It blocks only when the code as written parses and the code that would arrive does not.
Programs and scripts
Stops a command that runs a program that isn't on your machine, or a ./script that isn't in the folder. That includes commands inside $(...), backticks and bash -c, and after || or else.A program the command checks for first, as in command -v jq && jq, is left to the command.
Packages
Asks npm, PyPI, crates.io, RubyGems, Packagist, NuGet, Homebrew, Chocolatey and the PowerShell Gallery whether the package exists before installing, and whether the version asked for exists. For python -m, asks your Python whether the module is there. A package that npx, pnpm dlx, bunx, uvx or pipx run would download and run, a Docker image or tag being pulled, and a package a JavaScript or TypeScript file starts importing are checked the same way. Before npx downloads and runs a package that isn't installed, it asks npm too.With a private registry, Check stays silent rather than guess.
Folders and scripts
Stops cd into a folder that isn't there, node, python or bash running a script that isn't there, npm, pnpm or yarn run of a script package.json doesn't have, and python -m of a module your Python doesn't have.
Git
Stops git subcommands your git doesn't have, a checkout, switch, merge, rebase, reset, revert or cherry-pick to a branch, tag or commit that doesn't exist, and a push to a remote the repo doesn't have.
Deletes
Stops a delete when the folder the shell would really remove is a whole drive, your home folder or above it, a system folder, or a folder above your project. AI agents have wiped drives on Windows this way: a path quoted for one shell and passed through another, so rmdir receives \, the root of the drive.Ordinary deletes, inside your project or anywhere else, go ahead. A folder held in a variable isn't judged.
Copies
Stops a folder copy that needs more space than the destination has, before it fills the disk and fails partway.Measured for up to 1.5 seconds; a destination that already holds files isn't judged.
Library names
Stops a TypeScript write that uses a function, method, export or option a library doesn't have, like _.smartMerge() or request(url, { retry: 3 }). Your project's own TypeScript decides, against the library's own type definitions.Only new errors in the edit, only names traced to a library, TypeScript 5 or 6. If it takes longer than 2.5 seconds, the write goes ahead.
File writes
Blocks shell, Python, PowerShell and JavaScript files, and package.json, that wouldn't parse, before they're written.JavaScript is judged by Node's own parser: .mjs and .cjs always; an existing .js file that parsed before, when an edit breaks it in a way no dialect explains (an unclosed bracket, an unexpected end). A brand-new .js file is not judged: JSX, Flow and bundler code are written as .js, and Node can't read them. .jsx and other JSON files aren't parsed; .ts files get the library-name check instead. Files written with a heredoc, echo or printf are checked too.
03

What it won't catch.

Where the machine can't give a definite answer, Check stays out of the way.

A file that isn't there.
A missing file a program only reads, like cat notes.txt, runs and fails on its own. Check checks the program, the script node, python or bash would run, and the folder cd goes to, not every file a command reads.
A file written in a roundabout way.
Files written with your agent's write and edit tools, a heredoc, or echo or printf of one quoted text are parsed. Anything more involved, like echo "$x" >> app.py, isn't.
Code that parses but is wrong.
Logic bugs, wrong maths, insecure code, a function that exists but does something else. Check proves things exist and parse; it doesn't judge what code means.
Library names it can't see.
Made-up functions in plain JavaScript, in Python, in libraries without type definitions, and in TypeScript 7 projects.
A made-up name that happens to be real.
Check lets it through, because the command is real.
A real command that does the wrong thing.
Like deleting a folder in your project that you meant to keep, or force-pushing. Check asks whether something exists, not what you meant to do. (A delete that would really hit a drive, your home folder, a system folder or a folder above your project is still stopped: see Deletes above.)
What happens after.
An agent saying "done" or "tests pass" when they don't. Check works before each action, not after.
Private sources.
Packages from a private registry, Docker images from another registry or a private repository, and Go modules: from outside, missing and private look the same.
Anything your machine can't answer for sure.
Check lets it through rather than guess: commands run through eval, env, xargs, sudo or a login shell, anything after a command changes folder or installs something, a script an earlier part of the same command may have made, and PowerShell commands that load a module, define a function or alias, or test for the program themselves.

Check is not a security tool. You still need one.

04

Your data.

What leaves your machine, and what never does.

Sent
For each message you send, its identifier only, never its text. For each command, the command text, with some credential patterns redacted, plus the working folder with your username masked and the results of the checks your machine ran. For each file write, the file's name, its size and whether it already exists, and, if a parser rejects it, the parser's one-line error message, which can quote the word it stopped at, and for JavaScript or TypeScript the names of npm packages it starts importing that aren't installed or declared.Not all credentials are caught: a secret in a PowerShell variable assignment is sent as written.
Never sent
Your prompts, on current installs. File contents: when Claude writes or edits a file, Check parses it on your machine and sends only the parser's verdict.
Kept
A record of each check (time, key hash, network, version, tool, verdict). With improvement records on (new keys, switchable at the console), also the command with credentials removed and the reason. Never your messages or file contents. Everything we keep is listed in our privacy policy.
Account events
Install, uninstall, key created, top-up, with your OS and a truncated account ID. Never command content.

Installs made before 24 September 2026 still send each prompt to an endpoint we retired that day; it discards the prompt unread, stores nothing and charges nothing. Reinstalling Check stops it being sent.

We have our own key that we use on our own machine. We sometimes share what it catches as examples. We never share anything from yours.

What runs where. The gate runs on your machine, in ~/.check, before each command and file write. Your own shell reads the command and answers every check, and file writes are parsed right there too. The logic that decides which questions to ask runs on our servers and isn't published. The way to know if Check works is to use it: if it catches something you would have missed, it's working. If it misses something, you'll know before we do.

Your AI is going to make up another thing.

Check catches it first. 14 days free, no card. US$0.02 per message afterwards.