← BreakthroughCONTENT HISTORY

Update to Breakthrough

Snapshot Oct 31, 2026 · 01:17 UTC · version 0.24.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Breakthrough and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Keeps an EXISTING Breakthrough contact's employer and title right. When the user states where someone works now (\"Marco works at Kleecks, I just met him\", \"she's advising RudderStack\"), records that employer once the user confirms — the fix for people LinkedIn has wrong. Otherwise re-pulls their details from LinkedIn when the record is stale, and answers whether someone's job is still current (\"is Matt still at Quindar?\", \"did he leave?\"): Breakthrough holds the user's own record of that person. Confirms before changing anything. Writing to them or writing up a call is answer; what they said on a call is research-transcripts; their record as it stands is find-contact.",
  "included_files": [],
  "name": "refresh-contact",
  "skill_md_contents": "---\nname: refresh-contact\ndescription: >-\n  Keeps an EXISTING Breakthrough contact's employer and title right. When the user\n  states where someone works now (\"Marco works at Kleecks, I just met him\", \"she's\n  advising RudderStack\"), records that employer once the user confirms — the fix for\n  people LinkedIn has wrong. Otherwise re-pulls their details from LinkedIn when the\n  record is stale, and answers whether someone's job is still current (\"is Matt still\n  at Quindar?\", \"did he leave?\"): Breakthrough holds the user's own record of that\n  person. Confirms before changing anything.\n  Writing to them or writing up a call is answer; what they said on a call is\n  research-transcripts; their record as it stands is find-contact.\nwhen_to_use: >-\n  Use for statements of where someone works now (\"Mauricio works at Autopistas del\n  Café\", \"he's at Globex now\", \"he joined Kleecks\"); refresh requests (\"refresh Jane\",\n  \"update his title\"); complaints that a record is wrong (\"you have him at his old\n  company\"); departures (\"Sarah left Acme\", \"FYI they moved on\"); and currency\n  questions (\"is this current?\", \"where is Sarah now?\"). Prefer this over find-contact\n  and answer whenever a contact's employer or title is stated, reported\n  changed, or questioned — nothing changes without the user's say-so. Do NOT use for\n  someone not yet in the system; that is import-contact.\n---\n\n# Refresh a contact\n\nWraps the `refresh_contact` MCP tool, which does two different things:\n\n- **Records an employer the user states.** The user is the source of truth; nothing is\n  re-read from LinkedIn, because LinkedIn is usually what was wrong.\n- **Re-pulls the record from LinkedIn** when it has gone stale.\n\n## When this applies\n\nThe backend routes broadly on purpose, because the tool confirms before changing\nanything. All of these belong here:\n\n- **Statements of where someone works now** — \"Mauricio works at Autopistas del Café\",\n  \"he joined Kleecks\", \"she's advising RudderStack\". Advisory, fractional and board roles\n  count. These go to the correction path below, not a refresh.\n- **Explicit commands** — \"refresh Jane's contact info\", \"update this contact's title\"\n- **Stale-data complaints** — \"John's data is wrong\", \"you have her at her old employer\"\n- **Employer or title changes, however phrased** — including passive and note-style\n  mentions with no refresh verb at all: \"Sarah no longer works at Acme\", \"he's at Globex\n  now\", \"FYI Sarah left Acme\"\n- **Currency questions** — \"is his info up to date?\", \"do you have more current data?\"\n\n## Recording an employer the user states\n\nCall `refresh_contact(query=..., employer=\"<company>\")` — the company as the user said\nit, or its website. `employer` is where the person IS:\n\n- \"Venkat **left** Splashtop\" names where he is NOT — there is no employer; this is a\n  plain refresh. If they also say where he went (\"left Splashtop for RudderStack\"), the\n  destination is the `employer`, never the origin.\n- A company inside a **question** — \"is Matt still at Quindar?\" — is something to check,\n  never an employer.\n\nNothing is written until the user confirms. Each status names the one thing still\nmissing — **ask the user, then call again with their answer. Never fill these in\nyourself.**\n\n| Status | Ask the user | Then call again with |\n| --- | --- | --- |\n| `needs_contact_choice` | which of the listed people they mean | `contact_id` of that candidate |\n| `needs_business_choice` | which of the listed companies they mean | `employer_business_id`, or `employer_website` if none is right |\n| `needs_new_company_confirmed` | whether the company the tool found is right — or its website, if it found none | `employer_website=<website>` — `employer` stays the company's name |\n| `needs_change_kind` | was our record simply wrong, or did they change jobs? (decides whether past calls move) | `employer_change_kind=\"correction\"` or `\"job_change\"` |\n| `needs_since` | when they started | `employer_since=\"YYYY-MM-DD\"` |\n| `proposal` | show `message` — it says exactly what will change — and ask whether to apply | `apply_token` from this result, **only after they agree** |\n| `no_change_needed` | nothing — the record is already right; say so | — |\n| `applied` | nothing — report what changed | — |\n| `expired` | the confirmation lapsed; start over | — |\n\nKeep the same `employer` and answers on every follow-up call. `apply_token` is single\nuse and short lived: never store, reuse, or invent one.\n\n## Re-pulling from LinkedIn\n\n`refresh_contact(linkedin_url=None, email=None, query=None, user_requested=False)`. Pass\nthe user's message as `query` when you have no identifier — resolution is the tool's job.\n\n`user_requested` is your call, and the tool never infers it from the wording of `query`:\n\n- **true** — the user asked for the refresh outright (\"refresh Jane\", \"re-pull his\n  details\", \"update her record from LinkedIn\"), or has just confirmed a refresh you\n  offered. The tool starts the refresh.\n- **false** — you are acting on a hint: a change report, a complaint, a currency question\n  (\"Sarah left Acme\", \"is Matt still at Quindar?\"). The tool resolves the contact and\n  returns `needs_confirmation` so you can ask first.\n\nAnnotated **destructive**; Claude Code prompts before it runs. Don't ask the user to\npre-approve it.\n\n## Handling the result — read this before reporting anything\n\nFor a re-pull (no `employer`), five statuses. **Only `started` changed any state.** Every\nother status is a safe no-op that enqueued nothing.\n\n| Status | What happened | What you must do |\n| --- | --- | --- |\n| `started` | Refresh was **enqueued** | Report it's queued. Enrichment is *not* complete — don't present current field values as refreshed. |\n| `needs_confirmation` | One contact resolved, but from an **implicit** signal | **Stop and ask the user before refreshing.** Show which contact you matched. Once they confirm, call again with `user_requested=true`. |\n| `ambiguous` | Several candidates matched | Present the candidates and ask which. Do not pick one. |\n| `no_linkedin_url` | Contact found, but no stored URL to re-enrich from | Report it. Retrying will not help. |\n| `no_match` | Nothing resolved | Report it. Offer the import-contact skill if they have a URL or email. |\n\n### Why `needs_confirmation` exists\n\nBreakthrough deliberately separates an explicit refresh *command* from an implicit\n*signal*. A passing mention — a note, a complaint, a question about currency — resolves\nthe contact but stops short of refreshing, so a stray mention never silently triggers\na re-pull.\n\nA statement of a **new employer** — \"update Marco's employer, he's now at Kleecks\" — is\nnot a re-pull at all: pass it as `employer` (above). A re-pull only re-reads LinkedIn and\ncannot record what the user just told you.\n\nCollapsing these statuses into \"done\" defeats the guardrail. Report the one you got.\n\n## Reporting\n\nName the contact you matched — full name, ID, current role and employer — so the user can\ncatch a wrong match before anything is re-enriched.\n\nFor `started`, say the refresh is queued and data will update, not that it is updated.\n\nFor a stated employer, report only what the tool says happened: a `proposal` is not a\nchange until the user agrees and `applied` comes back.\n"
}

SHA-256 of public snapshot: dd9694efac9beee295dd3c6e2f1fb819391cd5e0f32cb20c9290e2209893a2ee