GateBolt

Connect an agent

GateBolt records every change your coding agent makes to a repo — the files it declared before editing, reconciled against what it actually touched. Setup takes about two minutes.

Claude CodeCodexsoonKirosoon

You’ll needNode 20+·git·a repo with a remote

  1. 1

    Install the CLI

    The GateBolt CLI runs the loop. Install it once, globally, so gatebolt is on your PATH.

    $npm i -g @gatebolt/cli

    Confirm it’s ready with gatebolt --version.

  2. 2

    Sign in

    Authorize the CLI in your browser — no keys to copy or paste.

    $gatebolt login
    Approve in the browser, then pick your organization in the terminal.
  3. 3

    Set up your repo

    Run this once inside the repo. It links the repo to GateBolt and wires Claude Code’s hooks.

    Enforcement

    Default. Claude declares as it works; nothing is blocked.

    $cd your-repo && gatebolt init
    What it writes
    • .gateboltcommit thisthe repo’s GateBolt id — shared so every clone reconciles the same repository
    • .claude/settings.jsoncommit thisthe declare → observe hooks Claude Code runs — committed so every clone and worktree enforces
    • .git/hooks/pre-pushlocala backstop that reconciles before a push
  4. That's it — make a change

    Open Claude Code in the repo and ask it to edit something. It declares the files first, then reconciles the diff when the turn ends — flagging anything it didn’t declare. Here’s a change where it caught a stray file:

    reconciled · main
    CClaude Codeclaude-opus-4-8· launched by you· 2m ago
    100
    Critical drift
    Touched 1 undeclared secrets file: .env · 2 matched, 1 unexpected, 0 missing
    Declared — what it said
    src/greeting.ts
    src/farewell.ts
    Observed — what it did
    src/greeting.ts+3
    src/farewell.ts+4
    .envsecrets+1
    a1f9…c3d77b02…9e14chain intact

    GateBolt doesn’t block the edit — it records it, scores the severity, and seals it in the tamper-evident ledger. Clean changes stay quiet; drift like this rises to the top.

    Get started

Add a second witness

Everything above is the agent reporting on its own work. A GateBolt step in CI reconciles the same declarations from a machine the agent never touched. Both records are kept on the change, side by side — neither is a correction of the other.

Optional
  1. 1Create a key with the CI scope under API keys. It can only witness — it can’t declare a change or add a repository, so a leaked runner secret can’t author the provenance it attests to.
  2. 2Save it as the repository secret GATEBOLT_KEY (GitHub → Settings → Secrets and variables → Actions).
  3. 3Commit this as .github/workflows/gatebolt.yml.
.github/workflows/gatebolt.yml
name: GateBolt
on: [push]
jobs:
  provenance:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: npx @gatebolt/cli ci
        env:
          GATEBOLT_KEY: ${{ secrets.GATEBOLT_KEY }}

fetch-depth: 0 is required — GateBolt refuses to run against a shallow clone rather than record a diff it knows is wrong. The step stays green whatever the drift unless you pass --fail-on, and skips itself on a pull request from a fork, where GitHub withholds the secret.

If something’s off

The hooks aren't firing in Claude Code
Settings load when a session starts. Open a new Claude Code session in the repo after running gatebolt init.
A hook says “gatebolt: command not found”
The hooks call gatebolt directly — make sure it’s installed globally (step 1) and that which gatebolt resolves.
The CI step says there's nothing to witness
A declaration is matched by branch, then by whether its base commit is an ancestor of the one being built. After a squash-merge the push is on main while the declaration belongs to the feature branch, so nothing matches — the pull request’s own run already witnessed that work. If it’s a branch build, check fetch-depth: 0 is set.
Strict mode is blocking my edits
That’s the point of strict — Claude must declare first. To make it advisory instead, re-run gatebolt init --enforce lenient.