gbrain frontmatter install-hook installs a git pre-commit hook in your
brain source's repo that runs gbrain frontmatter validate against staged
.md and .mdx files. Malformed frontmatter blocks the commit. Bypass with
git commit --no-verify.
The same eight validation classes the frontmatter-guard skill and
gbrain doctor's frontmatter_integrity subcheck report:
| Code | What it catches |
|---|---|
MISSING_OPEN |
File doesn't start with --- |
MISSING_CLOSE |
No closing --- before first heading |
YAML_PARSE |
YAML failed to parse (syntax or structure) |
SLUG_MISMATCH |
slug: in frontmatter doesn't match path-derived slug |
NULL_BYTES |
Binary corruption (\x00) anywhere in the content |
NESTED_QUOTES |
title: "outer "inner" outer" shape that breaks YAML |
NON_STRING_FIELD |
title/type/slug is an unquoted non-string scalar (title: 123) |
EMPTY_FRONTMATTER |
--- ... --- with nothing meaningful between |
For all registered sources inside a git repo (the source's own repo, or a
subdirectory of a host repo — the same shapes gbrain sync accepts):
gbrain frontmatter install-hookFor one source:
gbrain frontmatter install-hook --source <id>For force-overwrite of an existing pre-commit hook (writes a .bak):
gbrain frontmatter install-hook --forceThe hook lands at <git root>/.githooks/pre-commit — the source's own repo,
or the enclosing host repo when the source is registered as a subdirectory of
one (see the topology cases below). If core.hooksPath is unset, the install
also runs git config core.hooksPath .githooks so the hook is picked up
without manual git config. Pointing core.hooksPath at .githooks makes git
run every executable script in that directory and ignore .git/hooks/* for
every hook type, so the installer writes the gbrain hook but leaves
core.hooksPath unset (hook written …; core.hooksPath left unset) and
prints the reason plus the manual wiring step when:
core.hooksPathis already set — in any scope, a global one from husky, secret-scanner templates or dotfiles counts — to somewhere other than.githooks(git reads hooks only from there, so the gbrain hook would be inert) — copy.githooks/pre-commitinto that directory, or pointcore.hooksPathat.githooks; a value that already resolves to.githooksis left alone and counts as wired;.githooks/already holds other executable hook scripts (third-party clones commitpost-commit,pre-push, … there as a convention) — review them, thengit -C <root> config core.hooksPath .githooks;.git/hooks/holds an active hook (executable, not*.sample— a host repo's own pre-push, commit-msg, framework-installed hooks, …) — move them into.githooks/, then run the same command.
A source is skipped only when it sits outside any git repo (skipped, Not inside a git repository: …), its path contains a line terminator, which
the generated shell script could not carry safely (skipped, source path contains a line terminator; refusing to install hook), or .githooks/ /
.githooks/pre-commit is a symlink (Refusing to write through a symlink: …
— the installer never writes or removes through the link; the other sources
still install).
Standard git escape hatch:
git commit --no-verifyThis skips ALL pre-commit hooks. Use sparingly — the next time the user
runs gbrain doctor, the issues will surface.
gbrain frontmatter install-hook --uninstallIf a .bak was saved during install, it's restored as the active hook.
Otherwise the hook is removed cleanly.
The hook script checks for gbrain on $PATH. When missing, it prints a
one-line warning to stderr and exits 0 — commits aren't blocked just because
a developer hasn't installed gbrain locally. Once gbrain is installed, the
hook resumes blocking malformed pages.
If your OpenClaw wraps gbrain in a host repo that's not the brain repo itself, you may want a separate hook strategy:
- Brain repo IS the host repo (gbrain skills + brain pages in one repo):
install via
gbrain frontmatter install-hookas above. - Brain repo is a separate registered source (e.g.
~/brainregistered as a source, host repo is~/agent-fork): install in the brain repo only; agent-fork code doesn't need this hook. - Brain is a subdirectory of the host repo (the
<workspace>/brainlayoutgbrain bootstrapcreates and registers withgbrain sources add <id> --path <workspace>/brain): the hook installs at the host repo root, scoped tobrain/— staged files elsewhere in the host repo (README, AGENTS.md, code) are never validated. Several nested sources in one host repo share a single hook (their scopes union;--uninstall --source <id>drops only that source's scope); a source registered at the root widens it to the whole repo. Known limitation: a nested page that declaresslug:explicitly can be reported asSLUG_MISMATCH, becausefrontmatter validatederives the expected slug from the git root; pages gbrain writes itself carry noslug:, so bootstrap-created brains are unaffected. - Brain repo is auto-generated (e.g. by a sync daemon writing to a
bucket): skip the hook entirely; gate at the writer instead via
import { writeBrainPage } from 'gbrain/brain-writer'(planned in a later release; currently the CLI is the surface).
agent writes a page git commit doctor scan
↓ ↓ ↓
[source content] → [pre-commit hook validates] → [frontmatter_integrity check]
↓ ↓ ↓
raw file on disk blocks malformed commits surfaces existing issues
↓
`gbrain frontmatter validate
<source-path> --fix`
(writes .bak backups)
The hook is the write-time gate; doctor is the audit gate; the CLI is the
fix tool. They share parseMarkdown(..., {validate:true}) as the single
source of truth for what counts as malformed.