Open-source guardrail

Telling CI to skip a commit or push

AgentTrail Guard lets this run by default, and writes the match to its local decision log so you can see how often it happens.

Default action
Warn
Severity
Medium severity
Library version
0.2.1Sep 29, 2026

What it catches, and what it misses

Written into the rule itself, next to what it matches, so you can judge it before you trust it.

Warns on a commit or push that tells CI not to run: a git commit whose message carries [skip ci], [ci skip], [no ci], [skip actions], [actions skip], Azure Pipelines' [skip azp] family or ***NO_CI***, or a skip-checks: true trailer, and git push -o ci.skip / --push-option=ci.skip. GitHub Actions, GitLab, Azure Pipelines, CircleCI and Bitbucket each honour some of these, in any letter case, so the change lands with no check run against it. Deliberately NOT matched: skip-checks: false, near misses such as [ci-skip] or [skip deploy], other push options, and a commit message that only names git push -o ci.skip. Misses a message read from a file (git commit -F msg.txt), a marker added when a pull request is merged on the hosting site, and a push option set in git config. A global flag between git and commit/push is tolerated (git -C <dir> commit …, --no-pager, -c k=v), and an absolute tool path such as /usr/bin/git still matches; a flag that itself runs a program is not read. A quoted MENTION is not a use: a search, an echo or a curl --data body that only names this command is left alone, as long as every shell metacharacter stays inside the quotes. git commit is NOT one of those carriers here: the marker is read from the commit message, so a message that quotes [skip ci] does skip CI and still warns.

Tested on every build

The rule must match every command on the left and none on the right, or the library does not build. Catching the real thing is easy; staying quiet on the near-miss is the hard part.

Catches (15)

  • git commit -m "chore: bump version [skip ci]"
  • git commit -am "[ci skip] regenerate fixtures"
  • git commit -m "wip [no ci]"
  • git commit -m "docs: typo [skip actions]"
  • git commit -m "[SKIP CI] release"
  • git commit -m "update lockfile" -m "skip-checks: true"
  • git commit -m "***NO_CI*** sync"
  • git commit -m "tidy [skip azp]"
  • git commit -F - <<'EOF' chore: format [skip ci] EOF
  • git add -A && git commit -m "lint [ci skip]" && git push
  • git push -o ci.skip origin main
  • git push --push-option=ci.skip origin feature/x
  • git --no-pager commit -m "wip [skip ci]"
  • git -C /repo push -o ci.skip origin main
  • PowerShellgit commit -m "chore: bump version [skip ci]"

Stays quiet on (12)

  • grep -rn "git commit -m chore: bump version [skip ci]" docs/
  • echo "never run git commit -m chore: bump version [skip ci]"
  • curl --data "we ran git commit -m chore: bump version [skip ci]" https://api.example.com/comments
  • git commit -m "Skip the flaky CI job on forks"
  • git commit -m "fix [ci-skip] parsing"
  • git commit -m "chore: [skip deploy]"
  • git commit -m "ci: set skip-checks: false"
  • git commit -m "docs: explain git push -o ci.skip"
  • git log --grep "[skip ci]"
  • git push -o merge_request.create origin feature/x
  • git push origin main
  • git commit --amend --no-edit

What "warn" means in each app

The guard runs as a hook in each app, and each app gives a hook different powers. Here is what this rule's default action does in each one.

Claude Code
The call runs, and the match is written to the local decision log.
Cursor
The call runs, and Cursor shows nothing. The match is still written to the decision log.
Codex CLI
The call runs. Codex's terminal UI shows a hook line (a codex exec run shows nothing), and the match is written to the decision log.

Each app hands the guard a different set of calls: in a Cursor sandbox run mode, for one, some terminal commands run without reaching the guard at all. Read the notes for Cursor and for Codex CLI before you rely on a rule there.

Change what it does in one command

Turn it off, change its action, or silence it on one command shape. The narrow one is allow: the rule keeps catching everything else.

agenttrail-guard
$agenttrail-guard guardrails show ti.ci-skip-marker# everything about it
$agenttrail-guard guardrails set-action ti.ci-skip-marker ask# block, ask or warn
$agenttrail-guard guardrails allow ti.ci-skip-marker '<pattern>'# silence one shape
$agenttrail-guard guardrails disable ti.ci-skip-marker# turn it off

Put these guardrails in front of your agent.

AgentTrail Guard is free and open source. It checks every command and file change against the whole library before your agent runs it, on your machine, with no account.

bash
$npm i -g @agenttrail/guard
Read the source on GitHub