garrytan/gbrainmarkdown explorer
garrytan/gbrainmaster
skills / migrations

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 links table with inferred types.
  • Direction respects the subject-of-verb: people/alice --attended--> meetings/2026-04-03 reads naturally because the person is the subject.
  • link_source column distinguishes markdown from frontmatter from manual edges. Reconciliation on put_page only touches edges this page's frontmatter created — never other pages' edges.
  • origin_page_id provenance tracks WHICH page's frontmatter authored each edge, so multi-page overlap stays safe.

The field → type map

Frontmatter fieldOn page typeEdge typeDirection
company, companiespersonworks_atperson → company
foundedpersonfoundedperson → company
key_peoplecompanyworks_atperson → company (incoming)
partnercompanyyc_partnerperson → company (incoming)
investorsdeal, companyinvested_ininvestor → target (incoming)
leaddealled_roundlead → deal (incoming)
attendeesmeetingattendedperson → meeting (incoming)
sourcesanydiscussed_insource → page (incoming)
sourceanysourcepage → source (outgoing)
related, see_alsoanyrelated_topage → 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:

  1. Schema phase — ALTER TABLE adds link_source, origin_page_id, origin_field. Swaps unique constraint to include them. ~10s.
  2. 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.
  3. 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-frontmatter to 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

  1. gbrain doctor — surfaces any partial migrations and any post-upgrade failures recorded in ~/.gbrain/upgrade-errors.jsonl.
  2. Paste the recovery hint doctor prints.
  3. 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.
Continue exploring589 Markdown documents in the local repository