v0.13.0
skills/migrations/v0.13.0.md
name: v0.13.0 version: 0.13.0 headline: YAML frontmatter now creates typed graph edges automatically
v0.13.0 Migration: Frontmatter Relationship Indexing
TL;DR: this release teaches the knowledge graph to read your YAML frontmatter. Every company:, investors:, attendees:, key_people:, partner:, lead:, and related: field you already wrote now surfaces as a typed graph edge. gbrain graph <hub-entity> --depth 2 goes from returning ~7 nodes to 50+ on a real brain without you changing a word of content.
For most users: run gbrain upgrade and you're done. The orchestrator handles schema + backfill in 2-5 minutes on a 46K-page brain. You immediately see richer results from gbrain graph queries.
What changed
Before v0.13: graph edges came only from [Name](path) markdown refs. Your frontmatter was indexed for search but did not create graph relationships.
After v0.13:
- YAML frontmatter fields project into the
linkstable with inferred types. - Direction respects the subject-of-verb:
people/alice --attended--> meetings/2026-04-03reads naturally because the person is the subject. link_sourcecolumn distinguishesmarkdownfromfrontmatterfrommanualedges. Reconciliation onput_pageonly touches edges this page's frontmatter created — never other pages' edges.origin_page_idprovenance tracks WHICH page's frontmatter authored each edge, so multi-page overlap stays safe.
The field → type map
| Frontmatter field | On page type | Edge type | Direction |
|---|---|---|---|
company, companies | person | works_at | person → company |
founded | person | founded | person → company |
key_people | company | works_at | person → company (incoming) |
partner | company | yc_partner | person → company (incoming) |
investors | deal, company | invested_in | investor → target (incoming) |
lead | deal | led_round | lead → deal (incoming) |
attendees | meeting | attended | person → meeting (incoming) |
sources | any | discussed_in | source → page (incoming) |
source | any | source | page → source (outgoing) |
related, see_also | any | related_to | page → target (outgoing) |
Fields on pages not matching the On page type column are ignored for that mapping. E.g. a person page with key_people: is ignored (makes no sense); only company pages produce works_at incoming from key_people.
How to upgrade
gbrain upgrade
That runs the v0.13.0 orchestrator:
- Schema phase — ALTER TABLE adds
link_source,origin_page_id,origin_field. Swaps unique constraint to include them. ~10s. - Backfill phase — walks every page, extracts frontmatter edges via the batch-mode resolver (pg_trgm fuzzy match, zero LLM calls, zero API costs). Progress prints every 500 pages. 2-5 min on a 46K-page brain.
- Verify phase — asserts the backfill produced rows + records completion.
The migration is resumable. If it dies mid-backfill (OOM, network blip), re-run gbrain upgrade and it picks up where it left off via ON CONFLICT DO NOTHING on the new unique constraint.
Verification
# Link count should reflect the ~15-20K new frontmatter edges on a typical brain.
gbrain stats
# Sample a hub entity from your brain — depth-2 should return many more nodes than before.
gbrain graph <hub-entity-slug> --depth 2
# Filter to specific edge types (new in v0.13).
gbrain graph <hub-entity-slug> --depth 2 --type yc_partner,invested_in
# Count edges by provenance.
gbrain call get_stats --json
Troubleshooting
Migration failed mid-backfill. Re-run gbrain upgrade. Resumable via ON CONFLICT DO NOTHING + origin_page_id scoping.
PGLite without pg_trgm GIN index. The migration logs an INFO line and falls back to ILIKE matching. Fuzzy-match quality reduced, but migration completes successfully. No user action required.
Unresolvable names in the extract summary. The backfill prints a top-20 preview of frontmatter names that didn't resolve to any page. These are usually people/companies you've mentioned in frontmatter but never created pages for. Options:
- Create the missing pages (then run
gbrain extract links --source db --include-frontmatterto backfill). - Ignore — unresolved names stay unresolved until you create a page for them.
Agents using put_page see a new unresolved field in auto_links. This is additive. Existing agents that ignore unknown response fields keep working. Agents that want to escalate unresolved names: read response.auto_links.unresolved.
attendee vs attended type normalization. Legacy rows with link_type='attendee' or link_type='mention' keep working. Normalization to the v0.13 canonical names (attended, mentions) is deliberately NOT in this migration — it's a separate semantic concern. The gbrain normalize-types command (v0.14) handles it opt-in.
For downstream agent skill forks
If you maintain a fork of GBrain skills (a custom OpenClaw deployment or agent-fork), check docs/UPGRADING_DOWNSTREAM_AGENTS.md for the v0.13 section. Verdict: no action required for most skills. Three skills (meeting-ingestion, enrich, idea-ingest) get a new optional phase if you want to consume the auto_links.unresolved field.
If something goes wrong
gbrain doctor— surfaces any partial migrations and any post-upgrade failures recorded in~/.gbrain/upgrade-errors.jsonl.- Paste the recovery hint doctor prints.
- If that fails too, file an issue: https://github.com/garrytan/gbrain/issues with doctor output + upgrade-errors.jsonl contents. This is how the gbrain maintainers find fragile upgrade paths.