diff --git a/CHANGELOG.md b/CHANGELOG.md index a6d56eb29..f105aa5cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,46 @@ All notable changes to GBrain will be documented in this file. +## [0.31.10] - 2026-05-10 + +**Setup hands you a real bootstrap, not an empty brain. New `cold-start` skill sequences day-1 imports across markdown, contacts, calendar, email, conversations, X, archives, and meeting transcripts. New `ask-user` choice-gate pattern. Phase J in `setup` auto-launches cold-start when verification passes.** + +The setup skill has always ended with a working brain that's empty, leaving every new user asking "now what?" v0.31.10 closes that gap. After `gbrain doctor` confirms a healthy install, the agent now offers to populate the brain through a priority-ranked sequence of data sources, gated on user consent at every phase. Each phase delegates to existing recipes (`email-to-brain.md`, `calendar-to-brain.md`, `x-to-brain.md`) and skills (`meeting-ingestion`); cold-start is orchestration, not reimplementation. Resume state at `~/.gbrain/cold-start-state.json` matches the existing `update-state.json` convention. + +### What you can now do + +**Bootstrap a brain from scratch in one session.** The new `cold-start` skill sequences eight phases ranked by information density times ease: existing markdown / Obsidian (Tier 1) → Google Contacts → Google Calendar (90-day lookback) → Gmail (smart sample) → conversation exports (ChatGPT / Claude) → X / Twitter archive → file archives (Dropbox / Drive / local) → meeting transcripts (Circleback / Otter / Fireflies). Each phase is independently valuable; stop after any phase and resume from `~/.gbrain/cold-start-state.json` later. Trigger with "cold start", "fill my brain", or "what should I import first". + +**Setup auto-launches cold-start (Phase J).** After `gbrain doctor` passes, the setup skill no longer ends with "next steps: read the docs." It asks "Ready to populate your brain?" and transitions directly into cold-start. Decline once and it is deferred to `~/.gbrain/cold-start-state.json` with a `deferred` flag. Invoke later with the same trigger phrase. + +**Choice-gate pattern is now a documented convention.** `skills/ask-user/SKILL.md` codifies the "present 2-4 options, stop, wait" pattern that cold-start uses at every phase boundary. Platform-agnostic across Telegram inline buttons, Discord, CLI numbered options, and agent-native clarify tools. + +### How it works under the hood + +Cold-start is an orchestration skill, not a CLI command. The phase ordering ranks by information density times ease: existing markdown delivers the most pages per minute (already structured, no API), file archives deliver the fewest. Each phase delegates to a recipe (for direct OAuth setups) or to ClawVisor (for credential-vaulted setups). The skill never holds raw OAuth tokens; that posture is encoded at Phase 0. State persists across agent-loop crashes via `~/.gbrain/cold-start-state.json`; the resume protocol picks up at the first phase where `completed: false`. + +### Known limitations (will be addressed in follow-ups) + +**ClawVisor is currently required for the API-backed phases (Contacts, Calendar, Gmail).** The recipes (`recipes/email-to-brain.md`, `recipes/calendar-to-brain.md`) document a dual A / B pattern with direct-OAuth as Option B. Cold-start's Phase 0 will be relaxed to mirror that pattern in v0.32. If you do not want to use ClawVisor today, skip Phases 2-4 and run Phases 1, 5-8 for offline-only sources. + +**Phase-level resume granularity.** A mid-phase failure (e.g., contact 487 of 600) restarts the phase from contact 1. Idempotent slug writes prevent duplicates, but the round-trip cost is real. Per-item resume lands with the `gbrain cold-start` CLI counterpart in v0.32. + +### To take advantage of v0.31.10 + +```bash +gbrain upgrade +``` + +Then ask the agent to "fill my brain" or "cold start" to launch the new orchestration. If you have already run setup, run it again to get the new Phase J handoff, or invoke cold-start directly with the trigger phrase. State files live at `~/.gbrain/cold-start-state.json` and survive restarts. + +If you do not want ClawVisor today, run Phases 1 (markdown) and 5-8 (conversations, X, archives, transcripts) directly. Phases 2-4 (Contacts / Calendar / Gmail) will become opt-in to direct OAuth in v0.32. + +### For contributors + +Cold-start originated as PR #802. The branch shipped three commits including one that flipped ClawVisor from "recommended" to "required for API access." Codex outside-voice review of the v0.31.10 ship plan flagged that as vendor-coupling that prematurely cements ClawVisor as the public contract. The known-limitation above is the bridge: v0.31.10 ships the contributor's posture, v0.32 restores the dual-recipe pattern. Privacy scrub on the merging PR replaced "Hermes Agent" references in the new `ask-user` skill (which conflated the public NousResearch agent with private deployment names) with the canonical "OpenClaw agents" phrasing per CLAUDE.md doctrine. + +The version slot is deliberate. v0.31.4 through v0.31.9 are reserved for in-flight work; v0.31.10 was chosen so this user-facing skillpack expansion lands clearly above the patch-train. + ## [0.31.8] - 2026-05-10 **Multi-source brains stop misrouting writes, and `gbrain doctor` finally tells you when it does.** diff --git a/VERSION b/VERSION index e957dfa8d..673675043 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.31.8 +0.31.10 diff --git a/docs/GBRAIN_SKILLPACK.md b/docs/GBRAIN_SKILLPACK.md index 131328fdf..e1ad2ae44 100644 --- a/docs/GBRAIN_SKILLPACK.md +++ b/docs/GBRAIN_SKILLPACK.md @@ -102,6 +102,16 @@ Keeping it running and up to date. | [Upgrades & Auto-Update](guides/upgrades-auto-update.md) | check-update, agent notifications, migration files | | [Live Sync](guides/live-sync.md) | Keep the index current: cron, --watch, webhook approaches | +## Getting Started + +After setup, the brain is empty. The cold-start skill sequences the highest-leverage +data sources to populate it: + +| Guide | What It Covers | +|-------|---------------| +| [Cold Start](../skills/cold-start/SKILL.md) | Day-one bootstrapping: contacts, calendar, email, conversations, social, archives. Uses ClawVisor for safe credential handling — agents never hold raw API keys. | +| [Ask User](../skills/ask-user/SKILL.md) | Choice-gate pattern for human input at decision points. Used by cold-start and other skills. | + --- ## Appendix: GBrain CLI Quick Reference diff --git a/llms-full.txt b/llms-full.txt index 1c22f5744..01487d129 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1732,12 +1732,14 @@ This is the dispatcher. Skills are the implementation. **Read the skill file bef | "Validate skills", skill health check | `skills/testing/SKILL.md` | | Webhook setup, external event processing | `skills/webhook-transforms/SKILL.md` | | "Spawn agent", "background task", "parallel tasks", "steer agent", "pause/resume agent", "gbrain jobs submit", "submit a gbrain job", "submit a shell job", "shell job" | `skills/minion-orchestrator/SKILL.md` | +| "present options", "ask before proceeding", "choice gate", "user decision" | `skills/ask-user/SKILL.md` | ## Setup & migration | Trigger | Skill | |---------|-------| | "Set up GBrain", first boot | `skills/setup/SKILL.md` | +| "Now what?", "fill my brain", "cold start", "bootstrap", "import my data", "what should I import first" | `skills/cold-start/SKILL.md` | | "Migrate from Obsidian/Notion/Logseq" | `skills/migrate/SKILL.md` | | Brain health check, maintenance run | `skills/maintain/SKILL.md` | | "Extract links", "build link graph", "populate timeline" | `skills/maintain/SKILL.md` (extraction sections) | @@ -1764,7 +1766,7 @@ When multiple skills could match: 2. If the user mentions a URL, route by content type (link → idea-ingest, video → media-ingest) 3. If the user mentions a person/company, check if enrich or query fits better 4. Chaining is explicit in each skill's Phases section -5. When in doubt, ask the user +5. When in doubt, ask the user (see `skills/ask-user/SKILL.md` for the choice-gate pattern) ## Conventions (cross-cutting) @@ -1773,6 +1775,7 @@ These apply to ALL brain-writing skills: - `skills/conventions/brain-first.md` — check brain before external APIs - `skills/conventions/brain-routing.md` — which brain (DB) and which source (repo) to target; cross-brain federation is latent-space only - `skills/conventions/subagent-routing.md` — when to use Minions vs inline work +- `skills/ask-user/SKILL.md` — choice-gate pattern for human input at decision points - `skills/_brain-filing-rules.md` — where files go - `skills/_output-rules.md` — output quality standards diff --git a/package.json b/package.json index b02f51179..12b39eb0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gbrain", - "version": "0.31.8", + "version": "0.31.10", "description": "Postgres-native personal knowledge brain with hybrid RAG search", "type": "module", "main": "src/core/index.ts", diff --git a/skills/RESOLVER.md b/skills/RESOLVER.md index 9e8a664ef..a35798cf6 100644 --- a/skills/RESOLVER.md +++ b/skills/RESOLVER.md @@ -61,12 +61,14 @@ This is the dispatcher. Skills are the implementation. **Read the skill file bef | "Validate skills", skill health check | `skills/testing/SKILL.md` | | Webhook setup, external event processing | `skills/webhook-transforms/SKILL.md` | | "Spawn agent", "background task", "parallel tasks", "steer agent", "pause/resume agent", "gbrain jobs submit", "submit a gbrain job", "submit a shell job", "shell job" | `skills/minion-orchestrator/SKILL.md` | +| "present options", "ask before proceeding", "choice gate", "user decision" | `skills/ask-user/SKILL.md` | ## Setup & migration | Trigger | Skill | |---------|-------| | "Set up GBrain", first boot | `skills/setup/SKILL.md` | +| "Now what?", "fill my brain", "cold start", "bootstrap", "import my data", "what should I import first" | `skills/cold-start/SKILL.md` | | "Migrate from Obsidian/Notion/Logseq" | `skills/migrate/SKILL.md` | | Brain health check, maintenance run | `skills/maintain/SKILL.md` | | "Extract links", "build link graph", "populate timeline" | `skills/maintain/SKILL.md` (extraction sections) | @@ -93,7 +95,7 @@ When multiple skills could match: 2. If the user mentions a URL, route by content type (link → idea-ingest, video → media-ingest) 3. If the user mentions a person/company, check if enrich or query fits better 4. Chaining is explicit in each skill's Phases section -5. When in doubt, ask the user +5. When in doubt, ask the user (see `skills/ask-user/SKILL.md` for the choice-gate pattern) ## Conventions (cross-cutting) @@ -102,6 +104,7 @@ These apply to ALL brain-writing skills: - `skills/conventions/brain-first.md` — check brain before external APIs - `skills/conventions/brain-routing.md` — which brain (DB) and which source (repo) to target; cross-brain federation is latent-space only - `skills/conventions/subagent-routing.md` — when to use Minions vs inline work +- `skills/ask-user/SKILL.md` — choice-gate pattern for human input at decision points - `skills/_brain-filing-rules.md` — where files go - `skills/_output-rules.md` — output quality standards diff --git a/skills/_brain-filing-rules.json b/skills/_brain-filing-rules.json index b612837fd..f266d421c 100644 --- a/skills/_brain-filing-rules.json +++ b/skills/_brain-filing-rules.json @@ -122,6 +122,24 @@ "directory": "media/articles/", "examples": ["personalized article reads", "long-form content tailored to reader"], "description": "Same sanctioned exception as media/books/. One-of-one synthesis output of an article personalized for the reader. Distinct from raw article ingest, which goes to the article's primary-subject directory." + }, + { + "kind": "daily", + "directory": "daily/", + "examples": ["daily/calendar/YYYY-MM-DD.md", "daily/notes/YYYY-MM-DD.md"], + "description": "Date-keyed pages for events, calendar entries, or daily notes. Calendar imports land at daily/calendar/YYYY-MM-DD.md with attendees cross-linked to people/. Use when the primary subject is the date itself, not a person or topic." + }, + { + "kind": "media-format", + "directory": "media/", + "examples": ["media/x/{handle}/", "media/audio/", "media/video/"], + "description": "Format-prefixed parent for media-by-source-format ingest. Subdirectories like media/x/{handle}/ hold X/Twitter archives, media/audio/ holds podcast/voice captures. The format-prefix lives only when the content is sui generis to the source format AND lacks a clean primary-subject directory. Prefer subject-by-subject filing; fall through to media/ only when the source format IS the unifying frame." + }, + { + "kind": "conversation", + "directory": "conversations/", + "examples": ["conversations/chatgpt/{thread-slug}.md", "conversations/claude/{thread-slug}.md"], + "description": "Imported chat exports (ChatGPT, Claude, etc.) where the conversation itself is the artifact. Cross-link concepts and people from the conversation; the conversation page is the source-of-truth for the dialog. Distinct from voice-notes/ (which holds raw voice capture)." } ], "sources_dir": { diff --git a/skills/ask-user/SKILL.md b/skills/ask-user/SKILL.md new file mode 100644 index 000000000..deacbb44a --- /dev/null +++ b/skills/ask-user/SKILL.md @@ -0,0 +1,253 @@ +--- +name: ask-user +version: 1.0.0 +description: | + Reusable pattern for presenting the user with explicit choices and gating + execution until they respond. Used by other skills when a decision point + requires human input before proceeding. Platform-agnostic — works on + Telegram (inline buttons), Discord, CLI, or any agent with a message tool. +triggers: + - "present options" + - "ask before proceeding" + - "choice gate" + - "user decision" +priority: 50 +--- + +# Ask User — Choice Gate Pattern + +## Contract + +- Present 2-4 options (no more — decision paralysis kicks in past 4). +- Always include an escape hatch (Skip, Cancel, or "none of these"). +- Stop the turn immediately after presenting choices. No follow-up tool calls, + no preemptive action, no default-and-proceed. +- The user's response triggers the next turn. Acknowledge briefly, then branch. +- One question per message — never stack multiple choice gates. +- Self-explanatory option labels: action verb plus brief qualifier, not "Option 1". + +## What This Is + +A **formalized pattern** for presenting users with 2-4 options and **stopping +execution** until they respond. This is the canonical way to gate on user input +in any GBrain-powered agent. + +This is NOT a traditional async/await. In an LLM agent, "gating" means: +1. Present the choices (buttons or numbered options) +2. Explicitly stop the current turn (do not proceed) +3. The user's response triggers the next turn +4. Read the response and branch accordingly + +## When To Use + +- Ambiguous requests with multiple valid interpretations +- Destructive operations (bulk deletes, overwrites) +- Filing/routing decisions ("where should this go?") +- Priority triage ("which should I do first?") +- Cold-start phase gates ("ready for the next import source?") +- Any fork where the wrong default wastes significant work + +## When NOT To Use + +- Clear, unambiguous instructions → just do it +- Low-stakes decisions → pick the best option and mention it +- Time-critical operations where delay costs more than a wrong choice +- When the user has already expressed a preference + +## How To Present Choices + +### Platform-agnostic format (works everywhere) + +Present choices as a clear question with numbered or labeled options: + +``` +🔀 **How should I handle this?** + +[context about the decision — 1-3 lines max] + +1. **Option A** — short description +2. **Option B** — short description +3. **Option C** — short description +4. **Skip** — do nothing for now +``` + +### With inline buttons (Telegram, Discord, Slack) + +If the platform supports interactive buttons, use them: + +```json +{ + "message": "🔀 **How should I handle this?**\n\n", + "buttons": [ + { "label": "Option A — description", "value": "option_a" }, + { "label": "Option B — description", "value": "option_b" }, + { "label": "Skip", "value": "skip" } + ] +} +``` + +### With the `clarify` tool (OpenClaw agents) + +Some OpenClaw agents have a built-in `clarify` tool that presents choices natively: + +``` +clarify( + question: "How should I handle this?", + choices: [ + "Option A — description", + "Option B — description", + "Option C — description", + "Skip for now" + ] +) +``` + +## Constraints + +- **2-4 options max.** More than 4 creates decision paralysis. +- **Labels must be self-explanatory.** The user shouldn't need to re-read context. +- **Always include an escape hatch.** At minimum: "Skip" or "Cancel" as the last option. +- **One question per message.** Never stack multiple choice gates. + +## How To Gate (CRITICAL) + +After presenting choices, **you MUST stop your turn.** Do not: +- ❌ Continue with "while you decide, I'll start on..." +- ❌ Pick a default and proceed +- ❌ Send follow-up messages before the user responds +- ❌ Make assumptions about which option they'll pick + +Instead: +- ✅ End your message with a brief note that you're waiting +- ✅ Stop. Full stop. No more tool calls. + +## How To Handle The Response + +When the user responds: + +1. **Read the response** — button click, number, or text +2. **Acknowledge briefly** — "Got it, going with Option A." +3. **Branch and execute** the chosen path +4. If unclear, ask again + +### Handling text responses + +Users sometimes type instead of clicking. Handle gracefully: +- "the first one" / "A" / "1" → map to first option +- "merge" → fuzzy match against option labels/values +- "actually, none of those" → present alternatives or ask what they want +- Unrelated message → the user moved on; drop the gate + +## Formatting Guidelines + +### Question line emoji prefix + +Signal the decision type: +- 🔀 Routing/filing decisions +- ⚠️ Destructive/risky operations +- 🎯 Priority/triage decisions +- 💡 Creative/strategic forks +- 📋 Workflow/process choices +- 🔐 Credential/security decisions + +### Context block + +1-3 lines maximum. The user should understand the decision in under 5 seconds. + +### Button/option labels + +Format: `Action verb — brief qualifier` +- ✅ "Merge — combine with existing page" +- ✅ "Create new — separate meeting page" +- ❌ "Option 1" +- ❌ "Click here to merge the content into the existing brain page" + +## Examples + +### Cold-start phase gate +``` +📋 **Phase 2: Google Contacts** + +I can import your Google Contacts to seed the people/ directory. +This creates a brain page for each real contact (~200 pages). + +1. **Import via ClawVisor** — secure credential gateway +2. **Import via direct OAuth** — simpler, agent holds tokens +3. **Import from Google Takeout export** — offline, from file +4. **Skip** — move to the next phase +``` + +### Filing decision +``` +🔀 **Where should this go?** + +Meeting notes from call with Jane Smith. She already has a page at +people/jane-smith.md and there's a deal page at deals/acme-corp.md. + +1. **Merge into Jane's page** — add to her timeline +2. **Add to Acme deal page** — this was primarily a deal discussion +3. **New meeting page** — standalone at meetings/2026-01-15-jane-acme.md +4. **Skip** — don't file this +``` + +### Destructive operation +``` +⚠️ **About to delete 847 stale cache files (2.3 GB)** + +These haven't been accessed in 90+ days. They can be re-fetched +but that takes ~4 hours. + +1. **Delete them** — free up space now +2. **Archive first** — upload to cloud storage, then delete +3. **Keep them** — no changes +4. **Show me the list** — let me review before deciding +``` + +## Integration With Other Skills + +This pattern is used by: +- **cold-start** — phase gates for each import source +- **ingest** — routing decisions for ambiguous content +- **enrich** — merge vs create decisions for entity pages +- **brain-ops** — filing location decisions +- **meeting-ingestion** — where to file meeting notes +- **archive-crawler** — scan vs full ingestion gate + +When building a new skill that needs user input at a decision point, +reference this pattern rather than inventing a new one. + +## Anti-Patterns + +- **Continuing the turn after presenting choices.** "While you decide, I'll start on..." + defeats the gate. Stop. Wait. The whole point is that the user controls what happens next. +- **Picking a default and proceeding silently.** If the question matters enough to ask, + it matters enough to wait. Silent defaults erode trust the next time you do ask. +- **More than 4 options.** Decision paralysis is real. Group, summarize, or split into + staged questions instead. +- **No escape hatch.** Every choice gate must let the user decline. "None of these" + / "Skip" / "Cancel" is mandatory. +- **Stacking multiple choice gates in one message.** The user can only answer one + question per turn. Multi-question gates either get half-answered or dropped entirely. +- **Cryptic option labels.** "Option 1" forces re-reading the context. "Merge into + existing page" is self-explanatory. +- **Asking about low-stakes decisions.** If the wrong answer costs nothing, just pick + the best option and mention it. Reserve gates for forks where rework is expensive. + +## Output Format + +The skill's "output" is the choice-gate message itself, structured as: + +``` +{emoji-prefix} **{question}** + +{1-3 lines of context} + +1. **{Option A label}** — {short qualifier} +2. **{Option B label}** — {short qualifier} +3. **{Skip / Cancel}** — {what skipping means} +``` + +After emitting this, the skill stops the turn. No further tool calls, no +preemptive action, no follow-up message until the user responds. The +user's response triggers the next turn, where the calling skill branches +on the chosen option. diff --git a/skills/cold-start/SKILL.md b/skills/cold-start/SKILL.md new file mode 100644 index 000000000..bc87f6b78 --- /dev/null +++ b/skills/cold-start/SKILL.md @@ -0,0 +1,506 @@ +--- +name: cold-start +version: 1.0.0 +description: | + Day-one data bootstrapping for a new brain. Sequences the highest-leverage + data sources to go from empty brain to useful brain in one session. Uses + ClawVisor for safe credential handling — the agent never holds raw API keys. + Covers Gmail import, calendar sync, contacts seeding, X/Twitter archive, + conversation imports, and file archives. + Use when a user has just finished gbrain setup and asks "now what?" +triggers: + - "cold start" + - "fill my brain" + - "bootstrap brain" + - "import my data" + - "day one" + - "get started" + - "what should I import first" + - "populate brain" + - "now what?" +tools: + - search + - query + - get_page + - put_page + - add_link + - add_timeline_entry + - sync_brain +mutating: true +writes_pages: true +writes_to: + - people/ + - companies/ + - meetings/ + - daily/ + - media/ + - conversations/ + - sources/ +--- + +# Cold Start — Day-One Brain Bootstrapping + +You have a working brain. Search works. Now what? + +An empty brain is a static database. A brain with your email history, calendar, +contacts, conversations, and social media is a **live context membrane** that makes +every future interaction smarter. This skill sequences the highest-leverage data +sources to get you from zero to useful in one session. + +## Contract + +- Every import phase is gated on user consent (ask-user pattern) before proceeding. +- **Google/social API access goes through ClawVisor.** The agent never holds raw OAuth + tokens or API keys. This is a safety requirement, not a preference. ClawVisor vaults + credentials, enforces task-scoped authorization, logs every API call, and requires + human approval for destructive operations. If the user doesn't want ClawVisor, the + only safe alternative is offline file exports (Google Takeout, Twitter archive download). +- Each phase is independently valuable — the user can stop after any phase and still + have a useful brain. +- Progress is tracked in `~/.gbrain/cold-start-state.json` so interrupted sessions + can resume. +- Entity detection and cross-linking run on every import, not as a separate pass. + +## Prerequisites + +- GBrain installed and initialized (`gbrain doctor --json` all green) +- Brain repo cloned and synced +- Agent has terminal access and can run `gbrain` CLI commands + +## The Priority Stack + +Data sources ranked by **information density × ease of import**: + +| Priority | Source | Why | Time | Pages Created | +|----------|--------|-----|------|---------------| +| 1 | Existing markdown/Obsidian | Highest density — it's already structured | 5 min | 100s-1000s | +| 2 | Google Contacts | Seeds the people/ directory — names, emails, companies | 10 min | 50-500 | +| 3 | Google Calendar (90 days) | Meeting history with attendee context | 15 min | 30-90 | +| 4 | Gmail (recent threads) | Relationship context, active threads, org chart signals | 20 min | 50-200 | +| 5 | Conversations (ChatGPT/Claude exports) | Your thinking, questions, mental models | 15 min | 10-100 | +| 6 | X/Twitter archive | Your public positions, takes, engagement patterns | 20 min | 30-365 | +| 7 | File archives (Dropbox/Drive/local) | Historical documents, old writing, photos | 30+ min | varies | +| 8 | Meeting transcripts (Circleback/etc.) | Deep relationship context from recorded calls | 20 min | 10-50 | + +## Phase 0: ClawVisor Setup (Required for API Access) + +> **Safety boundary:** An AI agent with raw OAuth tokens to your Gmail, Calendar, +> and Contacts is an uncontrolled attack surface. One prompt injection, one +> malicious tool call, and your entire Google account is exposed. ClawVisor +> eliminates this risk class entirely. + +[ClawVisor](https://clawvisor.com) is a credential gateway that sits between the +agent and your APIs. The agent never sees your credentials — ClawVisor injects +them at request time, enforces policies, and logs everything. + +**What ClawVisor gives you:** +- **Credential vaulting** — agent sees shadow tokens, never real secrets +- **Task-scoped authorization** — each workflow declares exactly what it needs +- **Audit trail** — every API call logged with metadata (who, what, when) +- **Human approval gates** — destructive operations (send email, modify calendar) + require your explicit approval +- **Multi-service** — Gmail, Calendar, Contacts, Drive, GitHub, iMessage from one gateway +- **Revocation** — disable the agent's access in one click, no token rotation needed + +**Setup (15 min):** +1. Sign up at [app.clawvisor.com](https://app.clawvisor.com) +2. Create an agent in the dashboard, copy the agent token +3. Set environment variables: + ```bash + gbrain config set clawvisor_url "https://app.clawvisor.com" + gbrain config set clawvisor_agent_token "" + ``` +4. Activate Google services (Gmail, Calendar, Contacts) in the dashboard +5. Create a standing task with expansive scope: + > "Full brain bootstrapping: read emails, calendar events, and contacts to + > populate knowledge base. List, read, and search across all connected accounts." +6. Save the standing task ID: + ```bash + gbrain config set clawvisor_task_id "" + ``` + +**Critical scoping rule:** Be expansive in task purposes. "Email triage" gets +rejected by intent verification. "Full executive assistant email management +including inbox triage, searching by any criteria, reading emails, tracking +threads" works. The intent model uses the purpose to judge each request. + +### If the user declines ClawVisor + +Do NOT fall back to direct OAuth. Instead, skip Phases 2-4 (Contacts, Calendar, +Gmail) and proceed with offline-only imports: + +- **Phase 1** (markdown/Obsidian) — works without any API access +- **Phase 5** (conversation exports) — works from downloaded JSON files +- **Phase 6** (X/Twitter) — works from downloaded archive +- **Phase 7** (file archives) — works from local files +- **Phase 8** (meeting transcripts) — works from exported transcripts + +Tell the user: +> "No problem. We'll skip the Google imports for now and work with file-based +> sources. You can set up ClawVisor anytime to unlock Contacts, Calendar, and +> Gmail imports safely." + +**Do NOT offer direct OAuth as an alternative.** An agent holding raw Google +tokens is a security liability. The skill should not teach agents to store +credentials they shouldn't have. + +## Phase 1: Existing Markdown / Obsidian Import + +**The highest-leverage first import.** If the user already has a notes system, this +is hundreds or thousands of structured pages ready to go. + +### Discovery + +```bash +echo "=== Markdown Repository Discovery ===" +for dir in /data/* ~/git/* ~/Documents/* ~/notes/* ~/obsidian/* 2>/dev/null; do + if [ -d "$dir" ]; then + md_count=$(find "$dir" -name "*.md" -not -path "*/node_modules/*" \ + -not -path "*/.git/*" -not -path "*/.obsidian/*" 2>/dev/null | wc -l | tr -d ' ') + if [ "$md_count" -gt 5 ]; then + total_size=$(du -sh "$dir" 2>/dev/null | cut -f1) + echo " $dir ($total_size, $md_count .md files)" + fi + fi +done +``` + +### Import + +```bash +# For Obsidian vaults, use the migrate skill for proper wikilink handling +gbrain migrate --from obsidian --path /path/to/vault + +# For plain markdown directories +gbrain import /path/to/dir --no-embed --workers 4 + +# Verify +gbrain stats +gbrain search "" +``` + +### Post-import + +- Run link extraction: `gbrain extract links --source db` +- Run timeline extraction: `gbrain extract timeline --source db` +- Start embeddings: `gbrain embed --stale` (runs in background) + +> **Track progress:** +> ```bash +> echo '{"phase_1_complete": true, "pages_imported": N}' > ~/.gbrain/cold-start-state.json +> ``` + +## Phase 2: Google Contacts → People Pages + +**Seeds the people/ directory.** Every person in your contacts becomes a brain page +with name, email, phone, company, and notes. This is the foundation that all other +imports build on — when Gmail references "john@acme.com", the brain already knows +who John is. + +### Via ClawVisor + +```javascript +// Fetch all contacts +const contacts = await clawvisor('google.contacts', 'list_contacts', { + limit: 1000, + fields: 'names,emailAddresses,phoneNumbers,organizations,biographies' +}); +``` + +### Via direct Google People API + +```bash +curl -s -H "Authorization: Bearer $GOOGLE_TOKEN" \ + "https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses,phoneNumbers,organizations,biographies&pageSize=1000" +``` + +### Processing rules + +For each contact: +1. **Filter out noise** — skip contacts with no name, no email, or that are clearly + automated (noreply@, no-reply@, support@, notifications@) +2. **Check brain first** — `gbrain search "name"` to avoid duplicates +3. **Create people/ page** with: + - Name, email(s), phone(s), company, title + - Source attribution: `[Source: Google Contacts, YYYY-MM-DD]` + - Any notes from the contact as initial context +4. **Link to company** — if the contact has an organization, create/update the + company page and link the person to it + +### Quality gate + +After importing 5 contacts, pause and show the user a sample page. Ask: +> "Here's what a contact page looks like. Want me to continue with the rest, or +> adjust the format first?" + +## Phase 3: Google Calendar (Last 90 Days) + +**Meeting history with attendee context.** Calendar events reveal who the user meets +with, how often, and in what context. Combined with contacts, this builds a rich +relationship map. + +### Fetch events + +```javascript +// Via ClawVisor — query ALL calendar accounts +const accounts = ['primary@gmail.com', 'work@company.com']; +for (const account of accounts) { + const events = await clawvisor(`google.calendar:${account}`, 'list_events', { + timeMin: new Date(Date.now() - 90 * 86400000).toISOString(), + timeMax: new Date().toISOString(), + singleEvents: true, + orderBy: 'startTime' + }); +} +``` + +### Brain structure + +Follow the three-tier calendar architecture: +``` +brain/daily/calendar/ +├── calendar-log.md ← compiled truth (patterns, key people) +├── YYYY/ +│ ├── YYYY-MM.md ← monthly summary +│ └── YYYY-MM-DD.md ← daily event log +``` + +### Entity enrichment + +For each event with attendees: +1. Look up each attendee in the brain (they should exist from Phase 2) +2. Add a timeline entry to their page: met at [event title] on [date] +3. If an attendee has no brain page and appears in 3+ events, create one +4. Link attendees who appear in the same meeting + +## Phase 4: Gmail (Recent Threads) + +**Relationship context and active threads.** Email reveals organizational +relationships, ongoing conversations, and communication patterns. + +### Strategy: Smart sampling, not bulk import + +Don't import every email. Import the **signal**: + +1. **Sent mail (last 30 days)** — who the user actively communicates with +2. **Starred/important emails** — user-curated signal +3. **Threads with 3+ replies** — active conversations worth tracking +4. **Emails from people already in the brain** — enrichment, not cold import + +### Processing + +For each email thread: +1. **Entity detection** — extract people, companies mentioned +2. **Update people pages** — add communication context to timeline +3. **Create meeting pages** — if the email is a meeting summary or follow-up +4. **Skip noise** — newsletters, automated notifications, marketing + +### Filtering rules + +**Auto-skip (never import):** +- noreply@, no-reply@, notifications@, support@, mailer-daemon@ +- Unsubscribe-heavy senders (marketing) +- GitHub/Jira/Linear notification emails +- Calendar invites (already captured in Phase 3) + +**Always import:** +- Direct emails from people in the brain +- Starred/flagged emails +- Emails the user sent (their words are highest-value signal) + +## Phase 5: Conversation Exports (ChatGPT / Claude / Perplexity) + +**Your thinking, captured.** AI conversation exports reveal what the user +was researching, building, and thinking about. This is original thinking +preserved in dialog form. + +### Supported formats + +- **ChatGPT:** Settings → Data Controls → Export → `conversations.json` +- **Claude:** Download from claude.ai conversation history +- **Perplexity:** Export from settings + +### Processing + +For each conversation: +1. **Assess significance** (1-5 scale): + - 1 = Pure utility (how-tos, quick lookups) → skip or minimal page + - 2 = Minor context → 1-paragraph note + - 3 = Notable (reveals interests, building something) → full page + - 4 = Important (deep personal processing, strategic thinking) → rich page + - 5 = Defining (identity work, breakthrough insights) → full treatment +2. **Extract entities** — people, companies, concepts discussed +3. **Capture original thinking** — the user's exact phrasing is the signal. + Never paraphrase. +4. **File by primary subject** — not in a "conversations/" dump. A conversation + about a person goes to people/, about a concept goes to concepts/, etc. + +### Quality rule + +Only import conversations rated 3+. The brain is for signal, not noise. + +## Phase 6: X/Twitter Archive + +**Your public positions and engagement patterns.** Twitter reveals what the user +thinks, who they engage with, and what ideas they're developing publicly. + +### Data sources + +1. **Twitter data export** (Settings → Your Account → Download Archive) + - Contains all tweets, likes, DMs, bookmarks +2. **Live API** (if available) — recent tweets and engagement +3. **Bookmarks** — curated signal, high value + +### Brain structure + +``` +brain/media/x/{handle}/ +├── x-log.md ← compiled truth (themes, voice, key threads) +├── daily/YYYY-MM-DD.md ← daily tweet log +├── monthly/YYYY-MM.md ← monthly rollup +└── bookmarks/ ← saved/bookmarked content +``` + +### Processing + +- **Original tweets** → capture with full context, extract entities +- **Quote tweets** → capture the user's commentary + the source tweet +- **Threads** → reconstruct as a single narrative +- **Bookmarks** → high-signal curation, import with tags +- **Likes** — low signal, skip unless the user wants them + +## Phase 7: File Archives + +**Historical documents, old writing, photos with metadata.** This is the long tail — +less structured but potentially very high value (old journals, letters, early writing). + +Delegate to the `archive-crawler` skill. It handles: +- Crawling directory structures +- Filtering for high-value content (user's own writing, not installers) +- Text extraction from PDFs, images (OCR), documents +- Entity extraction and brain page creation + +> **Safety gate:** Archive crawling can be slow and create many pages. Always start +> with a scan-only pass: +> ```bash +> gbrain archive-crawler --scan-only --path /path/to/archive +> ``` +> Show the user the manifest before proceeding with full ingestion. + +**Supported sources:** +- Local directories (Dropbox sync folder, Google Drive, old hard drives) +- Cloud storage (Backblaze B2, S3) via mounted paths +- Email archives (PST, mbox, EML, Google Takeout) +- Data exports (LinkedIn, Facebook, etc.) + +## Phase 8: Meeting Transcripts + +**Deep relationship context from recorded calls.** If the user has a meeting +recording service (Circleback, Otter, Fireflies, Read.ai), import recent +transcripts. + +Delegate to `meeting-ingestion` skill. Key rules: +- Always pull the **complete transcript**, not just the AI summary +- Entity propagation is MANDATORY — every attendee gets a timeline update +- A meeting is NOT fully ingested until all entity pages are updated + +## Post-Bootstrap Checklist + +After completing available phases: + +1. **Verify brain health:** + ```bash + gbrain doctor --json + gbrain stats + ``` + +2. **Test retrieval:** + ```bash + gbrain query "who do I meet with most often?" + gbrain query "what am I working on?" + gbrain search "" + ``` + +3. **Set up live sync** (if not already): + - Calendar: daily cron + - Email: periodic sweep (4-8 hours) + - X: daily ingest + - Brain repo: `gbrain sync --repo ` every 5-30 minutes + +4. **Track state:** + ```json + // ~/.gbrain/cold-start-state.json + { + "started": "2026-01-15T10:00:00Z", + "credential_gateway": "clawvisor", + "phases_completed": [1, 2, 3, 4], + "phases_skipped": [6, 7], + "total_pages_created": 847, + "total_entities_linked": 1203, + "next_phase": 5 + } + ``` + +5. **Tell the user what to do next:** + > "Your brain has N pages across people, calendar, email, and conversations. + > Live sync is configured for [sources]. From here: + > - The **signal-detector** captures entities from every conversation + > - The **briefing** skill can compile daily context + > - The **executive-assistant** pattern handles email triage + > - Say 'enrich [person]' to deep-dive any contact" + +## Anti-Patterns + +- **Giving the agent raw OAuth tokens.** This is the #1 anti-pattern. An agent with + raw Gmail/Calendar tokens is an uncontrolled attack surface — one prompt injection + and your entire Google account is exposed. Use ClawVisor. If the user declines + ClawVisor, skip to offline imports. Never offer direct OAuth as a fallback. +- **Bulk importing everything without filtering.** The brain is for signal, not noise. + Filter out automated senders, marketing emails, utility conversations. +- **Importing without entity cross-linking.** Every import should detect entities and + update existing brain pages. Isolated imports don't compound. +- **Not gating on user consent.** Every phase should be presented as a choice. The user + may not want their DMs or therapy conversations imported. +- **Importing everything at significance 1.** Not every conversation is worth a brain + page. Use the significance scale and skip utility content. +- **Creating people pages for automated senders.** Sentry, GitHub notifications, + newsletter platforms are not people. Filter by the rules in Phase 4. + +## Resume Protocol + +If the session is interrupted: + +1. Read `~/.gbrain/cold-start-state.json` +2. Skip completed phases +3. Resume from `next_phase` +4. The user doesn't have to repeat credential setup or re-import completed sources + +## Output Format + +After each phase: + +``` +PHASE N COMPLETE: [source name] +================================ + +Pages created: N +Pages updated: N +Entities linked: N +Time elapsed: N min + +Sample pages: +- people/jane-smith.md (created — 3 emails, 5 meetings) +- companies/acme-corp.md (updated — 2 new employees linked) + +Next: Phase N+1 — [description]. Ready to proceed? +``` + +## Tools Used + +- `search` — check for existing pages before creating +- `query` — hybrid search for entity deduplication +- `get_page` — read existing pages for merge decisions +- `put_page` — create and update brain pages +- `add_link` — cross-reference entities +- `add_timeline_entry` — record events on entity timelines +- `sync_brain` — sync changes to the index after each phase diff --git a/skills/manifest.json b/skills/manifest.json index 639d4884c..eff4e74da 100644 --- a/skills/manifest.json +++ b/skills/manifest.json @@ -198,6 +198,16 @@ "name": "voice-note-ingest", "path": "voice-note-ingest/SKILL.md", "description": "Ingest voice notes with exact-phrasing preservation (never paraphrased); routes content based on a decision tree across originals/concepts/people/companies/ideas/personal/voice-notes." + }, + { + "name": "cold-start", + "path": "cold-start/SKILL.md", + "description": "Day-one brain bootstrapping: sequence the highest-leverage data sources (contacts, calendar, email, conversations, social, archives) to go from empty brain to useful brain. Uses ClawVisor for safe credential handling — agents never hold raw API keys." + }, + { + "name": "ask-user", + "path": "ask-user/SKILL.md", + "description": "Reusable choice-gate pattern for presenting users with 2-4 options and stopping execution until they respond. Platform-agnostic (Telegram buttons, Discord, CLI, OpenClaw clarify tool)." } ], "dependencies": { diff --git a/skills/setup/SKILL.md b/skills/setup/SKILL.md index 2c92c79b7..2ecc2650b 100644 --- a/skills/setup/SKILL.md +++ b/skills/setup/SKILL.md @@ -456,6 +456,38 @@ each check: [list results]. Everything is working / [specific item] needs attent If already configured or user declines, skip. +## Phase J: Cold Start — Populate Your Brain (AUTOMATIC) + +Setup is done. The brain works. But it's empty. **This is the most important +moment** — an empty brain is useless. Transition directly to the cold-start +skill to fill it with the user's actual data. + +**Do not end setup without offering cold-start.** The user just invested 15+ +minutes in setup. The payoff is seeing their brain come alive with their own +data. Stopping here is like installing a phone and never adding contacts. + +Present this immediately after verification passes: + +> "✅ GBrain is set up and verified. Now let's fill it with your data. +> +> I can connect your Google services (contacts, calendar, email), import +> your existing notes, pull in conversations from ChatGPT/Claude, and +> archive your tweets — all in one session. Each step is optional. +> +> **Ready to populate your brain?**" + +If the user says yes (or anything affirmative): +→ **Load and execute `skills/cold-start/SKILL.md`** immediately. Do not +just print a reference — actually run the cold-start skill. + +If the user says no or wants to stop: +→ Record in `~/.gbrain/cold-start-state.json`: +```json +{"deferred": true, "deferred_at": "ISO-timestamp", "phases_completed": []} +``` +→ Tell them: "You can run cold-start anytime by asking me to 'fill my brain' +or 'cold start'." + ## Schema State Tracking After presenting the recommended directories (Phase C/E) and the user selects which @@ -471,6 +503,7 @@ re-suggesting things the user already declined. ## Anti-Patterns +- **Ending setup without offering cold-start.** An empty brain is useless. Phase J (cold-start) is where setup pays off. Always present the "Ready to populate?" prompt after verification. Skipping this is like installing an app and never logging in. - **Asking for the Supabase anon key.** GBrain connects directly to Postgres over the wire protocol, not through the REST API. Only the database connection string is needed. - **Skipping live sync setup.** If sync doesn't run automatically, the vector DB falls behind and search returns stale answers. Phase H is not optional. - **Declaring setup complete without verification.** "The command ran" is not the same as "it worked." Push a test change, wait for sync, search for the corrected text. @@ -491,11 +524,14 @@ Live sync: [configured / method] Health check: all OK / [specific failures] Verification: [GBRAIN_VERIFY.md results] -Next steps: -- Read docs/GBRAIN_SKILLPACK.md for production agent patterns -- [any pending items] +🧠 Ready to populate your brain? I can connect your Google services, +import your notes, and pull in your conversations — all in one session. +→ Launching cold-start... ``` +**The output should transition directly into cold-start (Phase J), not end +with a bullet list.** The bullet list is for when the user defers cold-start. + ## Tools Used - `gbrain init --non-interactive --url ...` -- create brain