[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6N0PT8PETDHD3AMMBW0AHF5":3,"skill-same:01M6N0PT8PETDHD3AMMBW0AHF5":99},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":77,"commitSha":78,"skillDirectory":79,"forksCount":80,"repositoryHtmlUrl":81,"repositoryHomepageUrl":6,"ownerHtmlUrl":82,"ownerBlogUrl":83,"ownerDescription":84,"updatedAt":85,"install":86,"resources":98},"01M6N0PT8PETDHD3AMMBW0AHF5","maintain",null,"Brain health checks: back-link enforcement, citation audit, filing validation,\nstale info detection, orphan pages, and benchmarks. Use when asked to check\nbrain health, run maintenance, or audit quality.","garrytan\u002Fgbrain","garrytan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F19957?v=4","01M6DJCCDDG53MTYYRTXAXFG17","Garry Tan","01M6MZQZCEN3RRMD33E1X9ZZR9",32683,"MIT","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fmaintain\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"synthesize","when","my","conversations","re","you","filing","orphan","brain","get","consolidate","run","info","cycle","back","patterns","list","dream","audit","search","2026-11-10 10:12:30",false,"---\nname: maintain\nversion: 1.1.0\nupstream: maintain@fc834ee\ndescription: |\n  Brain health checks: back-link enforcement, citation audit, filing validation,\n  stale info detection, orphan pages, and benchmarks. Use when asked to check\n  brain health, run maintenance, or audit quality.\ntriggers:\n  - \"brain health\"\n  - \"check backlinks\"\n  - \"maintenance\"\n  - \"orphan pages\"\n  - \"stale pages\"\n  - \"extract links\"\n  - \"build link graph\"\n  - \"populate timeline\"\n  - \"populate links\"\n  - \"backfill graph\"\n  - \"extract timeline entries\"\n  - \"retriage the backlog\"\n  - \"re-score the triage\"\n  - \"run dream\"\n  - \"process today's session\"\n  - \"process yesterday's transcripts\"\n  - \"synthesize my conversations\"\n  - \"what patterns did you see\"\n  - \"did the dream cycle run\"\n  - \"consolidate yesterday's conversations\"\ntools:\n  - get_health\n  - get_brain_health\n  - get_page\n  - put_page\n  - list_pages\n  - get_backlinks\n  - add_link\n  - search\nmutating: true\n---\n\n# Maintain Skill\n\nPeriodic brain health checks and cleanup.\n\n## Contract\n\nThis skill guarantees:\n- All health dimensions are checked (stale, orphan, dead links, cross-refs, backlinks, citations, filing, tags)\n- Each issue found has a specific fix action\n- Back-link iron law is enforced\n- Citation format is validated against the standard\n- Results are reported with counts per dimension\n\n## Phases\n\n### Ownership failures are an inspection boundary\n\nRoutine maintenance, startup checks, `doctor --fix`, and a request to \"fix what's\nbroken\" do not authorize writer topology changes. On `owner_unavailable` or a\nwriter coordination refusal, inspect `gbrain sources writer status --brain \u003Cid>\n--json` on the selected host first and report the owner, epoch, enabled state and\nblocked recovery to the operator. Do not claim a checkout, activate managed mode,\ntransfer an owner, replace identities, or remove ownership markers as a repair.\nWhen the status reads `enabled: false` and the refusal says `unbound_source`,\nthe brain is in classic mode on purpose: report that writes go through the\ncheckout (file, commit, `gbrain sync`) and leave it classic.\nDeliberate administration requires a separately approved topology change and the\naction-specific intent plus reviewed state precondition described in\n`docs\u002Farchitecture\u002Ftopologies.md`. Neither a TTY nor `--yes` nor\n`--confirm-quiesced` substitutes for that decision. Remote credentials remain\nineligible for local writer administration.\n\n### Autonomous path (v0.36.4.0) — when you want to reach a target score\n\nIf the user asks \"get my brain to 90\u002F100\" or \"fix what's broken\", preview first\nand ask before applying anything:\n\n```bash\ngbrain doctor --remediation-plan --json              # preview: job steps + repair steps\n# Show the user the repair steps (each \"requires user agreement\") and the cost.\n# Only after the user agrees (plan_hash from the preview binds the approval):\ngbrain doctor --remediate --yes --include-repairs --expect \u003Cplan_hash> --target-score 90 --max-usd 5\n```\n\n`--remediation-plan` prints a dependency-ordered list of job steps (sync before\nextract, embed after consolidate, etc.) with per-step `est_seconds` and\n`est_usd_cost`, and, independent of the score target, the PROTECTED repair steps\nfor every `gbrain repair` kind with pending items. Each step carries the exact\ncommand that applies it, and the plan ends with one combined command.\n`--remediate` runs the repair steps only with `--include-repairs` (the user's\nagreement; without it they are listed as skipped), then walks the job plan,\nsubmitting each step as a Minion job and re-checking score between steps.\n`--max-usd N` is a cumulative cost cap across the run and every `--resume`: a\npaid step that would exceed it is not started, free steps still run, and the run\nstops with a resume command that keeps the cap and the agreement.\n\nWhen the target score is unreachable for the brain (empty brain with no entity\npages → `graph_coverage` caps at 70; unconfigured embedding key → caps at 60),\njob steps stop with a list of what's missing rather than looping; included repair\nsteps still run. `--json` classifies each finding `cleared`, `pending`,\n`consent_required`, `operator_required` (follow its instruction) or\n`unsupported` (report it; nothing clears it yet). After an upgrade, follow the\nrecipe in `docs\u002Fguides\u002Frepair.md#recover-after-upgrading-to-this-release`.\n\nUse the per-dimension walk below (Phase 2 onward) when:\n- The user explicitly asks for a dimension-by-dimension audit\n- You're investigating why score is stuck below `--remediate`'s ceiling\n- A specific dimension needs manual judgment that the auto path skips\n\n### Manual path\n\n1. **Run health check.** Check gbrain health (`get_health`) to get the dashboard. `get_health` needs admin scope; without it, call `get_brain_health` (read scope), which returns bands only (write capacity, write failures, ghost pages, unsearchable chunks), and skip the dimensions it cannot answer: stale pages, orphan pages, dead links, embed coverage, link and timeline counts and the brain score. Name the skipped dimensions in the report and ask for an admin token, or for `gbrain doctor --json` on the brain host, to cover them.\n2. **Check each dimension:**\n\n### Stale pages\nPages where compiled_truth is older than the latest timeline entry. The assessment hasn't been updated to reflect recent evidence.\n- Check the health output for stale page count\n- For each stale page: read the page from gbrain, review timeline, determine if compiled_truth needs rewriting\n\n### Orphan pages\nPages with zero inbound links. Nobody references them.\n- Review orphans: are they genuinely isolated or just missing links?\n- Add links in gbrain from related pages or flag for deletion\n\n### Dead links\nLinks pointing to pages that don't exist.\n- Remove dead links in gbrain\n\n### Missing cross-references\nPages that mention entity names but don't have formal links.\n- Read compiled_truth from gbrain, extract entity mentions, create links in gbrain\n\n### Link graph extraction\nIf link_count is 0 or low relative to page_count, run batch extraction:\n```bash\ngbrain extract links --dir ~\u002Fbrain\n```\nThis scans all markdown files for entity references, See Also sections, and\nfrontmatter fields, then creates typed links in the database.\n\n### Timeline extraction\nIf timeline_entry_count is 0, extract structured timeline from markdown:\n```bash\ngbrain extract timeline --dir ~\u002Fbrain\n```\n\n### Dream cycle (v0.23): synthesize + patterns\n\n`gbrain dream` runs the full maintenance cycle (core phases shown; opt-in\nphases like atoms\u002Fconcepts\u002Fdrift slot in between):\n\n```\nlint -> backlinks -> sync -> synthesize -> extract -> patterns -> embed -> orphans\n```\n\n`fence_repair` runs right after `sync`, once per maintenance pass: it repairs\nthe facts and takes fences sync held or pages store malformed (the same plan\n`gbrain repair fences` previews), for at most 300 s or a third of the job's\nremaining time, and resumes on the next run. `content_repair` runs right after\nit (#6377): the rest of the content-repair lane, today the `slug-conflicts`\nkind that removes a stray frontmatter `slug:` or records a recommended merge\nfor a person (`gbrain repair content` previews both kinds), for at most 120 s\nor a third of the remaining time. Pause both with\n`gbrain config set fences.repair.enabled false`.\n\nThe two new phases consolidate yesterday's conversations into long-term memory:\n\n**Synthesize phase (two-stage cascade):** reads the cycle source's transcripts from\n`dream.synthesize.session_corpus_dir` (another source's sessions wait for their own\n`gbrain dream --source \u003Cid> --phase synthesize`; unresolved or legacy files are held,\nalready-extracted ones included, until `gbrain sweep --assign-corpus \u003Csource>`), then triages before it spends: a cheap\nutility-tier judge (`models.dream.triage`) scores every new file 0–1 for\nsalience and pre-extracts candidate quotes + entities, cached in\n`dream_verdicts` with the judging model + prompt version (bounded per cycle\nby `dream.triage.max_ms`, default 5 min — deferred files retry next cycle,\nnever silently rejected). A file passes the gate two ways: it scores at or\nabove `dream.triage.threshold` (default 0.5), OR the **verified-segment\nrescue** fires — a score in `[dream.triage.rescue_floor, threshold)` still\npasses when at least `dream.triage.rescue_min_segments` (default 2; `0`\ndisables) of the judge's own quoted segments verify as substrings of the\ntranscript AND the content type is in `dream.triage.rescue_content_types`\n(default `mixed,reflection,idea,strategy,people` — never routine\u002Ftechnical).\nThe rescue costs nothing (no extra LLM calls, it re-reads the cached verdict)\nand it is what recovers real signal buried in an otherwise mundane transcript.\nThe whole gate is applied at READ time, so retuning the threshold or the\nrescue knobs re-gates with zero new LLM calls. Files that pass fan out one\nsynthesis subagent per transcript chunk, each primed with the triage map. By default\neach child runs in oneshot mode (`dream.synthesize.mode`, default `oneshot`):\nONE tool-less completion against a prompt carrying a pre-retrieved LINK\nCANDIDATES manifest (`dream.synthesize.link_manifest`, default on) and the\nwrite allow-list, validated end-to-end (slug fences, task shapes, wikilinks)\nbefore any page is written programmatically. A response that fails validation\nfalls back to the classic agentic loop in the same job, where the\n`dream.synthesize.max_turns` cap (default 16) applies; revert dial:\n`gbrain config set dream.synthesize.mode agentic`. Each child writes reflections\n(`wiki\u002Fpersonal\u002Freflections\u002F...`) and originals (`wiki\u002Foriginals\u002Fideas\u002F...`);\npeople timeline entries are written only on the agentic path (fallback or\n`mode agentic`), where the child has the `add_timeline_entry` tool. The orchestrator collects the slugs from\n`subagent_tool_executions` (NOT `pages.updated_at` — that would pick up\nunrelated writes), runs the quote verify pass over them (below), and\nreverse-renders each new page from DB → markdown on disk. To re-apply the\ngate after retuning the threshold or the rescue knobs, or to drain a queued\nbacklog, run `gbrain dream retriage --dry-run` (zero LLM calls, cached\nscores only) then `gbrain dream retriage --reconcile-queue`; `--force`\nre-judges everything from scratch. Retriage reads the SAME gate the cycle\ndoes, so a reconcile sweep never cancels a job the rescue admitted.\n\n**Claim verification (post-write, zero LLM):** after slug collection and\nbefore the reverse-write, `dream.synthesize.quote_verify` (default on) checks\nevery page this phase's children wrote against the transcripts that produced\nit. Pages created this run are checked whole; pages that already existed are\nchecked only on the sentences this run added. An exact quote is kept; a quote\nthat differs only in whitespace, curly quotes, dashes, or case, or a close\nparaphrase inside one speaker's turn, is replaced with the verbatim transcript\nslice. A sentence is quarantined when a quote grounds nowhere or only across\ntwo speakers, when it attributes a real quote to the wrong speaker, or when it\nstates a number or date the transcript lacks. Quarantined sentences leave the\npage body (and the timeline, facts and links derived from it) and are kept\nverbatim in frontmatter `unverified_claims`, which `get_page` shows but search,\nrecall and think do not read. Grounded quotes record their source span and\nspeaker in `grounding.quotes`. Nothing is ever fabricated. Telemetry lands in\n`details.synthesis.quote_verify`; the config key is the incident off switch.\n\n**Patterns phase:** runs after `extract` (so the graph state is fresh).\nReads recent reflections within `dream.patterns.lookback_days` (default 30),\nruns a single Sonnet pass to surface recurring themes, and writes pattern\npages to `wiki\u002Fpersonal\u002Fpatterns\u002F\u003Ctheme>` when ≥`dream.patterns.min_evidence`\n(default 3) reflections support a pattern. A completed run records the newest\nreflection it consumed (`dream.patterns.last_evidence_ts`); until a reflection\nin the window is newer than that, re-runs skip with `no_new_evidence` instead\nof paying for another model pass — `gbrain dream --phase patterns --once`\nforces one.\n\n**Quality bar (Iron Law for synthesis):**\n1. Quote the user verbatim. Quotation marks are ONLY for spans reproducible\n   EXACTLY from the transcript — if you cannot reproduce a span exactly,\n   paraphrase it WITHOUT quotation marks. Do not paraphrase memorable\n   phrasings you can quote exactly. (The quote verify pass enforces this\n   mechanically after the write.)\n2. Cross-reference compulsively: every new page MUST have at least one wikilink.\n3. Slug discipline: lowercase alphanumeric and hyphens only. NO underscores, NO file extensions.\n4. Edited transcripts produce NEW slugs (content-hash suffix changes) — never silently overwrite.\n5. Preserve concrete facts: carry the specific numbers, dates, dollar amounts,\n   names, and who-decided-what of the salient content, exactly as the\n   transcript states them. Do not pad with routine logistics.\n6. Ground every claim in the transcript. Attribute speculation as speculation,\n   and never state a completion state or outcome the transcript does not show.\n\n**Trust boundary (`allowed_slug_prefixes`):** the synthesis subagent runs with an\nexplicit allow-list of write paths sourced from `_brain-filing-rules.json`'s\n`dream_synthesize_paths.globs`. Even on prompt-injection success, the subagent\ncannot write outside that list. Trust comes from PROTECTED_JOB_NAMES — MCP\ncannot submit subagent jobs at all. Editing the JSON is the only way to add\na new directory the synthesizer can write to.\n\n**Idempotency + privacy:** transcripts are keyed by `(file_path, content_hash)`,\nso re-running on the same content is a no-op. `dream.synthesize.exclude_patterns`\n(default `[\"medical\", \"therapy\"]`) filters out transcripts before any LLM call.\nEach entry is auto-wrapped as a word-boundary regex (e.g. `medical` matches\n\"medical advice\" but NOT \"comedical\"). Power users may pass full regex.\n\n**Cooldown:** `dream.synthesize.cooldown_hours` (default 12) skips synthesize\nfor that long after a fully drained pass. The completion timestamp is stored\nin `dream.synthesize.last_completion_ts` and is written only when every child\ncompleted and nothing was deferred (synthesis budget, triage time budget or\npublish pending), never on skipped or failed runs. So under a standing\nbacklog the cooldown never applies and synthesize runs every cycle until the\nbacklog drains (#6753); it is not a cap of ~2 runs a day. To cap spend, use\n`dream.synthesize.max_submissions_per_source_per_day`. Explicit `--input` \u002F\n`--date` \u002F `--from` \u002F `--to` invocations bypass cooldown.\n\n**`--dry-run` semantics:** runs the scored triage pass (judges + caches\nverdicts for new files) but skips the synthesis subagents. NOT zero LLM\ncalls — for a zero-call preview from cached scores use\n`gbrain dream retriage --dry-run` instead.\n\n**Configure synthesize on a fresh brain:**\n```bash\ngbrain config set dream.synthesize.session_corpus_dir \u002Fpath\u002Fto\u002Ftranscripts\ngbrain config set dream.synthesize.enabled true\ngbrain dream --phase synthesize --dry-run --json   # preview\ngbrain dream                                       # full cycle\n```\n\n**Invocation patterns:**\n```bash\ngbrain dream                                          # full cycle\ngbrain dream --phase synthesize                       # just synthesize\ngbrain dream --phase patterns                         # just patterns\ngbrain dream --input ~\u002Ftranscripts\u002F2026-04-25.txt     # ad-hoc one transcript\ngbrain dream --from 2026-04-01 --to 2026-04-25        # backfill range\ngbrain dream --json                                   # CycleReport JSON\n```\n\n**Auto-commit deferred to v1.1:** v1 writes files to `brain_dir` but does NOT\n`git add` \u002F `commit` \u002F `push`. Either commit yourself or let `gbrain autopilot`\nhandle it.\nParses `- **YYYY-MM-DD** | Source — Summary` and `### YYYY-MM-DD — Title` formats.\nThe `Source — Summary` dash may be an em dash, an en dash or a spaced hyphen (` - `);\na colon (`Source: Summary`) is prose, so the row keeps `source: markdown` and the\nwhole text as its summary.\nNote: extracted entries improve structured queries (`gbrain timeline`), not vector search.\n\n### Autopilot check\nVerify autopilot is running:\n```bash\ngbrain autopilot --status\n```\nThe exit code is trustworthy for gating: 0 fresh (or nothing installed),\n1 needs attention (stale heartbeat, never ran, or paused by a migration),\n2 the daemon disabled itself (its repo path vanished). `--json` emits the\nfull report (`state`, `heartbeat_age_seconds`, `paused_reason`,\n`disabled_reason`). Status reads only the filesystem, so it works even\nwhen the database is down.\n\nIf not running, install it:\n```bash\ngbrain autopilot --install --repo ~\u002Fbrain\n```\nAutopilot runs sync, extract, and embed in a continuous loop with adaptive scheduling.\nIn v0.11.1+, autopilot dispatches each cycle as a single `autopilot-cycle`\nMinion job and supervises the worker child — one install step gives you\nsync + extract + embed + backlinks + durable job processing.\n\n### Fix a half-migrated install\nA v0.11.0 install where the migration skill never fired leaves Minions\npartially set up: schema is applied, but `~\u002F.gbrain\u002Fpreferences.json`\ndoesn't exist, autopilot runs inline, host manifests still reference\n`agentTurn`. Repair:\n\n```bash\n# Check migration status\ngbrain apply-migrations --list\n\n# Apply pending migrations (idempotent; safe on healthy installs)\ngbrain apply-migrations --yes\n\n# If host-specific handlers are flagged in ~\u002F.gbrain\u002Fmigrations\u002Fpending-host-work.jsonl:\n# walk them per skills\u002Fmigrations\u002Fv0.11.0.md + docs\u002Fguides\u002Fplugin-handlers.md,\n# ship handler registrations in the host repo, then re-run apply-migrations.\n```\n\nFull troubleshooting guide: `docs\u002Fguides\u002Fminions-fix.md`.\n\n### Back-link enforcement\nCheck that the back-linking iron law is being followed:\n- For each recently updated page, check if entities mentioned in it have\n  corresponding back-links FROM those entity pages\n- A mention without a back-link is a broken brain\n- Fix: add the missing back-link to the entity's Timeline or See Also section\n- Format: `- **YYYY-MM-DD** | Referenced in [page title](path) -- brief context`\n\n### Filing rule violations\nCheck for common misfiling patterns (see `skills\u002F_brain-filing-rules.md`):\n- Content with clear primary subjects filed in `sources\u002F` instead of the\n  appropriate directory (people\u002F, companies\u002F, concepts\u002F, etc.)\n- Use gbrain search to find pages in `sources\u002F` that reference specific\n  people, companies, or concepts -- these may be misfiled\n- Flag misfiled pages for review or re-filing\n\n### Citation audit\nSpot-check pages for missing `[Source: ...]` citations:\n- Read 5-10 recently updated pages\n- Check that compiled truth (above the line) has inline citations\n- Check that timeline entries have source attribution\n- Flag pages where facts appear without provenance\n\n### Tag consistency\nInconsistent tagging (e.g., \"vc\" vs \"venture-capital\", \"ai\" vs \"artificial-intelligence\").\n- Standardize to the most common variant using gbrain tag operations\n\n### Graph population (v0.10.3+)\n\nThe `links` and `timeline_entries` tables are the structured graph layer.\nPopulate them periodically or after major imports:\n\n- `gbrain extract links --source db` — backfill structured links by walking pages\n  from the engine. Reads `[Name](people\u002Fslug)` \u002F `[Name](companies\u002Fslug)` references\n  and infers relationship types (`attended`, `works_at`, `invested_in`, `founded`,\n  `advises`, `mentions`, `source`). Idempotent. Use `--source fs --dir \u003Cbrain>`\n  if you have a markdown checkout to walk instead.\n- `gbrain extract timeline --source db` — backfill structured timeline entries.\n  Parses `- **YYYY-MM-DD** | summary` lines from page content. Idempotent (DB\n  UNIQUE constraint).\n- `gbrain extract all --source db` — both in one run.\n- `gbrain graph-query \u003Cslug> --depth 2` — verify connectivity (use any well-known\n  entity slug as a probe).\n- `gbrain stats` — verify `link_count > 0` and `timeline_entry_count > 0` after extraction.\n- `gbrain health` — review `link_coverage` and `timeline_coverage` percentages\n  on entity pages (person\u002Fcompany). Below 50% means more extraction is needed.\n  On brains with very few entity pages these report \"too few to grade\"\n  (`null` in JSON, with `entity_page_count` carrying the denominator) instead\n  of a misleading 0%\u002F100% — grow the entity set before acting on coverage.\n\nAvailable link types (use with `gbrain graph-query --type`):\n`attended`, `works_at`, `invested_in`, `founded`, `advises`, `mentions`, `source`.\n\nGoing forward, every `gbrain put` call auto-creates and reconciles links via the\nauto-link post-hook (default on; disable: `gbrain config set auto_link false`).\nSo link-extract is mostly a one-time backfill. timeline-extract should be re-run\nafter bulk imports or content edits that add new dated entries.\n\n### Feature adoption check (weekly)\n```bash\ngbrain features --json    # scan for underused features + recommendations\n```\nRun weekly alongside lint. Surfaces missing embeddings, unused integrations,\nand configuration improvements.\n\n### Embedding freshness\nChunks without an embedding yet (`--stale` selects exactly those). Embedding\ncalls the configured provider, which bills per token, so this is paid work\nthat needs the user's approval first:\n1. Preview with no provider calls: `gbrain embed --stale --dry-run`.\n2. Relay the chunk count and cost estimate to the user and wait for an answer.\n3. Only after they agree, run `gbrain embed --stale --yes --max-usd \u003Ccap>`\n   with the cap they approved.\n\nWithout approval the command stops with exit 3 and an `[AGENT]` block asking\nyou to ask the user; relay it and stop. Never pass `--yes` on your own.\nFor a long run (>1000 chunks), route the approved command through the\ndurable ladder in `skills\u002Fminion-orchestrator\u002FSKILL.md` instead of a bare\nbackground shell, which hides that exit 3 in a log file.\n\nTo see what search cannot reach on one source, run\n`gbrain pages unsearchable --source \u003Cid> --json` (read-only). Read\n`semantic_unsearchable`, not only `unsearchable`: it adds `keyword_only`\npages, which keyword search finds but vector search misses. `awaiting_sync`\ncounts files sync still holds, which no embedding state includes; follow\n`gbrain sync status --source \u003Cid> --json` for those. Each row carries its `fix`.\n\n### Security (RLS verification)\nRun `gbrain doctor --json` and check the RLS status.\nAll tables should show RLS enabled. If not, run `gbrain init` again.\n\n### Schema health\nCheck that the schema version is up to date. `gbrain doctor --json` reports\nthe current version vs expected. If behind, `gbrain init` runs migrations\nautomatically.\n\n### File storage health\nCheck the integrity of stored files and redirect pointers:\n- Run `gbrain files verify` to check all DB records have valid data\n- Run `gbrain files status` to see migration state (local, mirrored, redirected)\n- Check for orphan `.redirect.yaml` pointers that reference missing storage files\n- Check for large binary files (>= 100 MB) still in git that should be in cloud storage\n- If storage backend is configured: verify redirect pointers resolve (download test)\n\n### Open threads\nTimeline items older than 30 days with unresolved action items.\n- Flag for review\n\n## Benchmark Testing\n\nPeriodically verify search quality hasn't regressed. Run a battery of test\nqueries across difficulty tiers:\n\n- **Tier 1 (entity lookup):** known names -- should always resolve\n- **Tier 2 (topic recall):** concepts, topics -- keyword search should handle\n- **Tier 3 (semantic):** queries with no exact keyword match -- needs embeddings\n- **Tier 4 (cross-domain):** relational\u002Fconnection queries -- only semantic handles\n\nCompare results from `gbrain search` (keyword) vs `gbrain query` (hybrid).\nQuality matters more than speed (2.5s right > 200ms wrong).\n\nWhen to run benchmarks:\n- After major brain imports or re-imports\n- After gbrain version upgrades\n- After embedding regeneration\n- Monthly to track quality drift\n\n## Heartbeat Integration\n\nFor production agents running on a schedule, integrate gbrain health checks into\nyour operational heartbeat.\n\n### On every heartbeat (hourly or per-session)\n\nRun `gbrain doctor --json` and check for degradation. Report any failing checks\nto the user. Key signals: connection health, schema version, RLS status, embedding\nstaleness.\n\n### Weekly maintenance\n\nRefresh embeddings for chunks that have none yet, with the same consent steps\nas \"Embedding freshness\" above: `gbrain embed --stale --dry-run`, relay the\nestimate, and after the user agrees `gbrain embed --stale --yes --max-usd \u003Ccap>`\n(or a standing approval the user set with\n`consent.preapprove.paid.max_usd_per_run`). For large brains (>5000 pages),\nsubmit the approved command through the minion-orchestrator durable ladder;\nif you must background it in a shell, keep the exit code:\n```bash\n(gbrain embed --stale --yes --max-usd \u003Ccap>; echo \"exit=$?\") > \u002Ftmp\u002Fgbrain-embed.log 2>&1 &\ntail -2 \u002Ftmp\u002Fgbrain-embed.log   # later: the last line is exit=\u003Ccode>\n```\nExit 3 in that log means the run needs the user's approval: relay it and stop.\n\n### Monthly backup check\n\nRun `gbrain backup status` and relay anything red. It verifies every knowledge\nrepo (and the agent workspace) has a git remote — local-only means a disk loss\nloses it. Fixes are printed inline (`gbrain bootstrap repo`, `git remote add`,\n`gbrain sources harden \u003Cid>`).\n\n### Daily verification\n\nVerify sync is running: check `gbrain stats` and confirm `last_sync` is within\nthe last 24 hours. If sync has stopped, the brain is drifting from the repo.\n\n### Stale compiled truth detection\n\nFlag pages where compiled truth is >30 days old but the timeline has recent entries.\nThis means new evidence exists that hasn't been synthesized. These pages need a\ncompiled truth rewrite (see the maintain workflow above).\n\n## Report Storage\n\nAfter maintenance runs, save a report:\n- Health check results (before\u002Fafter scores for each dimension)\n- Back-link violations found and fixed\n- Filing rule violations found\n- Citation gaps flagged\n- Benchmark results (if run)\n- Outstanding issues requiring user attention\n\nThis creates an audit trail for brain health over time.\n\n## Quality Rules\n\n- Never delete pages without confirmation\n- Log all changes via timeline entries\n- Check gbrain health before and after to show improvement\n\n## When it fails\n\nFollow the [agent operator protocol](..\u002Fconventions\u002Fagent-operator-protocol.md) for any gbrain error `code`, exit code, `[AGENT]` block or notice block. Specific to this skill:\n\n- `gbrain doctor --remediate` steps marked \"requires user agreement\" (PROTECTED repairs, paid steps): show the plan and cost, and run with `--yes --include-repairs --expect \u003Cplan_hash> --max-usd \u003Cn>` (the hash from `--remediation-plan --json`) only after the user agrees; `preview_changed` means the plan moved, so preview and ask again. A step that would exceed the cap is not started.\n- A finding classified `operator_required`: follow its instruction or relay it to the brain host's operator. `consent_required`: ask the user.\n- A writer-coordination refusal (`writer_coordinator_required`, `writer_not_quiesced`, `recovery_required`): inspect `gbrain sources writer status` and hand the blocked recovery to the operator; never claim a checkout or delete a lock.\n- Doctor warns `persistence_terminal_failures`: run its `fix.command` (an active blocker: a recovery record or a sync checkpoint blocker; or an unresolved gbrain-defect class to report with the receipt ids). For the rest of the pile, `gbrain sources writer failures \u003Csource> --group-by category` (read-only) groups receipts with a fix and drill-down per group; historical rows need nothing. Never cancel or edit receipts to clear the count. Runbook: [terminal write failures](https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fdocs\u002Fguides\u002Ftroubleshooting.md#terminal-write-failures).\n- `gbrain dream` stops on a budget (exit 11): run the printed `resume_command` within the agreed budget.\n\n## Anti-Patterns\n\n- Fixing pages without reading them first -- you must understand context before editing\n- Silently skipping dimensions -- every dimension must be checked and reported, even if clean\n- Deleting orphan pages without checking if they should be linked instead\n- Running embedding refresh during peak usage hours\n- Batch-fixing back-links without verifying the relationship is real\n- Marking a dimension \"clean\" without actually querying it\n- Rewriting compiled truth without reading the full timeline first\n- Removing tags without checking if other pages use the same tag consistently\n\n## Output Format\n\nThe maintenance report follows this structure:\n\n```\n## Brain Health Report — YYYY-MM-DD\n\n| Dimension           | Issues Found | Fixed | Remaining |\n|----------------------|-------------|-------|-----------|\n| Stale pages          | N           | N     | N         |\n| Orphan pages         | N           | N     | N         |\n| Dead links           | N           | N     | N         |\n| Missing cross-refs   | N           | N     | N         |\n| Back-link violations | N           | N     | N         |\n| Citation gaps        | N           | N     | N         |\n| Filing violations    | N           | N     | N         |\n| Tag inconsistencies  | N           | N     | N         |\n| Embedding staleness  | N           | N     | N         |\n| Security (RLS)       | N           | N     | N         |\n| Schema health        | N           | N     | N         |\n| File storage         | N           | N     | N         |\n| Open threads         | N           | N     | N         |\n\n### Details\n[Per-dimension breakdown with specific pages and actions taken]\n\n### Benchmark Results (if run)\n[Tier 1-4 query results with pass\u002Ffail]\n\n### Outstanding Issues\n[Items requiring user attention or confirmation]\n```\n\n## Tools Used\n\n- Check gbrain health (get_health; admin scope)\n- Check banded brain health without admin scope (get_brain_health)\n- List pages in gbrain with filters (list_pages)\n- Read a page from gbrain (get_page)\n- Check backlinks in gbrain (get_backlinks)\n- Link entities in gbrain (add_link)\n- Remove links in gbrain (remove_link)\n- Tag a page in gbrain (add_tag)\n- Remove a tag in gbrain (remove_tag)\n- View timeline in gbrain (get_timeline)\n","# Maintain Skill\n\nPeriodic brain health checks and cleanup.\n\n## Contract\n\nThis skill guarantees:\n- All health dimensions are checked (stale, orphan, dead links, cross-refs, backlinks, citations, filing, tags)\n- Each issue found has a specific fix action\n- Back-link iron law is enforced\n- Citation format is validated against the standard\n- Results are reported with counts per dimension\n\n## Phases\n\n### Ownership failures are an inspection boundary\n\nRoutine maintenance, startup checks, `doctor --fix`, and a request to \"fix what's\nbroken\" do not authorize writer topology changes. On `owner_unavailable` or a\nwriter coordination refusal, inspect `gbrain sources writer status --brain \u003Cid>\n--json` on the selected host first and report the owner, epoch, enabled state and\nblocked recovery to the operator. Do not claim a checkout, activate managed mode,\ntransfer an owner, replace identities, or remove ownership markers as a repair.\nWhen the status reads `enabled: false` and the refusal says `unbound_source`,\nthe brain is in classic mode on purpose: report that writes go through the\ncheckout (file, commit, `gbrain sync`) and leave it classic.\nDeliberate administration requires a separately approved topology change and the\naction-specific intent plus reviewed state precondition described in\n`docs\u002Farchitecture\u002Ftopologies.md`. Neither a TTY nor `--yes` nor\n`--confirm-quiesced` substitutes for that decision. Remote credentials remain\nineligible for local writer administration.\n\n### Autonomous path (v0.36.4.0) — when you want to reach a target score\n\nIf the user asks \"get my brain to 90\u002F100\" or \"fix what's broken\", preview first\nand ask before applying anything:\n\n```bash\ngbrain doctor --remediation-plan --json              # preview: job steps + repair steps\n# Show the user the repair steps (each \"requires user agreement\") and the cost.\n# Only after the user agrees (plan_hash from the preview binds the approval):\ngbrain doctor --remediate --yes --include-repairs --expect \u003Cplan_hash> --target-score 90 --max-usd 5\n```\n\n`--remediation-plan` prints a dependency-ordered list of job steps (sync before\nextract, embed after consolidate, etc.) with per-step `est_seconds` and\n`est_usd_cost`, and, independent of the score target, the PROTECTED repair steps\nfor every `gbrain repair` kind with pending items. Each step carries the exact\ncommand that applies it, and the plan ends with one combined command.\n`--remediate` runs the repair steps only with `--include-repairs` (the user's\nagreement; without it they are listed as skipped), then walks the job plan,\nsubmitting each step as a Minion job and re-checking score between steps.\n`--max-usd N` is a cumulative cost cap across the run and every `--resume`: a\npaid step that would exceed it is not started, free steps still run, and the run\nstops with a resume command that keeps the cap and the agreement.\n\nWhen the target score is unreachable for the brain (empty brain with no entity\npages → `graph_coverage` caps at 70; unconfigured embedding key → caps at 60),\njob steps stop with a list of what's missing rather than looping; included repair\nsteps still run. `--json` classifies each finding `cleared`, `pending`,\n`consent_required`, `operator_required` (follow its instruction) or\n`unsupported` (report it; nothing clears it yet). After an upgrade, follow the\nrecipe in `docs\u002Fguides\u002Frepair.md#recover-after-upgrading-to-this-release`.\n\nUse the per-dimension walk below (Phase 2 onward) when:\n- The user explicitly asks for a dimension-by-dimension audit\n- You're investigating why score is stuck below `--remediate`'s ceiling\n- A specific dimension needs manual judgment that the auto path skips\n\n### Manual path\n\n1. **Run health check.** Check gbrain health (`get_health`) to get the dashboard. `get_health` needs admin scope; without it, call `get_brain_health` (read scope), which returns bands only (write capacity, write failures, ghost pages, unsearchable chunks), and skip the dimensions it cannot answer: stale pages, orphan pages, dead links, embed coverage, link and timeline counts and the brain score. Name the skipped dimensions in the report and ask for an admin token, or for `gbrain doctor --json` on the brain host, to cover them.\n2. **Check each dimension:**\n\n### Stale pages\nPages where compiled_truth is older than the latest timeline entry. The assessment hasn't been updated to reflect recent evidence.\n- Check the health output for stale page count\n- For each stale page: read the page from gbrain, review timeline, determine if compiled_truth needs rewriting\n\n### Orphan pages\nPages with zero inbound links. Nobody references them.\n- Review orphans: are they genuinely isolated or just missing links?\n- Add links in gbrain from related pages or flag for deletion\n\n### Dead links\nLinks pointing to pages that don't exist.\n- Remove dead links in gbrain\n\n### Missing cross-references\nPages that mention entity names but don't have formal links.\n- Read compiled_truth from gbrain, extract entity mentions, create links in gbrain\n\n### Link graph extraction\nIf link_count is 0 or low relative to page_count, run batch extraction:\n```bash\ngbrain extract links --dir ~\u002Fbrain\n```\nThis scans all markdown files for entity references, See Also sections, and\nfrontmatter fields, then creates typed links in the database.\n\n### Timeline extraction\nIf timeline_entry_count is 0, extract structured timeline from markdown:\n```bash\ngbrain extract timeline --dir ~\u002Fbrain\n```\n\n### Dream cycle (v0.23): synthesize + patterns\n\n`gbrain dream` runs the full maintenance cycle (core phases shown; opt-in\nphases like atoms\u002Fconcepts\u002Fdrift slot in between):\n\n```\nlint -> backlinks -> sync -> synthesize -> extract -> patterns -> embed -> orphans\n```\n\n`fence_repair` runs right after `sync`, once per maintenance pass: it repairs\nthe facts and takes fences sync held or pages store malformed (the same plan\n`gbrain repair fences` previews), for at most 300 s or a third of the job's\nremaining time, and resumes on the next run. `content_repair` runs right after\nit (#6377): the rest of the content-repair lane, today the `slug-conflicts`\nkind that removes a stray frontmatter `slug:` or records a recommended merge\nfor a person (`gbrain repair content` previews both kinds), for at most 120 s\nor a third of the remaining time. Pause both with\n`gbrain config set fences.repair.enabled false`.\n\nThe two new phases consolidate yesterday's conversations into long-term memory:\n\n**Synthesize phase (two-stage cascade):** reads the cycle source's transcripts from\n`dream.synthesize.session_corpus_dir` (another source's sessions wait for their own\n`gbrain dream --source \u003Cid> --phase synthesize`; unresolved or legacy files are held,\nalready-extracted ones included, until `gbrain sweep --assign-corpus \u003Csource>`), then triages before it spends: a cheap\nutility-tier judge (`models.dream.triage`) scores every new file 0–1 for\nsalience and pre-extracts candidate quotes + entities, cached in\n`dream_verdicts` with the judging model + prompt version (bounded per cycle\nby `dream.triage.max_ms`, default 5 min — deferred files retry next cycle,\nnever silently rejected). A file passes the gate two ways: it scores at or\nabove `dream.triage.threshold` (default 0.5), OR the **verified-segment\nrescue** fires — a score in `[dream.triage.rescue_floor, threshold)` still\npasses when at least `dream.triage.rescue_min_segments` (default 2; `0`\ndisables) of the judge's own quoted segments verify as substrings of the\ntranscript AND the content type is in `dream.triage.rescue_content_types`\n(default `mixed,reflection,idea,strategy,people` — never routine\u002Ftechnical).\nThe rescue costs nothing (no extra LLM calls, it re-reads the cached verdict)\nand it is what recovers real signal buried in an otherwise mundane transcript.\nThe whole gate is applied at READ time, so retuning the threshold or the\nrescue knobs re-gates with zero new LLM calls. Files that pass fan out one\nsynthesis subagent per transcript chunk, each primed with the triage map. By default\neach child runs in oneshot mode (`dream.synthesize.mode`, default `oneshot`):\nONE tool-less completion against a prompt carrying a pre-retrieved LINK\nCANDIDATES manifest (`dream.synthesize.link_manifest`, default on) and the\nwrite allow-list, validated end-to-end (slug fences, task shapes, wikilinks)\nbefore any page is written programmatically. A response that fails validation\nfalls back to the classic agentic loop in the same job, where the\n`dream.synthesize.max_turns` cap (default 16) applies; revert dial:\n`gbrain config set dream.synthesize.mode agentic`. Each child writes reflections\n(`wiki\u002Fpersonal\u002Freflections\u002F...`) and originals (`wiki\u002Foriginals\u002Fideas\u002F...`);\npeople timeline entries are written only on the agentic path (fallback or\n`mode agentic`), where the child has the `add_timeline_entry` tool. The orchestrator collects the slugs from\n`subagent_tool_executions` (NOT `pages.updated_at` — that would pick up\nunrelated writes), runs the quote verify pass over them (below), and\nreverse-renders each new page from DB → markdown on disk. To re-apply the\ngate after retuning the threshold or the rescue knobs, or to drain a queued\nbacklog, run `gbrain dream retriage --dry-run` (zero LLM calls, cached\nscores only) then `gbrain dream retriage --reconcile-queue`; `--force`\nre-judges everything from scratch. Retriage reads the SAME gate the cycle\ndoes, so a reconcile sweep never cancels a job the rescue admitted.\n\n**Claim verification (post-write, zero LLM):** after slug collection and\nbefore the reverse-write, `dream.synthesize.quote_verify` (default on) checks\nevery page this phase's children wrote against the transcripts that produced\nit. Pages created this run are checked whole; pages that already existed are\nchecked only on the sentences this run added. An exact quote is kept; a quote\nthat differs only in whitespace, curly quotes, dashes, or case, or a close\nparaphrase inside one speaker's turn, is replaced with the verbatim transcript\nslice. A sentence is quarantined when a quote grounds nowhere or only across\ntwo speakers, when it attributes a real quote to the wrong speaker, or when it\nstates a number or date the transcript lacks. Quarantined sentences leave the\npage body (and the timeline, facts and links derived from it) and are kept\nverbatim in frontmatter `unverified_claims`, which `get_page` shows but search,\nrecall and think do not read. Grounded quotes record their source span and\nspeaker in `grounding.quotes`. Nothing is ever fabricated. Telemetry lands in\n`details.synthesis.quote_verify`; the config key is the incident off switch.\n\n**Patterns phase:** runs after `extract` (so the graph state is fresh).\nReads recent reflections within `dream.patterns.lookback_days` (default 30),\nruns a single Sonnet pass to surface recurring themes, and writes pattern\npages to `wiki\u002Fpersonal\u002Fpatterns\u002F\u003Ctheme>` when ≥`dream.patterns.min_evidence`\n(default 3) reflections support a pattern. A completed run records the newest\nreflection it consumed (`dream.patterns.last_evidence_ts`); until a reflection\nin the window is newer than that, re-runs skip with `no_new_evidence` instead\nof paying for another model pass — `gbrain dream --phase patterns --once`\nforces one.\n\n**Quality bar (Iron Law for synthesis):**\n1. Quote the user verbatim. Quotation marks are ONLY for spans reproducible\n   EXACTLY from the transcript — if you cannot reproduce a span exactly,\n   paraphrase it WITHOUT quotation marks. Do not paraphrase memorable\n   phrasings you can quote exactly. (The quote verify pass enforces this\n   mechanically after the write.)\n2. Cross-reference compulsively: every new page MUST have at least one wikilink.\n3. Slug discipline: lowercase alphanumeric and hyphens only. NO underscores, NO file extensions.\n4. Edited transcripts produce NEW slugs (content-hash suffix changes) — never silently overwrite.\n5. Preserve concrete facts: carry the specific numbers, dates, dollar amounts,\n   names, and who-decided-what of the salient content, exactly as the\n   transcript states them. Do not pad with routine logistics.\n6. Ground every claim in the transcript. Attribute speculation as speculation,\n   and never state a completion state or outcome the transcript does not show.\n\n**Trust boundary (`allowed_slug_prefixes`):** the synthesis subagent runs with an\nexplicit allow-list of write paths sourced from `_brain-filing-rules.json`'s\n`dream_synthesize_paths.globs`. Even on prompt-injection success, the subagent\ncannot write outside that list. Trust comes from PROTECTED_JOB_NAMES — MCP\ncannot submit subagent jobs at all. Editing the JSON is the only way to add\na new directory the synthesizer can write to.\n\n**Idempotency + privacy:** transcripts are keyed by `(file_path, content_hash)`,\nso re-running on the same content is a no-op. `dream.synthesize.exclude_patterns`\n(default `[\"medical\", \"therapy\"]`) filters out transcripts before any LLM call.\nEach entry is auto-wrapped as a word-boundary regex (e.g. `medical` matches\n\"medical advice\" but NOT \"comedical\"). Power users may pass full regex.\n\n**Cooldown:** `dream.synthesize.cooldown_hours` (default 12) skips synthesize\nfor that long after a fully drained pass. The completion timestamp is stored\nin `dream.synthesize.last_completion_ts` and is written only when every child\ncompleted and nothing was deferred (synthesis budget, triage time budget or\npublish pending), never on skipped or failed runs. So under a standing\nbacklog the cooldown never applies and synthesize runs every cycle until the\nbacklog drains (#6753); it is not a cap of ~2 runs a day. To cap spend, use\n`dream.synthesize.max_submissions_per_source_per_day`. Explicit `--input` \u002F\n`--date` \u002F `--from` \u002F `--to` invocations bypass cooldown.\n\n**`--dry-run` semantics:** runs the scored triage pass (judges + caches\nverdicts for new files) but skips the synthesis subagents. NOT zero LLM\ncalls — for a zero-call preview from cached scores use\n`gbrain dream retriage --dry-run` instead.\n\n**Configure synthesize on a fresh brain:**\n```bash\ngbrain config set dream.synthesize.session_corpus_dir \u002Fpath\u002Fto\u002Ftranscripts\ngbrain config set dream.synthesize.enabled true\ngbrain dream --phase synthesize --dry-run --json   # preview\ngbrain dream                                       # full cycle\n```\n\n**Invocation patterns:**\n```bash\ngbrain dream                                          # full cycle\ngbrain dream --phase synthesize                       # just synthesize\ngbrain dream --phase patterns                         # just patterns\ngbrain dream --input ~\u002Ftranscripts\u002F2026-04-25.txt     # ad-hoc one transcript\ngbrain dream --from 2026-04-01 --to 2026-04-25        # backfill range\ngbrain dream --json                                   # CycleReport JSON\n```\n\n**Auto-commit deferred to v1.1:** v1 writes files to `brain_dir` but does NOT\n`git add` \u002F `commit` \u002F `push`. Either commit yourself or let `gbrain autopilot`\nhandle it.\nParses `- **YYYY-MM-DD** | Source — Summary` and `### YYYY-MM-DD — Title` formats.\nThe `Source — Summary` dash may be an em dash, an en dash or a spaced hyphen (` - `);\na colon (`Source: Summary`) is prose, so the row keeps `source: markdown` and the\nwhole text as its summary.\nNote: extracted entries improve structured queries (`gbrain timeline`), not vector search.\n\n### Autopilot check\nVerify autopilot is running:\n```bash\ngbrain autopilot --status\n```\nThe exit code is trustworthy for gating: 0 fresh (or nothing installed),\n1 needs attention (stale heartbeat, never ran, or paused by a migration),\n2 the daemon disabled itself (its repo path vanished). `--json` emits the\nfull report (`state`, `heartbeat_age_seconds`, `paused_reason`,\n`disabled_reason`). Status reads only the filesystem, so it works even\nwhen the database is down.\n\nIf not running, install it:\n```bash\ngbrain autopilot --install --repo ~\u002Fbrain\n```\nAutopilot runs sync, extract, and embed in a continuous loop with adaptive scheduling.\nIn v0.11.1+, autopilot dispatches each cycle as a single `autopilot-cycle`\nMinion job and supervises the worker child — one install step gives you\nsync + extract + embed + backlinks + durable job processing.\n\n### Fix a half-migrated install\nA v0.11.0 install where the migration skill never fired leaves Minions\npartially set up: schema is applied, but `~\u002F.gbrain\u002Fpreferences.json`\ndoesn't exist, autopilot runs inline, host manifests still reference\n`agentTurn`. Repair:\n\n```bash\n# Check migration status\ngbrain apply-migrations --list\n\n# Apply pending migrations (idempotent; safe on healthy installs)\ngbrain apply-migrations --yes\n\n# If host-specific handlers are flagged in ~\u002F.gbrain\u002Fmigrations\u002Fpending-host-work.jsonl:\n# walk them per skills\u002Fmigrations\u002Fv0.11.0.md + docs\u002Fguides\u002Fplugin-handlers.md,\n# ship handler registrations in the host repo, then re-run apply-migrations.\n```\n\nFull troubleshooting guide: `docs\u002Fguides\u002Fminions-fix.md`.\n\n### Back-link enforcement\nCheck that the back-linking iron law is being followed:\n- For each recently updated page, check if entities mentioned in it have\n  corresponding back-links FROM those entity pages\n- A mention without a back-link is a broken brain\n- Fix: add the missing back-link to the entity's Timeline or See Also section\n- Format: `- **YYYY-MM-DD** | Referenced in [page title](path) -- brief context`\n\n### Filing rule violations\nCheck for common misfiling patterns (see `skills\u002F_brain-filing-rules.md`):\n- Content with clear primary subjects filed in `sources\u002F` instead of the\n  appropriate directory (people\u002F, companies\u002F, concepts\u002F, etc.)\n- Use gbrain search to find pages in `sources\u002F` that reference specific\n  people, companies, or concepts -- these may be misfiled\n- Flag misfiled pages for review or re-filing\n\n### Citation audit\nSpot-check pages for missing `[Source: ...]` citations:\n- Read 5-10 recently updated pages\n- Check that compiled truth (above the line) has inline citations\n- Check that timeline entries have source attribution\n- Flag pages where facts appear without provenance\n\n### Tag consistency\nInconsistent tagging (e.g., \"vc\" vs \"venture-capital\", \"ai\" vs \"artificial-intelligence\").\n- Standardize to the most common variant using gbrain tag operations\n\n### Graph population (v0.10.3+)\n\nThe `links` and `timeline_entries` tables are the structured graph layer.\nPopulate them periodically or after major imports:\n\n- `gbrain extract links --source db` — backfill structured links by walking pages\n  from the engine. Reads `[Name](people\u002Fslug)` \u002F `[Name](companies\u002Fslug)` references\n  and infers relationship types (`attended`, `works_at`, `invested_in`, `founded`,\n  `advises`, `mentions`, `source`). Idempotent. Use `--source fs --dir \u003Cbrain>`\n  if you have a markdown checkout to walk instead.\n- `gbrain extract timeline --source db` — backfill structured timeline entries.\n  Parses `- **YYYY-MM-DD** | summary` lines from page content. Idempotent (DB\n  UNIQUE constraint).\n- `gbrain extract all --source db` — both in one run.\n- `gbrain graph-query \u003Cslug> --depth 2` — verify connectivity (use any well-known\n  entity slug as a probe).\n- `gbrain stats` — verify `link_count > 0` and `timeline_entry_count > 0` after extraction.\n- `gbrain health` — review `link_coverage` and `timeline_coverage` percentages\n  on entity pages (person\u002Fcompany). Below 50% means more extraction is needed.\n  On brains with very few entity pages these report \"too few to grade\"\n  (`null` in JSON, with `entity_page_count` carrying the denominator) instead\n  of a misleading 0%\u002F100% — grow the entity set before acting on coverage.\n\nAvailable link types (use with `gbrain graph-query --type`):\n`attended`, `works_at`, `invested_in`, `founded`, `advises`, `mentions`, `source`.\n\nGoing forward, every `gbrain put` call auto-creates and reconciles links via the\nauto-link post-hook (default on; disable: `gbrain config set auto_link false`).\nSo link-extract is mostly a one-time backfill. timeline-extract should be re-run\nafter bulk imports or content edits that add new dated entries.\n\n### Feature adoption check (weekly)\n```bash\ngbrain features --json    # scan for underused features + recommendations\n```\nRun weekly alongside lint. Surfaces missing embeddings, unused integrations,\nand configuration improvements.\n\n### Embedding freshness\nChunks without an embedding yet (`--stale` selects exactly those). Embedding\ncalls the configured provider, which bills per token, so this is paid work\nthat needs the user's approval first:\n1. Preview with no provider calls: `gbrain embed --stale --dry-run`.\n2. Relay the chunk count and cost estimate to the user and wait for an answer.\n3. Only after they agree, run `gbrain embed --stale --yes --max-usd \u003Ccap>`\n   with the cap they approved.\n\nWithout approval the command stops with exit 3 and an `[AGENT]` block asking\nyou to ask the user; relay it and stop. Never pass `--yes` on your own.\nFor a long run (>1000 chunks), route the approved command through the\ndurable ladder in `skills\u002Fminion-orchestrator\u002FSKILL.md` instead of a bare\nbackground shell, which hides that exit 3 in a log file.\n\nTo see what search cannot reach on one source, run\n`gbrain pages unsearchable --source \u003Cid> --json` (read-only). Read\n`semantic_unsearchable`, not only `unsearchable`: it adds `keyword_only`\npages, which keyword search finds but vector search misses. `awaiting_sync`\ncounts files sync still holds, which no embedding state includes; follow\n`gbrain sync status --source \u003Cid> --json` for those. Each row carries its `fix`.\n\n### Security (RLS verification)\nRun `gbrain doctor --json` and check the RLS status.\nAll tables should show RLS enabled. If not, run `gbrain init` again.\n\n### Schema health\nCheck that the schema version is up to date. `gbrain doctor --json` reports\nthe current version vs expected. If behind, `gbrain init` runs migrations\nautomatically.\n\n### File storage health\nCheck the integrity of stored files and redirect pointers:\n- Run `gbrain files verify` to check all DB records have valid data\n- Run `gbrain files status` to see migration state (local, mirrored, redirected)\n- Check for orphan `.redirect.yaml` pointers that reference missing storage files\n- Check for large binary files (>= 100 MB) still in git that should be in cloud storage\n- If storage backend is configured: verify redirect pointers resolve (download test)\n\n### Open threads\nTimeline items older than 30 days with unresolved action items.\n- Flag for review\n\n## Benchmark Testing\n\nPeriodically verify search quality hasn't regressed. Run a battery of test\nqueries across difficulty tiers:\n\n- **Tier 1 (entity lookup):** known names -- should always resolve\n- **Tier 2 (topic recall):** concepts, topics -- keyword search should handle\n- **Tier 3 (semantic):** queries with no exact keyword match -- needs embeddings\n- **Tier 4 (cross-domain):** relational\u002Fconnection queries -- only semantic handles\n\nCompare results from `gbrain search` (keyword) vs `gbrain query` (hybrid).\nQuality matters more than speed (2.5s right > 200ms wrong).\n\nWhen to run benchmarks:\n- After major brain imports or re-imports\n- After gbrain version upgrades\n- After embedding regeneration\n- Monthly to track quality drift\n\n## Heartbeat Integration\n\nFor production agents running on a schedule, integrate gbrain health checks into\nyour operational heartbeat.\n\n### On every heartbeat (hourly or per-session)\n\nRun `gbrain doctor --json` and check for degradation. Report any failing checks\nto the user. Key signals: connection health, schema version, RLS status, embedding\nstaleness.\n\n### Weekly maintenance\n\nRefresh embeddings for chunks that have none yet, with the same consent steps\nas \"Embedding freshness\" above: `gbrain embed --stale --dry-run`, relay the\nestimate, and after the user agrees `gbrain embed --stale --yes --max-usd \u003Ccap>`\n(or a standing approval the user set with\n`consent.preapprove.paid.max_usd_per_run`). For large brains (>5000 pages),\nsubmit the approved command through the minion-orchestrator durable ladder;\nif you must background it in a shell, keep the exit code:\n```bash\n(gbrain embed --stale --yes --max-usd \u003Ccap>; echo \"exit=$?\") > \u002Ftmp\u002Fgbrain-embed.log 2>&1 &\ntail -2 \u002Ftmp\u002Fgbrain-embed.log   # later: the last line is exit=\u003Ccode>\n```\nExit 3 in that log means the run needs the user's approval: relay it and stop.\n\n### Monthly backup check\n\nRun `gbrain backup status` and relay anything red. It verifies every knowledge\nrepo (and the agent workspace) has a git remote — local-only means a disk loss\nloses it. Fixes are printed inline (`gbrain bootstrap repo`, `git remote add`,\n`gbrain sources harden \u003Cid>`).\n\n### Daily verification\n\nVerify sync is running: check `gbrain stats` and confirm `last_sync` is within\nthe last 24 hours. If sync has stopped, the brain is drifting from the repo.\n\n### Stale compiled truth detection\n\nFlag pages where compiled truth is >30 days old but the timeline has recent entries.\nThis means new evidence exists that hasn't been synthesized. These pages need a\ncompiled truth rewrite (see the maintain workflow above).\n\n## Report Storage\n\nAfter maintenance runs, save a report:\n- Health check results (before\u002Fafter scores for each dimension)\n- Back-link violations found and fixed\n- Filing rule violations found\n- Citation gaps flagged\n- Benchmark results (if run)\n- Outstanding issues requiring user attention\n\nThis creates an audit trail for brain health over time.\n\n## Quality Rules\n\n- Never delete pages without confirmation\n- Log all changes via timeline entries\n- Check gbrain health before and after to show improvement\n\n## When it fails\n\nFollow the [agent operator protocol](..\u002Fconventions\u002Fagent-operator-protocol.md) for any gbrain error `code`, exit code, `[AGENT]` block or notice block. Specific to this skill:\n\n- `gbrain doctor --remediate` steps marked \"requires user agreement\" (PROTECTED repairs, paid steps): show the plan and cost, and run with `--yes --include-repairs --expect \u003Cplan_hash> --max-usd \u003Cn>` (the hash from `--remediation-plan --json`) only after the user agrees; `preview_changed` means the plan moved, so preview and ask again. A step that would exceed the cap is not started.\n- A finding classified `operator_required`: follow its instruction or relay it to the brain host's operator. `consent_required`: ask the user.\n- A writer-coordination refusal (`writer_coordinator_required`, `writer_not_quiesced`, `recovery_required`): inspect `gbrain sources writer status` and hand the blocked recovery to the operator; never claim a checkout or delete a lock.\n- Doctor warns `persistence_terminal_failures`: run its `fix.command` (an active blocker: a recovery record or a sync checkpoint blocker; or an unresolved gbrain-defect class to report with the receipt ids). For the rest of the pile, `gbrain sources writer failures \u003Csource> --group-by category` (read-only) groups receipts with a fix and drill-down per group; historical rows need nothing. Never cancel or edit receipts to clear the count. Runbook: [terminal write failures](https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fdocs\u002Fguides\u002Ftroubleshooting.md#terminal-write-failures).\n- `gbrain dream` stops on a budget (exit 11): run the printed `resume_command` within the agreed budget.\n\n## Anti-Patterns\n\n- Fixing pages without reading them first -- you must understand context before editing\n- Silently skipping dimensions -- every dimension must be checked and reported, even if clean\n- Deleting orphan pages without checking if they should be linked instead\n- Running embedding refresh during peak usage hours\n- Batch-fixing back-links without verifying the relationship is real\n- Marking a dimension \"clean\" without actually querying it\n- Rewriting compiled truth without reading the full timeline first\n- Removing tags without checking if other pages use the same tag consistently\n\n## Output Format\n\nThe maintenance report follows this structure:\n\n```\n## Brain Health Report — YYYY-MM-DD\n\n| Dimension           | Issues Found | Fixed | Remaining |\n|----------------------|-------------|-------|-----------|\n| Stale pages          | N           | N     | N         |\n| Orphan pages         | N           | N     | N         |\n| Dead links           | N           | N     | N         |\n| Missing cross-refs   | N           | N     | N         |\n| Back-link violations | N           | N     | N         |\n| Citation gaps        | N           | N     | N         |\n| Filing violations    | N           | N     | N         |\n| Tag inconsistencies  | N           | N     | N         |\n| Embedding staleness  | N           | N     | N         |\n| Security (RLS)       | N           | N     | N         |\n| Schema health        | N           | N     | N         |\n| File storage         | N           | N     | N         |\n| Open threads         | N           | N     | N         |\n\n### Details\n[Per-dimension breakdown with specific pages and actions taken]\n\n### Benchmark Results (if run)\n[Tier 1-4 query results with pass\u002Ffail]\n\n### Outstanding Issues\n[Items requiring user attention or confirmation]\n```\n\n## Tools Used\n\n- Check gbrain health (get_health; admin scope)\n- Check banded brain health without admin scope (get_brain_health)\n- List pages in gbrain with filters (list_pages)\n- Read a page from gbrain (get_page)\n- Check backlinks in gbrain (get_backlinks)\n- Link entities in gbrain (add_link)\n- Remove links in gbrain (remove_link)\n- Tag a page in gbrain (add_tag)\n- Remove a tag in gbrain (remove_tag)\n- View timeline in gbrain (get_timeline)\n",{"name":5,"tools":44,"version":52,"mutating":53,"triggers":54,"upstream":75,"description":76},[45,46,47,48,49,50,51,38],"get_health","get_brain_health","get_page","put_page","list_pages","get_backlinks","add_link","1.1.0",true,[55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],"brain health","check backlinks","maintenance","orphan pages","stale pages","extract links","build link graph","populate timeline","populate links","backfill graph","extract timeline entries","retriage the backlog","re-score the triage","run dream","process today's session","process yesterday's transcripts","synthesize my conversations","what patterns did you see","did the dream cycle run","consolidate yesterday's conversations","maintain@fc834ee","Brain health checks: back-link enforcement, citation audit, filing validation,\nstale info detection, orphan pages, and benchmarks. Use when asked to check\nbrain health, run maintenance, or audit quality.\n","master","074ec301549ded4930f04d2c3b22d709a6c095cc","skills\u002Fmaintain",4871,"https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain","https:\u002F\u002Fgithub.com\u002Fgarrytan","https:\u002F\u002Fblog.garrytan.com","Writes software, dreams. ","2026-11-12 04:41:06",{"source":8,"skillName":5,"commands":87,"prompt":97,"zipAvailable":53},[88,91,94],{"tool":89,"command":90},"npx","npx skills add garrytan\u002Fgbrain --skill maintain",{"tool":92,"command":93},"bunx","bunx skills add garrytan\u002Fgbrain --skill maintain",{"tool":95,"command":96},"pnpm","pnpm dlx skills add garrytan\u002Fgbrain --skill maintain","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fmaintain\u002FSKILL.md",[],[100,112,118,140,166,179],{"skillNo":101,"name":102,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":39},"01M6N109FNGH1PK49T734PZXGB","query-helper","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fquery-helper\u002FSKILL.md",[],[106,107,108,38,109,110,111],"query helper","helper","query","page","find","false",{"skillNo":113,"name":114,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":39},"01M6N108A23GW6NGQEQ0E7GV0A","broken","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbroken\u002FSKILL.md",[],[114],{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":39},"01M6N105E88C5K2H03H0CC79G1","brain-ops","Read, enrich, and write brain pages with source attribution.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbrain-ops\u002FSKILL.md",[],[125,27,126,127,128,109,129,130,131,132,108,133,134,135,136,137,138,139,38],"brain ops","ops","true","attribution","read","write","up","look","pages","people","with","enrich","web","path","source",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":151,"publishedAt":39},"01M6N102GRMF22TVCNT6RK5MRD","meeting-prep","Build a briefing before you meet someone, from their recent threads, open loops and what they care about.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Fmeeting-prep\u002FSKILL.md",[146],{"categoryNo":147,"categoryName":148,"taxonomyType":149,"taxonomyTypeDesc":150},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[152,153,154,155,156,38,157,158,159,108,111,160,161,24,162,163,164,165],"meeting","prep","meeting prep","me","prepare","brief","open","build","loops","about","briefing","threads","for","Meet",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":39},"01M6N1005QK7REHX5KGMNR5PF0","inbox-zero","Triage the inbox into replies, delegations and archives.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Finbox-zero\u002FSKILL.md",[],[173,174,175,38,176,111,177,21,178],"inbox zero","ZeRO","inbox","clear","replies","triage",{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":183,"categories":184,"keywords":185,"publishedAt":39},"01M6N0ZXQ8RRRW71PNV61T57GP","deal-memo","Draft an investment memo from the deal pages and the founder history already in the brain.","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog-query\u002Fskills\u002Fdeal-memo\u002FSKILL.md",[],[186,187,188,133,27,189,190,130,191,127,38,192],"deal memo","deal","memo","draft","investment","history","founder"]