Configuration¶
grip reads configuration from four places. Higher in the list wins.
- Command-line flags, e.g.
--passing-score 80. - Environment variables prefixed with
GRIP_, e.g.GRIP_PASSING_SCORE=80. .grip.tomlat the repository root.[tool.grip]inpyproject.tomlat the repository root.
grip config prints the effective result.
Options¶
| Option | Default | Description |
|---|---|---|
passing_score |
70 |
Minimum Grip Score (0 to 100) required to let the commit or push through. |
difficulty |
"normal" |
easy, normal or hard. Changes both the questions and the grading strictness. |
provider |
"auto" |
auto, anthropic, openai (any OpenAI-compatible API), ollama, claude-code, codex, gemini or fake. auto uses the first of Claude Code, Codex and Gemini CLI found on PATH, else anthropic; grip status shows what it picked. |
model |
provider default | Model identifier passed to the provider. Empty uses the provider's default (claude-opus-5 for Anthropic, the CLI's own default for coding agents). Required for openai and ollama. |
effort |
"medium" |
Reasoning effort for models that support it: low, medium, high, xhigh, max, or none to omit the parameter. Ignored for Haiku 4.5 and non-Anthropic providers. |
api_key_env |
provider default | Name of the environment variable holding the API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, OLLAMA_API_KEY). |
base_url |
provider default | Override the API base URL, for proxies or self-hosted servers. |
exclude |
lockfiles and generated files | Globs removed from the diff. Patterns without / match at any depth. |
max_diff_bytes |
200000 |
Larger patches are truncated before being sent. |
remember_passes_hours |
24 |
How long a passed diff is remembered. 0 disables. |
cache_hours |
24 |
How long the questions (and the whiteboard) written for a diff are reused when the same diff is quizzed again, so a retry after a failed quiz costs one grading call instead of two. 0 asks the model every time; --fresh does so once. |
hook_mode |
"quiz" |
What the git hook asks for. quiz: questions in the terminal. whiteboard: the whiteboard opens in your browser and you defend the change there. With no browser to open (over SSH, no display), the hook falls back to the terminal quiz. grip quiz always asks in the terminal. |
require_tty |
false |
Fail (exit 2) instead of skipping when no interactive terminal is available. |
fail_open |
false |
Let the commit or push through when the provider errors out. |
timeout |
120 |
Per-request timeout for provider calls, in seconds. |
The default exclude list is:
exclude = [
"*.lock", "*.lockb", "*.min.js", "*.min.css", "*.map", "*.snap", "*.svg",
"*.pb.go", "*_pb2.py", "*.generated.*",
"package-lock.json", "yarn.lock", "pnpm-lock.yaml", "Cargo.lock", "poetry.lock",
"uv.lock", "go.sum", "Pipfile.lock", "composer.lock", "Gemfile.lock",
]
Setting exclude replaces the list; copy the defaults if you want to extend them.
Examples¶
A strict team setup in .grip.toml:
Defend every push on the whiteboard instead of in the terminal:
Or for yourself only: export GRIP_HOOK_MODE=whiteboard.
A local-only setup with Ollama:
Anthropic through a corporate gateway, keeping the key in a custom variable:
provider = "anthropic"
base_url = "https://llm-gateway.example.com"
api_key_env = "COMPANY_ANTHROPIC_KEY"
Per-developer overrides without touching the shared file:
Environment variables that are not options¶
| Variable | Effect |
|---|---|
GRIP_SKIP=1 |
Skip the quiz once. |
CI=true |
Skip the quiz (set by every CI provider). |
PRE_COMMIT_FROM_REF / PRE_COMMIT_TO_REF |
Set by the pre-commit framework at pre-push; grip uses them as the diff range. |
GRIP_FAKE_SCRIPT / GRIP_FAKE_DELAY |
Script file and artificial latency for the fake provider. See Providers. |