# goalline > Free, open source CLI and GitHub Action that catches AI coding agents editing tests to pass. It replays the old version of every test a change edited against the new code, so a moved expectation shows up with its exact old and new values. It also keeps signed receipts for every check, so CI can skip what the same code already passed. - Run: `npx github:intikhab49/goalline ` or `npm install -g github:intikhab49/goalline`. Node 20+ and git, zero dependencies, MIT. Version 0.14.0. - `goalline goalpost --base origin/main -- npx jest {files}`: old tests on the new code. Verdicts: HELD, MOVED (with old and new values), BROKE, CRASHED (not judged), EMPTY, UNKNOWN. Exits 2 when something is flagged. - `goalline prove-red`: new tests must fail on the base code, or they test nothing. - `goalline guard --hook`: a Claude Code Stop hook that keeps the agent working until it restores a moved expectation or records why (`guard --ack ... --why ...`, ledger via `guard --report`). - `goalline history --from-git`: replays the last 200 merged pull requests and reports what goalpost would have flagged. - `goalline run --gate --reuse`: signed receipts (in-toto test-result, DSSE, Ed25519) keyed by the git tree; skips a gate the same code already passed. `--input db=pg` adds the PostgreSQL schema to the receipt. `goalline verify --require a,b` says which gates are proven. - `goalline run` also watches the real clock in Jest, Vitest and node --test runs: a pass whose own tests or code read `Date.now()` or `new Date()` counts until the next midnight (`--clock-ttl`), as do reads of fake timers left at the real time; fake timers set to a fixed time don't count. - Jest, Vitest and pytest are judged test by test; any other runner file by file, by exit code. - GitHub Action: `uses: intikhab49/goalline@v0` with `command: npx jest {files}`. A flagged test the change explains in `.goalpost-acks.json` (its own `guard --ack` entries) shows its reason on the card and doesn't fail the step (`acks: false` to fail on every flag). Marketplace: https://github.com/marketplace/actions/goalline-catch-ai-edited-tests - Benchmark: on the last 200 merged PRs of pallets/click and pallets/jinja, 126 edited a test and 31 were flagged with their old and new values. Every flag was a deliberate change its PR explains, and 4 changed what users see without the changelog saying so. Every flag with its reason: https://intikhab49.github.io/goalline/benchmark/ - No AI model is involved and no source code leaves the machine. - Independent project by Intikhab Azam. ## Guides - [How to tell if an AI coding agent edited a test to make it pass](https://intikhab49.github.io/goalline/catch-ai-edited-tests/): When a change edits the code and its test together, CI passes either way. Run the old tests on the new code to see which expectation moved, and to what. - [Stop Claude Code from editing tests to pass](https://intikhab49.github.io/goalline/claude-code-stop-hook/): A Claude Code Stop hook that runs the old tests on the agent's work and keeps it working until it restores the behaviour or explains why it changed. - [A GitHub Action that catches tests edited to pass](https://intikhab49.github.io/goalline/github-action/): goalline's GitHub Action runs the old tests on each pull request's new code and puts every moved expectation, with its values, on the job summary. - [Check that new tests fail on the old code](https://intikhab49.github.io/goalline/prove-red/): A test that passes before the fix proves nothing. goalline prove-red runs a change's new tests on the base code and flags any that already pass. - [Skip CI tests that the exact same code already passed](https://intikhab49.github.io/goalline/skip-tests-already-passed/): goalline keeps a signed receipt for every test run, keyed by the git tree, so a gate this exact code already passed is skipped instead of run again. - [Test caching that notices when the database schema changed](https://intikhab49.github.io/goalline/database-schema-inputs/): goalline --input db=pg hashes the schema PostgreSQL reports before and after each test run, so a cached pass never stands in for a different database. - [Find the tests that read the real clock](https://intikhab49.github.io/goalline/tests-that-read-the-clock/): goalline counts the real-clock reads your own tests and code make under Jest, Vitest or node --test, and a pass that read the clock counts until midnight. - [Replaying 400 merged pull requests of pallets/click and pallets/jinja](https://intikhab49.github.io/goalline/benchmark/): goalline history on the last 200 merged PRs of click and jinja: 126 edited a test, 31 were flagged, and every flag was a deliberate change its PR explains. - [goalline command reference](https://intikhab49.github.io/goalline/commands/): Every goalline command and option, from goalline help: run, verify, goalpost, prove-red, guard, history, prune and trial-report. ## Docs - [README](https://github.com/intikhab49/goalline#readme): everything, with the limits and the trust model - [Releases](https://github.com/intikhab49/goalline/releases): what changed in each version ## Optional - [llms-full.txt](https://intikhab49.github.io/goalline/llms-full.txt): the README and the full command reference as plain text