---
version: "0.28.0"
title: "v0.28 — Takes + Think + Unified Model Config"
status: published
---

# v0.28 — Takes, Think, Unified Model Config

You upgraded from v0.27 (or earlier) to v0.28. New surface area:

- **Takes** — typed/weighted/attributed claims stored as fenced markdown
  tables and indexed in Postgres. Four kinds: `fact | take | bet | hunch`.
  Holders: `world | garry | brain | <slug>`.
- **`gbrain takes`** CLI — list / search / add / update / supersede / resolve.
- **Unified model config** — `models.default` replaces per-phase
  `dream.synthesize.model` etc. Aliases: `opus`, `sonnet`, `haiku`,
  `gemini`, `gpt`. CLI flag `--model <name>` overrides per-call.
- **Per-token MCP allow-list** — `access_tokens.permissions.takes_holders`
  controls which holders an MCP-bound token sees. Default: `["world"]`.
- **Three new MCP ops** — `takes_list`, `takes_search`, `think`.
- **`gbrain think` op surface** — registered now; pipeline lands in v0.28.x.

## What the migration did automatically

`gbrain apply-migrations --yes` runs three orchestrator phases:

1. **Schema verify** — schema migrations v37 (takes + synthesis_evidence)
   and v38 (access_tokens.permissions JSONB) ran; tables are present.
   (v31 was claimed by v0.25's eval_capture_tables, v32+v33 by v0.26's
   OAuth + admin dashboard, v34 by v0.26.5's destructive-guard columns,
   v35 by v0.26.8's auto-RLS event trigger, and v36 by v0.27's
   subagent provider-neutral persistence before v0.28 landed.)
2. **Backfill takes** — walked every page in the brain, parsed any fenced
   `<!--- gbrain:takes:begin/end -->` table found, populated the takes
   index in Postgres. Idempotent; safe to re-run.
3. **Re-chunk TODO queued** — `~/.gbrain/migrations/pending-host-work.jsonl`
   gained an entry asking you to re-chunk pages that had takes BEFORE
   v0.28. The chunker now strips fenced takes content (so per-token MCP
   visibility actually works) but the strip rule only applies to NEW
   imports. Legacy pages still have takes content baked into their
   `content_chunks` rows — re-chunk them to apply the strip retroactively.

## What you need to do as the host agent

### 1. Verify the upgrade

```bash
gbrain doctor
```

Expected: `takes_backfill_complete` and `takes_fence_chunk_leak` checks
both green. If either is red, follow the doctor's fix hint.

### 2. Re-chunk pages with pre-v0.28 takes (one-time, cosmetic for fresh installs)

For brains with existing fenced takes content in pre-v0.28 markdown:

```bash
# Identify pages with takes content that's been chunked into content_chunks
gbrain doctor --check takes_fence_chunk_leak

# If the check is RED, re-import those pages so the new chunker rule applies.
# Run only on the affected slugs (the doctor output enumerates them):
gbrain extract takes --rebuild
gbrain sync   # picks up the markdown delta if any
```

Fresh installs (no pre-v0.28 takes content): nothing to do.

### 3. Migrate to the unified model config (optional, mechanical)

Old per-phase keys still work in v0.28 with a deprecation warning.
v0.30 will remove them. Migrate when convenient:

```bash
# Old (deprecated):
gbrain config set dream.synthesize.model claude-sonnet-4-6
gbrain config set dream.patterns.model claude-sonnet-4-6

# New (one key controls everything):
gbrain config set models.default sonnet

# Per-op override (optional):
gbrain config set models.dream.synthesize opus

# Cleanup deprecated keys:
gbrain config unset dream.synthesize.model
gbrain config unset dream.patterns.model
```

### 4. Configure MCP token visibility (optional, security-relevant)

Existing tokens default to `permissions.takes_holders=["world"]` — they
see public claims only, never private hunches. Tokens for trusted agents
(e.g., your own OpenClaw deployment) need explicit broader visibility:

```bash
# List existing tokens
gbrain auth list

# Grant a token visibility into garry's takes (and brain-derived takes)
gbrain auth permissions <token-name> set-takes-holders world,garry,brain

# Or create a new token with the wider set up-front
gbrain auth create my-claude-desktop --takes-holders world,garry,brain
```

Tokens for third-party agents (claude.ai, public integrations) should
keep the default `["world"]` — Garry's hunches stay private.

### 5. Try the takes layer

```bash
# Add a take by hand
gbrain takes add people/alice-example \
  --claim "Strong technical founder I have ever met" \
  --kind take --who garry --weight 0.85 \
  --source "OH 2026-05-01"

# List
gbrain takes people/alice-example

# Search
gbrain takes search "technical founder"

# Resolve a bet
gbrain takes resolve people/alice-example --row 3 --outcome true \
  --value 50000000 --unit usd --source crustdata
```

## Verify

```bash
gbrain doctor         # all checks green; schema_version >= 32
gbrain stats          # numbers stable

# If any step failed, file an issue:
# https://github.com/garrytan/gbrain/issues
# Include: gbrain doctor output, ~/.gbrain/upgrade-errors.jsonl if it exists,
# and which step broke. The migration is designed to be idempotent — safe
# to re-run after fixing the underlying issue.
```

## What ships in v0.28.x as follow-ups

- `gbrain think` synthesis pipeline (gather → RRF → cite → synthesize)
- `gbrain takes seed <slug>` — LLM extracts claims from page prose
- Dream `auto_think` + `drift` phases (opt-in)
- Cross-page reference resolution in `source` columns

The op surfaces are registered in v0.28.0 so MCP/SDK callers can detect
them; the pipelines fill in incrementally without breaking the contract.
