Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Gates

[[gates]] lists the commands that must pass before you are asked to review a change. Each [[gates]] table is one gate; they run in order, user gates before project gates. For intentional failures, manual /review --skip-gates opens gate-free review and /commit --skip-gates bypasses only that invocation's final publication gates (Committing). Neither changes the configured gates for later turns or commits.

[[gates]]
name = "check"
paths = ["**/*.rs", "Cargo.toml"]
command = ["cargo", "check", "--all-targets"]

[[gates]]
name = "test"
modes = ["code"]
paths = ["**/*.rs"]
command = ["cargo", "test"]
retry_limit = 2

[[gates]]
name = "fmt"
paths = ["**/*.rs"]
command = ["cargo", "fmt", "--check"]
retry_limit = 1

[[gates]]
name = "docs"
paths = ["**/*.md"]
command = ["yucky", "--check", "{files}"]
KeyMeaningDefault
nameShown in status lines and to the model.Required
pathsGlobs over the files the turn changed; the gate runs when any matches. * stops at /, ** does not.Any path
commandShell string or executable-and-arguments array, run in the worktree. Exit 0 passes. {files}: see below.Required
retry_limitFailures the model may fix on its own before the review opens with the failure attached.3

An array runs directly, without a shell: its first string is the executable and all remaining strings are literal arguments. No variable expansion, globbing, pipes, or redirection occurs. Use a string, such as command = "cargo test 2>&1 && echo passed", when you need sh -c. Both forms capture stdout and stderr; direct execution needs no 2>&1.

Arrays must contain a nonempty executable, only strings, and no NUL bytes. {files} must occupy a whole argument and cannot appear in the executable.

modes optionally restricts a gate to code, design, or both. Omission is unrestricted. Explicit empty lists, unknown or wrong-case names, and non-string values are configuration errors. Repeated valid modes are deduplicated in stable order. The mode allowlist and path globs must both match. Quick and recorded review turns count as code; plan turns are read-only and run no gates.

[[gates]]
name = "design-check"
modes = ["design"]
paths = ["designs/**/*.md"]
command = "check-designs {files}"

check-designs represents your own project command. Leave shared checks such as Markdown formatting unscoped. Existing gates need no edits and remain unrestricted. Final publication selects modes from accepted unpublished work, not the session's current mode.

A gate's files are the changed paths its paths match, or every changed path when it has none, less any that were deleted. In an array, each {files} argument expands to those paths as separate literal arguments. In a shell string, they are each quoted for the shell. HEPH_GATE_FILES holds them one per line in both forms. A gate that uses {files} and has no files is skipped. See Checking only the changed files.

A gate may run for up to thirty minutes; its output streams into the conversation as it arrives and is given to the model whole when it fails. CARGO_TARGET_DIR is set to the project's shared target directory when [worktree] shared_target is on (the default).

Gates need no permission, but do acquire matching execution locks. Array commands match exec(program) args(...); strings match shell(<expanded command>), after file expansion in both cases. Acceptance Gates explains when they run and what the model sees.