Skip to content

Releases: datacrate360/agent-countercheck

Agent Countercheck v0.5.3

Choose a tag to compare

@github-actions github-actions released this 21 Oct 02:02
Immutable release. Only release title and notes can be modified.
  • Fix: on macOS and Linux, processes a check leaves running in the background are stopped when the check ends.
    A check that started a server or sleep 300 & and exited could pass while that process kept running (and kept
    its port open) after verify finished, beyond the check's timeout. Each check already ran in its own process
    group, but the group was only killed on timeout; now it is killed after every check, as Windows already did with
    its Job Object. Reported by Perch Scan. A process that deliberately leaves the group (setsid) can still escape
    on Unix; the macOS sandbox and a container remain the way to contain a hostile check.

Install

You use Command
Python pip install -U agent-countercheck · uvx --from agent-countercheck countercheck verify
macOS / Linux, Homebrew brew trust --formula datacrate360/tap/agent-countercheck && brew upgrade agent-countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.ps1 | iex

Agent Countercheck v0.5.2

Choose a tag to compare

@github-actions github-actions released this 21 Oct 01:26
Immutable release. Only release title and notes can be modified.
  • Fix: protected files stored in Git LFS work again (#11).
    Since v0.5.1 the base is read from git's own objects, which for an LFS file is the small pointer, so an untouched
    LFS test fixture counted as changed and the checks ran against the pointer. Now the real content comes from the
    local LFS store, checked against the pointer's SHA-256 and size: an untouched file isn't a change, an edited one is
    put back with its real content, and a changed LFS store is refused like a changed git object. If the content isn't
    on the computer, verify says so (git lfs pull) instead of failing the check. Golden expected files stored in LFS
    are read the same way.

Install

You use Command
Python pip install -U agent-countercheck · uvx --from agent-countercheck countercheck verify
macOS / Linux, Homebrew brew trust --formula datacrate360/tap/agent-countercheck && brew upgrade agent-countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.ps1 | iex

Agent Countercheck v0.5.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 00:25
Immutable release. Only release title and notes can be modified.

Upgrade: security fix. With v0.5.0 and earlier, an agent that changed settings in the project's own .git could
get VERIFIED for broken code with weakened tests. Found in an audit (docs/audit/2026-10-findings.md).

  • Fix: what changed is decided from the files themselves, and the base from checked git objects. Countercheck
    used git's index and git diff to find changed files, and trusted git to show the base revision. Settings in the
    worker's own .git could make an edited protected file look unchanged, or make the base show other content, and
    turn a FAILED into VERIFIED. Now the clean copy's bytes are compared with the base, and every git object read for
    the base is hashed again and must match its id (replace refs are ignored); a mismatch stops the run with an error.
    A protected file that differs only by CRLF line endings is not reported as changed and still runs with its base
    bytes. Protected files stored through a git filter (e.g. Git LFS) are compared as stored in git.
  • Fix: nothing is written or deleted through a symlinked folder in the clean copy. If the worker replaced a
    folder with a symlink out of the project, putting back its protected files wrote them through the link, and a
    golden check's old output file was deleted through it. Now such a link is replaced by a real folder in the copy
    before protected files are restored, a golden output behind it is left alone (and refused after the run), and a
    link folder behind it is not linked.
  • Docs fix: the README's "at least N tests" example could pass failing tests. Its exit code came from
    grep -q '^OK' on the output, so code that printed OK and a few ... ok lines passed while its tests failed. The
    example now keeps unittest's own exit code and counts tests from its Ran N tests line.

Install

You use Command
Python pip install -U agent-countercheck · uvx --from agent-countercheck countercheck verify
macOS / Linux, Homebrew brew trust --formula datacrate360/tap/agent-countercheck && brew upgrade agent-countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.ps1 | iex

Agent Countercheck v0.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 21:13
Immutable release. Only release title and notes can be modified.
  • Receipts can say which changed files no check covers (#6).
    Add covers = ["backend/**"] to a [[check]]; [[forbid]] and [[coverage]] cover their paths. The receipt
    then lists every changed file none of them covers, and show, report and ui show it. Top-level
    uncovered = "unverified" turns such a VERIFIED into UNVERIFIED. Off until a check declares covers, so existing
    projects see no change; read from the base revision like every other rule. docs/checks.md "Which files the checks
    cover".

Install

You use Command
Python pip install agent-countercheck · uvx --from agent-countercheck countercheck verify
macOS / Linux, Homebrew brew trust --formula datacrate360/tap/agent-countercheck && brew install datacrate360/tap/agent-countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.ps1 | iex

Every install gives you the countercheck command.

Agent Countercheck v0.4.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:08
Immutable release. Only release title and notes can be modified.

Upgrading: nothing to change in your projects. Homebrew users: brew trust --formula datacrate360/tap/agent-countercheck, then brew upgrade (Homebrew 7 asks before loading a renamed third-party formula).

  • Renamed to Agent Countercheck, to make clear it's for AI agents. The command is still countercheck, and so are
    the .countercheck/ folder, the hooks and the COUNTERCHECK_* settings: existing projects need no change.
    • GitHub: datacrate360/agent-countercheck (the old address redirects).
    • PyPI: pip install agent-countercheck / uvx --from agent-countercheck countercheck. pip install countercheck
      keeps working: from this release it installs agent-countercheck.
    • Homebrew: brew install datacrate360/tap/agent-countercheck; the tap renames the old formula, so
      brew upgrade moves existing installs over.
  • New look for countercheck ui and countercheck report, in DataCrate360's teal and coral: a header, cards for the
    totals, verdict pills, and runs that open and close. Still no web fonts, images or outside requests.
  • Fixed: the countercheck ui page showed "disconnected" and stopped updating after a new receipt landed. The
    server handled one connection at a time and answered a browser's spare, still-silent connection with 400 Bad Request after 2 s; the browser then read that stale reply for its next update. Silent connections are now closed
    without a reply, and each connection has its own thread (at most 32), so one can't hold up another.

Install

You use Command
Python pip install agent-countercheck · uvx --from agent-countercheck countercheck verify
macOS / Linux, Homebrew brew trust --formula datacrate360/tap/agent-countercheck && brew install datacrate360/tap/agent-countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/agent-countercheck/PROD/install.ps1 | iex

Every install gives you the countercheck command.

Countercheck v0.3.1

Choose a tag to compare

@github-actions github-actions released this 20 Oct 15:54
Immutable release. Only release title and notes can be modified.

Hermes desktop app / gateway users: upgrade; with v0.3.0 the hook ran no checks there. Then approve the hook once
in a terminal (docs/hooks/hermes.md).

  • Recipes: recipes/ with a first recipe, Oracle → Snowflake (check files, helper scripts, a tested
    5-minute start). README FAQ and diagrams.

  • Fixed: the Hermes hook did nothing when Hermes ran outside the project. Hermes sends its own working directory
    as cwd, and the desktop app and gateway run from the home folder, so hermes-pre-verify found no git repository
    and silently let every turn finish. It now checks the git repositories holding the turn's changed_paths that
    have a .countercheck/checks.toml (each one; a failure names its project), and stays silent when the changed files
    are in no such project. A project counts if its check file is in the working tree or the base revision, so
    deleting checks.toml doesn't skip the checks. Without changed_paths, cwd is used as before.

  • Docs: docs/hooks/hermes.md: setup, which project gets checked, and the one-time hook
    approval Hermes needs (hermes hooks list shows "not allowlisted" until you answer y in a terminal; until then the
    hook never runs).

Install

You use Command
Python pip install countercheck · uvx countercheck verify
macOS / Linux, Homebrew brew install datacrate360/tap/countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.ps1 | iex

Countercheck v0.3.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 18:07
Immutable release. Only release title and notes can be modified.
  • Native Windows support (Windows 10/11, x86_64): countercheck.exe runs without WSL. Install with
    pip install countercheck, uvx countercheck or irm .../install.ps1 | iex (checks the SHA-256 against
    SHA256SUMS.txt before installing). What works: verify, show, init, report, ui, the three hooks
    (claude-stop, hermes-pre-verify, session-start) with Windows paths, every check type. Checks run with Git for
    Windows' sh by default (a missing sh fails the check with a plain message); each check runs in a Job Object,
    so a timeout kills the whole process tree and background leftovers stop when the check ends; link folders become directory junctions; symlinks Windows refuses are written as text files with the
    target, like git does. Paths and the tree hash use /, so the same work gives the same receipt paths and tree
    hash on Windows and Unix. CI tests every change on Windows. What doesn't, yet: no sandbox on Windows (checks
    run as a normal process; the receipt says none (no sandbox on Windows yet), --sandbox seatbelt is a plain
    error); no ARM64 build (the x86_64 one runs under emulation); no winget or scoop.
  • shell option on a check: "sh" (default), "pwsh" (PowerShell 7, or Windows PowerShell) or "cmd"
    (Windows). Validated when the check file is read.
  • Fixed: Windows line endings. A $ at the end of a coverage (or forbid) pattern now also matches before
    \r\n; before, coverage reported items in CRLF files as missing.
  • countercheck ui: a live page of the receipts that updates while an agent works. 127.0.0.1 only, a random
    token in the address, Host checked (so other web pages and DNS rebinding can't read it), GET only, read-only, a
    strict Content-Security-Policy with a per-page nonce. Port 7357, or any free port when taken (--port to choose);
    a second countercheck ui reuses the running one. No web framework: the Rust standard library only.
  • countercheck report: one self-contained HTML page of every saved run (verdict, the agent's claim, each check
    and its output, protected changes, seal status, a targets × checks grid for matrix checks). No scripts and no
    outside resources (enforced by a Content-Security-Policy); every value is escaped, because receipts carry text from
    the agent's files. --open opens it in the browser.

Install

You use Command
Python pip install countercheck · uvx countercheck verify
macOS / Linux, Homebrew brew install datacrate360/tap/countercheck
macOS / Linux, any shell curl -fsSL https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.sh | sh
Windows 10/11, PowerShell irm https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.ps1 | iex

Windows needs Git for Windows. Every download is listed in SHA256SUMS.txt.

Countercheck v0.2.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 16:19
Immutable release. Only release title and notes can be modified.

Upgrade note: add the new session-start hook next to your existing stop hook (snippets in the README, "Agent
hooks"). Without it, hooks behave as in v0.2.0.

  • Security: countercheck hook session-start (Claude Code / Cortex Code SessionStart, Hermes
    on_session_start). The stop hooks locked the checks to HEAD, so an agent that committed an edit to a
    protected test or to checks.toml moved the "locked" rules with it and was let through. The new hook records the
    commit each session started from (in .git/countercheck/sessions/), and the stop hooks lock the checks to it.
    Add it to your hook settings (README "Agent hooks"). The benchmark was not affected: it pinned the base with
    COUNTERCHECK_BASE.

  • network = true on a check lets it use the internet under the macOS sandbox (writes stay confined; the receipt
    marks it). A check that fails while running without the internet gets a hint; the verdict stays FAILED, so a
    worker can't soften a failure by making a blocked network call on purpose. This removes the benchmark's only
    false alarms (checks that call a real website). The hint only appears when the output looks like a connection
    error.

  • Contributors: docs/architecture.md (the rules and one run step by step), step-by-step guides in
    .claude/skills/, a new example examples/ml-eval-threshold/, DCO sign-off for pull requests.

Install / upgrade: brew upgrade countercheck · pip install -U countercheck · uvx countercheck@latest · curl -fsSL https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.sh | sh

Countercheck v0.2.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 14:29
Immutable release. Only release title and notes can be modified.

Upgrade if you use Countercheck on Linux. In v0.1.0, when a check ran past its time limit, Countercheck
stopped it with kill -KILL -<process group>. The kill in procps-ng 4.0.4 (Ubuntu 24.04, Debian 13 and others)
can misread that and signal every process the user owns. v0.2.0 uses kill -s KILL -- -<group> and never signals
group ids of 1 or less; a test checks that a timed-out check's whole process group really stops. macOS was not
affected.

New

  • Check types (docs/checks.md): matrix (one check over many targets, a result per target),
    [[forbid]] (patterns that must not appear, reported as file:line), golden (output must match a locked
    reference: exact text, or CSV with a numeric tolerance and optional row sorting), budget (a printed
    METRIC name=value within limits) and [[coverage]] (every item in a locked list is found). Target lists,
    reference files and inventories must be protected, so a worker can't change what it is judged by.
  • Example: examples/data-migration/, a made-up two-tenant migration that uses
    every check type and fails for four explained reasons.
  • Claude Code hook: countercheck hook claude-stop blocks Claude Code's stop while the checks fail and passes the
    reasons back (docs/hooks/claude-code.md). Cortex Code reads the same hook format.
    A loop guard (COUNTERCHECK_MAX_NUDGES, default 3) means it never blocks forever.
  • Honest blockers: both hooks let an agent stop when its final message honestly says the work can't be
    finished (and it changed no protected file). The FAILED receipt is kept. Claims of success and any protected-file
    change are still pushed back.
  • Sandbox (macOS): localhost is allowed, so web tests with a local server and a browser work; the internet
    stays blocked.

Fixed

  • A receipt that recorded a cost (--cost-usd) could read back as BROKEN in countercheck show (a float lost one
    bit in JSON). Numbers now round-trip exactly.
  • Protected-file matching resolves ./, .. and empty path segments first, so ./tests/a is protected and paths
    outside the repository never match.
  • The PyPI source package includes the LICENSE file.

Tests

69 → 136 tests on macOS (134 on Linux), including property tests and tests that catch every surviving mutant
found by mutation testing in the receipt, claim and config code.

Install / upgrade: brew upgrade countercheck · pip install -U countercheck · uvx countercheck@latest · curl -fsSL https://raw.githubusercontent.com/datacrate360/countercheck/PROD/install.sh | sh

Countercheck v0.1.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 20:27
Immutable release. Only release title and notes can be modified.