---
title: "How to check issues, notes, and docs before a commit"
description: "Run store checks through a git hook and reuse the gates in CI."
type: how-to
canonical_url: https://eng.rip/how-to-check-issues-notes-and-docs-before-a-commit/
---

# How to check issues, notes, and docs before a commit

Use gaff's pre-commit hook to refuse commits with broken issue references, broken note links, or Diátaxis type faults. Start with initialized stores and the tools installed; see [Tools](<tools.md>).

## Declare the checks

Create `.gaff/gaff.yml` with these entries, or add them to its existing `git:` list:

```yaml
git:
  - name: issues
    on: [pre-commit]
    command: ["tisket", "check"]
  - name: notes
    on: [pre-commit]
    command: ["zettel", "check"]
  - name: docs
    on: [pre-commit]
    command: ["diataxis", "check"]
```

Each entry has a `name`, an `on` list of git hooks, and a `command` argument array. Commands run with the repository as their working directory. `required` defaults to `true`; `false` reports a failure and runs the remaining entries.

If the repository vendors skills, add an entry with `command: ["almanac", "sync", "--check"]` to the same hook. That command exits 1 when a pinned skill drifts. See [How to vendor agent skills with almanac](<how-to-vendor-agent-skills-with-almanac.md>).

Keep these checks on `pre-commit`. Git passes the remote name and URL to pre-push commands, and gaff forwards those arguments. A pre-push entry running `zettel check` fails with `unexpected argument 'origin'`.

## Install and validate the hook

Run these commands in order:

```sh
gaff init --git
gaff check
```

Installation prints `installed: pre-commit` and writes `.git/hooks/pre-commit`. Gaff never sets `core.hooksPath`. It keeps a hook it did not write as `<hook>.local` and calls that hook first.

`gaff check` validates the configuration. It exits 1 when a named hook is not installed, so installation must come first. Run `gaff init --git` again after editing the hooks list; it writes one script per hook.

On a commit, inspect failures from the named check:

| Check | Result |
| --- | --- |
| `tisket check` | Reports broken references and store problems; prints `no problems found` when clear. |
| `zettel check` | Reports broken links and invalid provenance. A single problem exits 1 with `1 problem(s):`, the note, and the target. |
| `diataxis check` | Faults exit 1. Advice does not fail the check. |

## Run the same gates in CI

Run the declared pre-commit entries against HEAD:

```sh
gaff ci --hook pre-commit
```

The command prints `gaff ci: ok` when the checks pass. Plain `gaff ci` also runs pre-push entries and fails when none is declared.

For generated GitHub workflows, declare `github:` entries using the [configuration keys](https://gaff.eng.rip/configuration/). A step with `use_git: <entry>` reuses that git entry's command.

Render the workflows, then commit `.github/workflows/<name>.yml`:

```sh
gaff init --github
```

Check the committed workflows for drift:

```sh
gaff check --github
```

The check exits 1 when a committed workflow differs from the configuration.

## Remove the hooks

To remove gaff's scripts and restore the kept hooks, run:

```sh
gaff init --git --uninstall
```
