[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6N0SJ2JMQMJA8NS5X06AAD9":3,"skill-same:01M6N0SJ2JMQMJA8NS5X06AAD9":88},{"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":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":66,"ownerDescription":67,"updatedAt":68,"install":69,"resources":81},"01M6N0SJ2JMQMJA8NS5X06AAD9","resolve-before-asking",null,"Gate on identity questions to the user. Before any \"who is X?\" (or role \u002F\nrelationship question) reaches the user, exhaust the brain's lookup chain:\nthink → search + page read → mounted sources → timeline\u002Fgraph → web. If\nescalation survives the chain, ask WITH a hypothesis, never a bare unknown.\nAlso owns the no-placeholders-at-ingest rule: pages created during bulk\ningestion get their relationship\u002Frole resolved immediately.","garrytan\u002Fgbrain","garrytan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F19957?v=4","01M6DJCCDDG53MTYYRTXAXFG17","Garry Tan","01M6MZQZCEN3RRMD33E1X9ZZR9",32847,"MIT","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fresolve-before-asking\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"resolve before asking","brain","bare","bulk ingestion","content analysis","unknown","at","bulk","people","sources","chain","placeholder","get","relationship","ingestion","never","read","question","ask","analysis","search","2026-11-10 10:12:30",false,"---\nname: resolve-before-asking\nversion: 1.0.0\ndescription: |\n  Gate on identity questions to the user. Before any \"who is X?\" (or role \u002F\n  relationship question) reaches the user, exhaust the brain's lookup chain:\n  think → search + page read → mounted sources → timeline\u002Fgraph → web. If\n  escalation survives the chain, ask WITH a hypothesis, never a bare unknown.\n  Also owns the no-placeholders-at-ingest rule: pages created during bulk\n  ingestion get their relationship\u002Frole resolved immediately.\ntriggers:\n  - \"resolve before asking\"\n  - \"before asking the user\"\n  - \"unidentified contact\"\n  - \"unknown relationship\"\n  - \"should I ask who\"\n  - \"don't know who this is\"\n  - \"to be filled by content analysis\"\n  - \"placeholder on this page\"\nmutating: true\nwrites_pages: true\nwrites_to:\n  - people\u002F\n  - companies\u002F\nupstream: resolve-before-asking@fc834ee\n---\n\n# Resolve Before Asking — Exhaust the Brain Before Bothering the User\n\n> **Convention:** see [conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)\n> for the base lookup chain (search → query → get_page → external APIs). This\n> skill extends that chain one hop further, to the human boundary: asking the\n> user is the LAST resort, after the brain AND external escalation, not a\n> shortcut around them.\n\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) —\n> pages touched by the ingest-resolution section file by primary subject\n> (`people\u002F`, `companies\u002F`).\n\n## Purpose\n\n**Never ask the user \"who is X?\" when the answer already exists in the brain.**\n\nThe memory answers before the human is bothered — that is the product promise.\nThis skill defines the lookup chain that runs before any entity-identification\nquestion is sent to the user, and the escalation format when asking really is\njustified.\n\n## The Bug This Kills\n\nThe pattern: the agent encounters an entity with a rich brain page — timeline\nentries, meeting history, an imported message archive — and instead of reading\nthem, asks the user \"who is X?\". This is lazy escalation. It spends the user's\nattention on questions the system can answer itself.\n\nExamples of the bug (anonymized):\n\n- **alice-example** — her brain page already carried a role line (\"Chief of\n  Staff at acme-example\") and a long meeting history → the agent still asked.\n- **charlie-example** — a thick imported email thread whose subject lines all\n  pointed at one shared project → the agent still asked.\n\n## When This Fires\n\nThis is a harness-routing convention, not a mechanical guarantee: route here\nwhenever ANY of these are true —\n\n1. A reply draft contains \"who is [name]?\" or equivalent.\n2. A draft asks about someone's role, relationship, or identity.\n3. You are about to present an entity as \"unknown\" or \"unidentified\".\n4. A brain page has `[To be filled by content analysis]` or similar\n   placeholder text.\n5. You are composing a list of people and leaving any as \"unknown\n   relationship\".\n\n## The Lookup Chain (run in order; STOP at the first clear answer)\n\n### Step 1: `think` — cross-brain synthesis (solves most cases)\n\n```bash\ngbrain think \"Who is {entity}? What is their relationship to the user? What role do they play? Use all available context — meetings, timeline, imported archives, facts.\"\n```\n\n`think` synthesizes across ALL brain data. If the entity has a page with\nimported-activity stats, timeline entries, and meeting history, `think` will\nconnect the dots. Over MCP, `entity(\"{entity}\")` first gives a zero-LLM card\n(aliases, last-touched, top edges); `synthesize` is the heavy cross-page\nanswer when the card isn't enough.\n\n**If this returns a clear answer → STOP. Use the answer. Do not ask the user.**\n\n### Step 2: `search` + full page read\n\n```bash\ngbrain search \"{entity}\" --limit 5\ngbrain get {entity-slug}\n```\n\nWhat to look for:\n\n- `relationship` field in frontmatter — filled means resolved.\n- Role signals repeated in timeline entries (\"advisor\", \"colleague at\n  acme-example\", \"chief of staff\").\n- Facts table — any role\u002Frelationship facts.\n- Meeting history — what did they attend? With whom?\n\n**If timeline entries repeat a consistent role → STOP. The role is obvious.\nDo not ask the user.**\n\n### Step 3: Query each mounted source the brain actually has\n\nDon't hardcode channels. Check what the brain holds, then query it:\n\n```bash\ngbrain sources list\ngbrain query \"emails with {entity}\" --limit 10\ngbrain query \"meetings with {entity}\" --limit 5\n```\n\nWhatever is mounted — an email archive, calendar imports, chat transcripts,\nmeeting notes — a handful of subject lines or meeting titles usually reveals\nthe relationship:\n\n- Invoice \u002F scheduling \u002F billing subjects → professional services.\n- Recurring 1:1 titles with consistent co-attendees → colleague.\n- Dinner \u002F weekend-plan messages → personal friend.\n\n### Step 4: Timeline + graph walk\n\n```bash\ngbrain timeline {entity-slug} --limit 20\ngbrain backlinks {entity-slug}\ngbrain graph {entity-slug} --depth 2\n```\n\nDated events, who references this entity, and what it connects to. A person\nwho back-links from a company page and three meeting pages is not an unknown.\n\n### Step 5: Web search (external escalation, per brain-first)\n\nOnly after steps 1–4 return nothing useful. Run a generic web search on\n`\"{entity name} {company\u002Fdomain hints accumulated in steps 1-4}\"`. Fold\nanything found back into the brain page before using it (the brain-ops\nread-enrich-write cycle), so the next lookup doesn't repeat the work.\n\n### Step 6: Escalate to the user (LAST RESORT) — ask WITH a hypothesis\n\nOnly after ALL previous steps return nothing conclusive:\n\n- State what you searched.\n- State what you found — even partial signals.\n- Ask a SPECIFIC, confirmable question: not \"who is X?\" but \"Is {entity} the\n  {best guess assembled from partial signals}?\"\n\nUse [ask-user](..\u002Fask-user\u002FSKILL.md) for the choice-gate mechanics (2–4\noptions, escape hatch, stop the turn).\n\n## Confidence Thresholds\n\n- **High confidence (don't ask):** `think`\u002F`synthesize` gives a clear answer,\n  OR 3+ timeline entries carry a consistent role description, OR the page's\n  relationship field is filled.\n- **Low confidence (ask, leading with your best guess):** contradictory\n  signals or very sparse data. Ask — but the question opens with your\n  hypothesis, and states the contradiction if there is one.\n\nThere is no third state. Either the brain answered (use it) or it didn't\n(finish the chain, then ask with a hypothesis).\n\n## No Placeholders at Ingest\n\nWhen ANY ingestion pipeline (email import, calendar enrichment, chat\ntranscripts, meeting ingestion) creates or significantly updates a person or\ncompany page, resolve the entity's identity and relationship immediately —\nnever leave placeholder text. Pages like\n\n- `[To be filled by content analysis]`\n- `> Contact from the user's personal network.`\n- an empty `## Context` section\n\nare bugs, especially when the ingestion batch itself contains hundreds of\nsignals about who the person is. Run this as a post-ingestion pass over every\npage the batch created or updated:\n\n1. **Check for placeholders.** Scan the touched pages for markers\n   (`[To be filled`, `Unknown relationship`, `TBD`). No placeholders AND\n   relationship filled → skip, already resolved.\n2. **Run the chain** (steps 1–4 above; at ingest time, step 1 alone usually\n   suffices because the batch just wrote the signals `think` needs).\n3. **Extract:** relationship type (friend \u002F colleague \u002F advisor \u002F family \u002F\n   founder), professional role (title + company), key context (how they know\n   the user, what era).\n4. **Update the page** (`put_page`): fill the `relationship` frontmatter\n   field, replace the placeholder description with a real one-liner, update\n   the `## Context` or intro paragraph.\n5. **Batch efficiency** for bulk runs (100+ pages): resolve in batches of\n   10–20; prioritize by captured-activity volume (more activity = more likely\n   the user meets this name in a briefing); skip pages already substantive.\n\n### Email-domain shortcut (hypothesis generator, not proof)\n\nBefore running the chain, the sender's domain often seeds the hypothesis:\n\n| Domain shape | Hypothesis |\n|---|---|\n| `@acme-example.com` — a company already in the brain | Likely acme-example employee. Confirm against the company page + shared meetings, then fill. |\n| Corporate domain NOT in the brain | New company. Run the chain; consider seeding a `companies\u002F` page. |\n| Personal domain (gmail, etc.) | No shortcut — run the full chain. |\n\n### Quality bar\n\nA resolved page passes this test: if the user encounters the name in a\nbriefing, triage, or meeting prep, the page's first line says who they are\nWITHOUT the user needing to ask.\n\n- Bad: `> Contact from the user's personal network.`\n- Good: `> Operations lead at acme-example — handles invoicing and vendor\n  onboarding for the user.`\n\n## Contract\n\nThis skill guarantees:\n\n- No identity\u002Frole\u002Frelationship question reaches the user until the lookup\n  chain (steps 1–5) has run for that entity.\n- Every escalation states what was searched, what was found, and leads with a\n  hypothesis — never a bare \"who is X?\".\n- No placeholder text survives an ingestion batch on pages this skill touches;\n  relationship\u002Frole fields are filled at write time.\n- Writes land only under the `writes_to:` directories, filed by primary\n  subject per `_brain-filing-rules.md`.\n- Privacy contract preserved: no real names, no fork-specific filesystem path\n  literals, no upstream-fork references in examples.\n\n## Output Format\n\nTwo possible outputs:\n\n**(a) Resolved silently** — the identity is used in the current flow; if a\npage had a placeholder, it is filled (`put_page`) as a side effect. No message\nto the user about the lookup.\n\n**(b) Escalation with a hypothesis** — formatted per the ask-user choice gate:\n\n```\n? **Is {entity} the {best guess}?**\n\nSearched: think, search + page read, mounted sources, timeline\u002Fgraph, web.\nFound: recurring invoices from @widget-co.com; two meetings alongside the\nacme-example team. Nothing names their role directly.\n\n1. **Confirm** — {entity} is {best guess}\n2. **Correct me** — it's someone else (tell me who)\n3. **Skip** — leave unresolved for now\n```\n\nAfter emitting the gate, stop the turn (see ask-user).\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- Every lookup comes back empty with a degraded notice: keyword-only search can miss the entity. Say so in the confirmable question instead of asking \"who is X?\" cold.\n- `get_page` returns `page_not_found` for a guessed slug: try title and alias search before concluding the entity is unknown.\n- Filling a page returns `revision_conflict`: re-read and merge.\n\n## Anti-Patterns\n\n- ❌ \"Who is X?\" with no prior lookup.\n- ❌ \"What's their relationship to you?\" when the brain page has dozens of\n  timeline entries.\n- ❌ Presenting a list of unknowns without running the chain on each one.\n- ❌ Leaving `[To be filled by content analysis]` on a page whose ingestion\n  batch carried hundreds of signals.\n- ❌ Asking about someone whose email address names their employer\n  (`jane@acme-example.com`).\n- ❌ Using `memory_search` for entity lookups — memory tools search session\n  notes, not the brain knowledge graph; brain-first.md bans this. Use\n  `search` \u002F `query` \u002F `entity`.\n- ❌ Treating a nonzero `search` hit count as chain-complete — read the page;\n  run `query` for synonym phrasings before concluding \"not in the brain\".\n- ❌ Escalating with false confidence: partial signal is a hypothesis, not a\n  resolution. If signals contradict, the escalation states the contradiction.\n\n## Dedup (sharp boundaries)\n\n- **[query](..\u002Fquery\u002FSKILL.md)** — owns the lookup verb mechanics (3-layer\n  search, synthesis, citations) for answering the user's questions. This\n  skill consumes those same tools but owns a decision, not a lookup: WHETHER\n  an identity question is allowed to reach the user at all.\n- **[brain-ops](..\u002Fbrain-ops\u002FSKILL.md)** — owns the general read-enrich-write\n  cycle for every brain interaction. This skill is the gate on one specific\n  exit ramp of that cycle: the identity question to the human.\n- **[ask-user](..\u002Fask-user\u002FSKILL.md)** — owns HOW to ask (choice-gate format,\n  option limits, stopping the turn). This skill owns WHETHER asking is\n  justified and WHAT the question must contain (searched \u002F found \u002F\n  hypothesis).\n- **[enrich](..\u002Fenrich\u002FSKILL.md)** — owns creating and updating entity pages\n  with the tiered enrichment protocol. The \"No Placeholders at Ingest\"\n  section here is the acceptance bar those writes must meet; when a\n  placeholder needs filling, run this skill's chain, then write via the\n  enrich\u002Fbrain-ops conventions.\n- **[conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)** — owns\n  brain-before-external-API ordering for all lookups. This skill inherits\n  that ordering and adds the final boundary: external-before-human.\n- A dedup-before-create entity guard (phonetic\u002Falias matching before a new\n  page is created) is a DIFFERENT failure class — that guard prevents\n  duplicate pages at write time; this skill prevents needless questions at\n  ask time. Cross-reference, don't merge, if\u002Fwhen it ships.\n\n## The Standard\n\nWould the user look at this person's brain page — the imported archive, the\nemployer-revealing email domain, the timeline entries all repeating the same\nrole — and think it was reasonable that the agent asked who this person is?\n\nIf the answer is no, the chain wasn't run. Run it.\n","# Resolve Before Asking — Exhaust the Brain Before Bothering the User\n\n> **Convention:** see [conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)\n> for the base lookup chain (search → query → get_page → external APIs). This\n> skill extends that chain one hop further, to the human boundary: asking the\n> user is the LAST resort, after the brain AND external escalation, not a\n> shortcut around them.\n\n> **Convention:** see [_brain-filing-rules.md](..\u002F_brain-filing-rules.md) —\n> pages touched by the ingest-resolution section file by primary subject\n> (`people\u002F`, `companies\u002F`).\n\n## Purpose\n\n**Never ask the user \"who is X?\" when the answer already exists in the brain.**\n\nThe memory answers before the human is bothered — that is the product promise.\nThis skill defines the lookup chain that runs before any entity-identification\nquestion is sent to the user, and the escalation format when asking really is\njustified.\n\n## The Bug This Kills\n\nThe pattern: the agent encounters an entity with a rich brain page — timeline\nentries, meeting history, an imported message archive — and instead of reading\nthem, asks the user \"who is X?\". This is lazy escalation. It spends the user's\nattention on questions the system can answer itself.\n\nExamples of the bug (anonymized):\n\n- **alice-example** — her brain page already carried a role line (\"Chief of\n  Staff at acme-example\") and a long meeting history → the agent still asked.\n- **charlie-example** — a thick imported email thread whose subject lines all\n  pointed at one shared project → the agent still asked.\n\n## When This Fires\n\nThis is a harness-routing convention, not a mechanical guarantee: route here\nwhenever ANY of these are true —\n\n1. A reply draft contains \"who is [name]?\" or equivalent.\n2. A draft asks about someone's role, relationship, or identity.\n3. You are about to present an entity as \"unknown\" or \"unidentified\".\n4. A brain page has `[To be filled by content analysis]` or similar\n   placeholder text.\n5. You are composing a list of people and leaving any as \"unknown\n   relationship\".\n\n## The Lookup Chain (run in order; STOP at the first clear answer)\n\n### Step 1: `think` — cross-brain synthesis (solves most cases)\n\n```bash\ngbrain think \"Who is {entity}? What is their relationship to the user? What role do they play? Use all available context — meetings, timeline, imported archives, facts.\"\n```\n\n`think` synthesizes across ALL brain data. If the entity has a page with\nimported-activity stats, timeline entries, and meeting history, `think` will\nconnect the dots. Over MCP, `entity(\"{entity}\")` first gives a zero-LLM card\n(aliases, last-touched, top edges); `synthesize` is the heavy cross-page\nanswer when the card isn't enough.\n\n**If this returns a clear answer → STOP. Use the answer. Do not ask the user.**\n\n### Step 2: `search` + full page read\n\n```bash\ngbrain search \"{entity}\" --limit 5\ngbrain get {entity-slug}\n```\n\nWhat to look for:\n\n- `relationship` field in frontmatter — filled means resolved.\n- Role signals repeated in timeline entries (\"advisor\", \"colleague at\n  acme-example\", \"chief of staff\").\n- Facts table — any role\u002Frelationship facts.\n- Meeting history — what did they attend? With whom?\n\n**If timeline entries repeat a consistent role → STOP. The role is obvious.\nDo not ask the user.**\n\n### Step 3: Query each mounted source the brain actually has\n\nDon't hardcode channels. Check what the brain holds, then query it:\n\n```bash\ngbrain sources list\ngbrain query \"emails with {entity}\" --limit 10\ngbrain query \"meetings with {entity}\" --limit 5\n```\n\nWhatever is mounted — an email archive, calendar imports, chat transcripts,\nmeeting notes — a handful of subject lines or meeting titles usually reveals\nthe relationship:\n\n- Invoice \u002F scheduling \u002F billing subjects → professional services.\n- Recurring 1:1 titles with consistent co-attendees → colleague.\n- Dinner \u002F weekend-plan messages → personal friend.\n\n### Step 4: Timeline + graph walk\n\n```bash\ngbrain timeline {entity-slug} --limit 20\ngbrain backlinks {entity-slug}\ngbrain graph {entity-slug} --depth 2\n```\n\nDated events, who references this entity, and what it connects to. A person\nwho back-links from a company page and three meeting pages is not an unknown.\n\n### Step 5: Web search (external escalation, per brain-first)\n\nOnly after steps 1–4 return nothing useful. Run a generic web search on\n`\"{entity name} {company\u002Fdomain hints accumulated in steps 1-4}\"`. Fold\nanything found back into the brain page before using it (the brain-ops\nread-enrich-write cycle), so the next lookup doesn't repeat the work.\n\n### Step 6: Escalate to the user (LAST RESORT) — ask WITH a hypothesis\n\nOnly after ALL previous steps return nothing conclusive:\n\n- State what you searched.\n- State what you found — even partial signals.\n- Ask a SPECIFIC, confirmable question: not \"who is X?\" but \"Is {entity} the\n  {best guess assembled from partial signals}?\"\n\nUse [ask-user](..\u002Fask-user\u002FSKILL.md) for the choice-gate mechanics (2–4\noptions, escape hatch, stop the turn).\n\n## Confidence Thresholds\n\n- **High confidence (don't ask):** `think`\u002F`synthesize` gives a clear answer,\n  OR 3+ timeline entries carry a consistent role description, OR the page's\n  relationship field is filled.\n- **Low confidence (ask, leading with your best guess):** contradictory\n  signals or very sparse data. Ask — but the question opens with your\n  hypothesis, and states the contradiction if there is one.\n\nThere is no third state. Either the brain answered (use it) or it didn't\n(finish the chain, then ask with a hypothesis).\n\n## No Placeholders at Ingest\n\nWhen ANY ingestion pipeline (email import, calendar enrichment, chat\ntranscripts, meeting ingestion) creates or significantly updates a person or\ncompany page, resolve the entity's identity and relationship immediately —\nnever leave placeholder text. Pages like\n\n- `[To be filled by content analysis]`\n- `> Contact from the user's personal network.`\n- an empty `## Context` section\n\nare bugs, especially when the ingestion batch itself contains hundreds of\nsignals about who the person is. Run this as a post-ingestion pass over every\npage the batch created or updated:\n\n1. **Check for placeholders.** Scan the touched pages for markers\n   (`[To be filled`, `Unknown relationship`, `TBD`). No placeholders AND\n   relationship filled → skip, already resolved.\n2. **Run the chain** (steps 1–4 above; at ingest time, step 1 alone usually\n   suffices because the batch just wrote the signals `think` needs).\n3. **Extract:** relationship type (friend \u002F colleague \u002F advisor \u002F family \u002F\n   founder), professional role (title + company), key context (how they know\n   the user, what era).\n4. **Update the page** (`put_page`): fill the `relationship` frontmatter\n   field, replace the placeholder description with a real one-liner, update\n   the `## Context` or intro paragraph.\n5. **Batch efficiency** for bulk runs (100+ pages): resolve in batches of\n   10–20; prioritize by captured-activity volume (more activity = more likely\n   the user meets this name in a briefing); skip pages already substantive.\n\n### Email-domain shortcut (hypothesis generator, not proof)\n\nBefore running the chain, the sender's domain often seeds the hypothesis:\n\n| Domain shape | Hypothesis |\n|---|---|\n| `@acme-example.com` — a company already in the brain | Likely acme-example employee. Confirm against the company page + shared meetings, then fill. |\n| Corporate domain NOT in the brain | New company. Run the chain; consider seeding a `companies\u002F` page. |\n| Personal domain (gmail, etc.) | No shortcut — run the full chain. |\n\n### Quality bar\n\nA resolved page passes this test: if the user encounters the name in a\nbriefing, triage, or meeting prep, the page's first line says who they are\nWITHOUT the user needing to ask.\n\n- Bad: `> Contact from the user's personal network.`\n- Good: `> Operations lead at acme-example — handles invoicing and vendor\n  onboarding for the user.`\n\n## Contract\n\nThis skill guarantees:\n\n- No identity\u002Frole\u002Frelationship question reaches the user until the lookup\n  chain (steps 1–5) has run for that entity.\n- Every escalation states what was searched, what was found, and leads with a\n  hypothesis — never a bare \"who is X?\".\n- No placeholder text survives an ingestion batch on pages this skill touches;\n  relationship\u002Frole fields are filled at write time.\n- Writes land only under the `writes_to:` directories, filed by primary\n  subject per `_brain-filing-rules.md`.\n- Privacy contract preserved: no real names, no fork-specific filesystem path\n  literals, no upstream-fork references in examples.\n\n## Output Format\n\nTwo possible outputs:\n\n**(a) Resolved silently** — the identity is used in the current flow; if a\npage had a placeholder, it is filled (`put_page`) as a side effect. No message\nto the user about the lookup.\n\n**(b) Escalation with a hypothesis** — formatted per the ask-user choice gate:\n\n```\n? **Is {entity} the {best guess}?**\n\nSearched: think, search + page read, mounted sources, timeline\u002Fgraph, web.\nFound: recurring invoices from @widget-co.com; two meetings alongside the\nacme-example team. Nothing names their role directly.\n\n1. **Confirm** — {entity} is {best guess}\n2. **Correct me** — it's someone else (tell me who)\n3. **Skip** — leave unresolved for now\n```\n\nAfter emitting the gate, stop the turn (see ask-user).\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- Every lookup comes back empty with a degraded notice: keyword-only search can miss the entity. Say so in the confirmable question instead of asking \"who is X?\" cold.\n- `get_page` returns `page_not_found` for a guessed slug: try title and alias search before concluding the entity is unknown.\n- Filling a page returns `revision_conflict`: re-read and merge.\n\n## Anti-Patterns\n\n- ❌ \"Who is X?\" with no prior lookup.\n- ❌ \"What's their relationship to you?\" when the brain page has dozens of\n  timeline entries.\n- ❌ Presenting a list of unknowns without running the chain on each one.\n- ❌ Leaving `[To be filled by content analysis]` on a page whose ingestion\n  batch carried hundreds of signals.\n- ❌ Asking about someone whose email address names their employer\n  (`jane@acme-example.com`).\n- ❌ Using `memory_search` for entity lookups — memory tools search session\n  notes, not the brain knowledge graph; brain-first.md bans this. Use\n  `search` \u002F `query` \u002F `entity`.\n- ❌ Treating a nonzero `search` hit count as chain-complete — read the page;\n  run `query` for synonym phrasings before concluding \"not in the brain\".\n- ❌ Escalating with false confidence: partial signal is a hypothesis, not a\n  resolution. If signals contradict, the escalation states the contradiction.\n\n## Dedup (sharp boundaries)\n\n- **[query](..\u002Fquery\u002FSKILL.md)** — owns the lookup verb mechanics (3-layer\n  search, synthesis, citations) for answering the user's questions. This\n  skill consumes those same tools but owns a decision, not a lookup: WHETHER\n  an identity question is allowed to reach the user at all.\n- **[brain-ops](..\u002Fbrain-ops\u002FSKILL.md)** — owns the general read-enrich-write\n  cycle for every brain interaction. This skill is the gate on one specific\n  exit ramp of that cycle: the identity question to the human.\n- **[ask-user](..\u002Fask-user\u002FSKILL.md)** — owns HOW to ask (choice-gate format,\n  option limits, stopping the turn). This skill owns WHETHER asking is\n  justified and WHAT the question must contain (searched \u002F found \u002F\n  hypothesis).\n- **[enrich](..\u002Fenrich\u002FSKILL.md)** — owns creating and updating entity pages\n  with the tiered enrichment protocol. The \"No Placeholders at Ingest\"\n  section here is the acceptance bar those writes must meet; when a\n  placeholder needs filling, run this skill's chain, then write via the\n  enrich\u002Fbrain-ops conventions.\n- **[conventions\u002Fbrain-first.md](..\u002Fconventions\u002Fbrain-first.md)** — owns\n  brain-before-external-API ordering for all lookups. This skill inherits\n  that ordering and adds the final boundary: external-before-human.\n- A dedup-before-create entity guard (phonetic\u002Falias matching before a new\n  page is created) is a DIFFERENT failure class — that guard prevents\n  duplicate pages at write time; this skill prevents needless questions at\n  ask time. Cross-reference, don't merge, if\u002Fwhen it ships.\n\n## The Standard\n\nWould the user look at this person's brain page — the imported archive, the\nemployer-revealing email domain, the timeline entries all repeating the same\nrole — and think it was reasonable that the agent asked who this person is?\n\nIf the answer is no, the chain wasn't run. Run it.\n",{"name":5,"version":45,"mutating":46,"triggers":47,"upstream":55,"writes_to":56,"description":59,"writes_pages":46},"1.0.0",true,[19,48,49,50,51,52,53,54],"before asking the user","unidentified contact","unknown relationship","should I ask who","don't know who this is","to be filled by content analysis","placeholder on this page","resolve-before-asking@fc834ee",[57,58],"people\u002F","companies\u002F","Gate on identity questions to the user. Before any \"who is X?\" (or role \u002F\nrelationship question) reaches the user, exhaust the brain's lookup chain:\nthink → search + page read → mounted sources → timeline\u002Fgraph → web. If\nescalation survives the chain, ask WITH a hypothesis, never a bare unknown.\nAlso owns the no-placeholders-at-ingest rule: pages created during bulk\ningestion get their relationship\u002Frole resolved immediately.\n","master","074ec301549ded4930f04d2c3b22d709a6c095cc","skills\u002Fresolve-before-asking",4902,"https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain","https:\u002F\u002Fgithub.com\u002Fgarrytan","https:\u002F\u002Fblog.garrytan.com","Writes software, dreams. ","2026-11-14 04:11:30",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":46},[71,74,77],{"tool":72,"command":73},"npx","npx skills add garrytan\u002Fgbrain --skill resolve-before-asking",{"tool":75,"command":76},"bunx","bunx skills add garrytan\u002Fgbrain --skill resolve-before-asking",{"tool":78,"command":79},"pnpm","pnpm dlx skills add garrytan\u002Fgbrain --skill resolve-before-asking","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fresolve-before-asking\u002FSKILL.md",[82],{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":87},"routing-eval.jsonl","OTHER","其他",1236,"https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Fskills\u002Fresolve-before-asking\u002Frouting-eval.jsonl",[89,101,107,127,154,168],{"skillNo":90,"name":91,"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":92,"categories":93,"keywords":94,"publishedAt":40},"01M6N109FNGH1PK49T734PZXGB","query-helper","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fquery-helper\u002FSKILL.md",[],[95,96,97,39,98,99,100],"query helper","helper","query","page","find","false",{"skillNo":102,"name":103,"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":104,"categories":105,"keywords":106,"publishedAt":40},"01M6N108A23GW6NGQEQ0E7GV0A","broken","https:\u002F\u002Fgithub.com\u002Fgarrytan\u002Fgbrain\u002Fblob\u002Fmaster\u002Ftest\u002Ffixtures\u002Fskill-catalog\u002Fskills\u002Fbroken\u002FSKILL.md",[],[103],{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":40},"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",[],[114,20,115,116,117,98,35,118,119,120,97,121,27,122,123,124,125,126,39],"brain ops","ops","true","attribution","write","up","look","pages","with","enrich","web","path","source",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":138,"publishedAt":40},"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",[133],{"categoryNo":134,"categoryName":135,"taxonomyType":136,"taxonomyTypeDesc":137},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[139,140,141,142,143,39,144,145,146,97,100,147,148,149,150,151,152,153],"meeting","prep","meeting prep","me","prepare","brief","open","build","loops","about","you","briefing","threads","for","Meet",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":160,"publishedAt":40},"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",[],[161,162,163,39,164,100,165,166,167],"inbox zero","ZeRO","inbox","clear","replies","my","triage",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":40},"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",[],[175,176,177,121,20,178,179,118,180,116,39,181],"deal memo","deal","memo","draft","investment","history","founder"]