v0.40.5
skills/migrations/v0.40.5.md
version: v0.40.5.0 feature_pitch: Federated Sync v2 — parallel source sync, push-triggered webhooks, async embedding, per-source health dashboard target_files:
- sources.config (per-source webhook_secret, github_repo, tracked_branch, priority)
- sources.config.federated (auto-embed-backfill on flip) manual_steps: required for users with multiple federated sources
v0.40.5.0 — Federated Sync v2
GBrain now treats every federated source as an independent unit. Cross-source sync runs in parallel, GitHub pushes can trigger sync within seconds, embedding decouples from the sync pipeline so onboarding doesn't block, and gbrain sources status shows per-source health.
What the orchestrator did automatically
gbrain apply-migrations --yes (run by gbrain upgrade) handled:
- Migration v92 — partial expression index on
sources.config->>'github_repo'for fast webhook source-lookup - Schema bootstrap probe — legacy brains pick up the same index via
initSchema() - Per-source sync lock —
SYNC_LOCK_IDconstant now resolves togbrain-sync:default; per-source sync acquiresgbrain-sync:<source_id> - Phantom-redirect lock parity — phantom-redirect pass uses the same per-source key so cross-source isolation works the same way
- Facts backstop source-scoping fix —
performSyncnow passes sourceId toengine.getPage(previously could mis-attribute facts to wrong source on slug collision)
What you should do manually
Run these steps once per machine after gbrain upgrade:
1. Verify the new surfaces work
# Per-source health dashboard
gbrain sources status
# Doctor should surface federation_health
gbrain doctor
# Sync trigger CLI smoke
gbrain sync trigger --help
2. Set up webhook-driven sync per source
For each federated source whose repo lives on GitHub, register a webhook:
gbrain sources webhook set <source-id> --github-repo <owner>/<repo>
# Save the printed secret — you only see it once
Then in the GitHub repo settings → Webhooks → Add webhook:
- Payload URL:
<your gbrain serve --http URL>/webhooks/github - Content type:
application/json - Secret: (the secret printed by
webhook set) - Events: Just the push event
- Active: checked
To rotate later: gbrain sources webhook rotate <source-id>. The new secret invalidates the old one immediately; update the GitHub webhook config to match.
3. (Optional) Set source priority
Per-source priority drives autopilot dispatch order. The default brain typically wants high; archival sources can use low:
# Hand-edit sources.config via SQL or via a future `gbrain sources config set` command
# In v0.40.5 set via direct SQL:
gbrain exec "UPDATE sources SET config = jsonb_set(config, '{priority}', '\"high\"') WHERE id = 'default'"
gbrain exec "UPDATE sources SET config = jsonb_set(config, '{priority}', '\"low\"') WHERE id = 'media-corpus'"
Recognized values: high (priority -10), normal (0), low (5). Unknown values fall back to normal with a once-per-source stderr warning.
4. (Optional) Tune embed-backfill budget caps
Default caps: $10/job, $25/source/24h. Override via DB config:
gbrain config set embed.backfill_max_usd 20 # raise per-job cap
gbrain config set embed.backfill_max_usd_per_source_24h 100 # raise 24h cap
gbrain config set embed.backfill_cooldown_min 30 # raise cooldown window
5. (Optional) Opt out of parallel sync entirely
If something breaks and you need v0.39 behavior immediately:
gbrain config set sync.federated_v2 false
gbrain jobs supervisor restart
Per-source lock + migration v92 stay on regardless (those are correctness fixes, not features).
Verify the outcome
After completing the steps above:
- Parallel sync works:
gbrain sync --allshould complete noticeably faster than before. If multiple sources used to take minutes-to-hours, you should see them run concurrently. - Webhook fires:
git pushto a webhook-configured source should produce a[dispatch]line in autopilot logs (orgbrain jobs listshould show a freshsyncjob within seconds). - Dashboard is accurate:
gbrain sources statusshould match the numbers fromgbrain statsper source. - No regressions: Existing
gbrain sync --source <id>still works the same way;gbrain syncwith no flags still syncs the default source.
If something goes wrong
gbrain doctor is your first stop:
federation_health: warn— surfaces lag, embed coverage, or queue depth issues per source with paste-ready remediation commandsfederation_health: fail— surfaces critical lag (>24h) or embed coverage (<50% with >1000 chunks)
For partial states or unexpected errors, file an issue at https://github.com/garrytan/gbrain/issues with:
- Output of
gbrain doctor --json - Output of
gbrain sources status --json - Contents of
~/.gbrain/upgrade-errors.jsonlif present - Which step broke