Write a check¶
This guide shows you how to create a custom check that validates a standard across your repositories.
Create the check file¶
Checks are YAML files stored in data/checks/. The filename becomes the check's slug (identifier).
Create data/checks/has-readme.yaml:
name: Has README
description: Ensures every tracked repo has a README.md
targets:
regex: ".*" # all repos
script: |
test -f README.md
That's it — Grimoire picks up new check files automatically on the next refresh cycle.
Understand the structure¶
Every check definition has these fields:
| Field | Required | Description |
|---|---|---|
name |
Yes | Display name on the dashboard |
description |
Yes | What the check validates |
targets |
Yes | Which repos to run against (see targeting) |
script |
Yes | Bash script to execute |
schedule |
No | Cron expression; defaults to refresh_schedule |
enabled |
No | true (default) or false |
severity |
No | "error" (default) or "warning" — controls how failures appear on the dashboard |
Exit codes¶
A check script communicates its result via exit code:
| Exit code | Result |
|---|---|
0 |
✅ Pass |
| Any non-zero | ❌ Fail (reported as error or warning based on severity) |
Script environment¶
Scripts execute inside the cloned repository directory for the target branch. Available environment variables:
| Variable | Description |
|---|---|
REPO_OWNER |
Repository owner |
REPO_NAME |
Repository name |
REPO_FULL_NAME |
owner/name |
BRANCH |
Branch being checked |
Scripts have a 5-minute timeout and output is capped at 64 KB.
Targeting¶
The targets field determines which repos a check runs against. You must specify exactly one strategy:
All repos (regex match-all)¶
Specific repos (explicit list)¶
Pattern match (regex)¶
Dynamic (script)¶
Run a script in each repo — include the repo if it exits 0:
Set severity¶
By default, check failures are reported as errors. For advisory checks, set severity to warning:
Warnings appear with a yellow indicator on the dashboard instead of red, and carry a lower weight in the backlog.
Set a custom schedule¶
By default, checks run on the global refresh_schedule. Override with a cron expression:
Trigger manually¶
# Run against all targeted repos
curl -X POST http://localhost:8000/api/checks/has-readme/run
# Run against a specific repo
curl -X POST "http://localhost:8000/api/checks/has-readme/run?repo=owner/repo"
Disable a check¶
Toggle from the API:
Or set enabled: false in the YAML file.