mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
* fix(security): scope cross-source reads to the caller grant; close get_page exact-path leak One shared resolveRequestedScope() routes every source-scoped read op (query, code_callers/callees, search_by_image, code_blast/flow, get_page) through a single fail-closed trust+grant ladder: a remote caller's __all__ collapses to its granted sources (never the whole brain) and an explicit out-of-grant source_id is rejected. get_page's exact-match path now honors a federated grant via getPage(sourceIds[]) in both engines. Legacy bearer tokens carry their stored permissions.source_id grant (bounded, never widened). Also retries getConfig on transient connection loss. Closes #1924, #1371, #1393, #1336, #1603. * fix(ingest): non-string frontmatter no longer aborts lint/sync; embed/hook/catalog papercuts Parser coerces a non-string title to a string and falls back to inference for slug/type (never fabricating a "123" slug), with a lint NON_STRING_FIELD finding surfacing the malformed frontmatter; a defensive guard in content-sanity stops a non-string title from crashing the whole lint/sync run brain-wide. Plus: embed --catch-up no longer arms the overflowed 32-bit budget timer (and surfaces unembeddable chunks); the frontmatter pre-commit hook ships a correct .md/.mdx regex; and the skill catalog parses YAML block-scalar descriptions. Closes #1883, #1658, #1556, #1948, #1946, #1840, #1711. * v0.42.37.0 fix(security,ingest): source-isolation grant enforcement + non-string frontmatter guard + papercuts Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add NON_STRING_FIELD frontmatter validation class to docs for v0.42.37.0 The v0.42.37.0 non-string-frontmatter fix added an eighth validation class (NON_STRING_FIELD / lint code frontmatter-non-string-field). Update the two current-state docs that enumerate the validation classes: - skills/frontmatter-guard/SKILL.md (seven->eight + table row) - docs/integrations/pre-commit.md (seven->eight + table row) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
107 lines
4.1 KiB
Markdown
107 lines
4.1 KiB
Markdown
# Pre-commit hook for brain repos (v0.22.4+)
|
|
|
|
`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`.
|
|
|
|
## What the hook catches
|
|
|
|
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 |
|
|
|
|
## Install
|
|
|
|
For all registered sources that are git repos:
|
|
|
|
```bash
|
|
gbrain frontmatter install-hook
|
|
```
|
|
|
|
For one source:
|
|
|
|
```bash
|
|
gbrain frontmatter install-hook --source <id>
|
|
```
|
|
|
|
For force-overwrite of an existing pre-commit hook (writes a `.bak`):
|
|
|
|
```bash
|
|
gbrain frontmatter install-hook --force
|
|
```
|
|
|
|
The hook lands at `<source>/.githooks/pre-commit`. If `core.hooksPath` is
|
|
unset, the install also runs `git config core.hooksPath .githooks` so the
|
|
hook is picked up without manual git config.
|
|
|
|
## Bypass
|
|
|
|
Standard git escape hatch:
|
|
|
|
```bash
|
|
git commit --no-verify
|
|
```
|
|
|
|
This skips ALL pre-commit hooks. Use sparingly — the next time the user
|
|
runs `gbrain doctor`, the issues will surface.
|
|
|
|
## Uninstall
|
|
|
|
```bash
|
|
gbrain frontmatter install-hook --uninstall
|
|
```
|
|
|
|
If a `.bak` was saved during install, it's restored as the active hook.
|
|
Otherwise the hook is removed cleanly.
|
|
|
|
## Behavior on machines without gbrain installed
|
|
|
|
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.
|
|
|
|
## For downstream agent forks
|
|
|
|
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-hook` as above.
|
|
- **Brain repo is a separate registered source** (e.g. `~/brain` registered
|
|
as a source, host repo is `~/agent-fork`): install in the brain repo only;
|
|
agent-fork code doesn't need this hook.
|
|
- **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).
|
|
|
|
## How it fits into the broader frontmatter pipeline
|
|
|
|
```
|
|
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.
|