# v0.29.1 migration — Salience + Recency as two orthogonal options

`gbrain upgrade` runs `gbrain apply-migrations` automatically. Most users
won't need to do anything else. If you hit issues or want to verify the
upgrade succeeded, run the steps below.

## What changed

This release adds two new optional ranking axes to the `query` MCP op:

- `salience: 'off' | 'on' | 'strong'` — boost pages with high
  `emotional_weight` + many active takes. NO time component.
- `recency: 'off' | 'on' | 'strong'` — boost pages with recent
  `effective_date`, per-prefix decay. NO mattering signal.

They're TRULY ORTHOGONAL — either, both, or neither. The agent decides
per query, with `--explain` output showing the resolved values and
sources.

Existing v0.29.0 callers (no new params) get UNCHANGED behavior.

## What the agent should do

Read `skills/conventions/salience-and-recency.md` (auto-installed by
the skillpack). Then in your `gbrain query` calls:

1. Pass `salience='on'` for "what matters about X" queries (catch up,
   meeting prep, conversation recall).
2. Pass `recency='on'` for "what's new on X" queries (latest, this
   week, today's news).
3. Pass both for "what's been going on with X" queries.
4. Omit both for canonical / definitional / code / graph queries
   (`who is X`, `what is X`, etc.) — gbrain's heuristic defaults
   to `off`.

## Verification

```bash
# 1. Confirm upgrade
gbrain --version    # 0.29.1
gbrain doctor --json | jq '.checks[] | select(.name | startswith("schema_version"))'

# 2. Recompute emotional weights (one-time after upgrade)
gbrain dream --phase recompute_emotional_weight

# 3. Verify health checks
gbrain doctor --json | jq '.checks[] | select(.name | startswith("salience_health") or startswith("effective_date_health"))'

# 4. Try the new axes
gbrain query "what's been going on with X" --explain --json | jq '._resolved'
# expected: { salience: "on", recency: "on", salience_source: "auto_heuristic", recency_source: "auto_heuristic" }

gbrain query "who is X" --explain --json | jq '._resolved'
# expected: { salience: "off", recency: "off", ... }

# 5. Date filter
gbrain query "acme" --since 7d --until 2024-06-30 --json
```

## If something looks wrong

```bash
# Re-apply migrations manually
gbrain apply-migrations --yes

# Force re-run the v0.29.1 backfill (computeEffectiveDate on every page)
gbrain reindex-frontmatter --yes --force

# Doctor for any warnings
gbrain doctor --json
```

If issues persist, file at https://github.com/garrytan/gbrain/issues
with the doctor output and contents of `~/.gbrain/upgrade-errors.jsonl`
(if it exists).

## Schema additions (idempotent, additive only)

Migration v38 adds 4 nullable columns to `pages`:
- `effective_date` — content-date computed from frontmatter precedence
- `effective_date_source` — sentinel for the doctor check
- `import_filename` — basename captured at import for filename-date precedence
- `salience_touched_at` — bumped by recompute_emotional_weight on changes

Migration v39 adds 7 nullable columns to `eval_candidates`:
- `as_of_ts`, `salience_param`, `recency_param`, `salience_resolved`,
  `recency_resolved`, `salience_source`, `recency_source`

Plus the `pages_coalesce_date_idx` expression index for since/until filters.

NDJSON `schema_version` STAYS at 1; consumers ignore unknown fields.
No cross-repo coordination required.

## Behavior changes

- v0.29.0 `get_recent_salience` formula: UNCHANGED for callers who don't
  pass `recency_bias='on'`. Pass `recency_bias='on'` to opt into per-prefix
  decay (concepts/originals/writing/ evergreen; daily/, media/x/ aggressive).

- v0.29.0 SearchOpts: `afterDate`, `beforeDate`, `recencyBoost: 0|1|2`
  remain as DEPRECATED ALIASES for `since`, `until`, `recency`. They
  emit a stderr warning once per process. Removed in v0.30.

- `detail='high'` source-boost bypass — UNCHANGED in v0.29.1. The
  known temporal-query swamp is documented; pass `salience='on'` to
  compensate via salience boost.
