relokant-sweep · git:20260626.926d22f · 2026-06-26 · sha256 2f1bc1eb1a4314d1
relokant-sweep git:20260626.926d22fA
Immutable. This exact content never changes and is served at /api/v1/blob/2f1bc1eb1a4314d1.
--- name: relokant-sweep description: "Repeatable sourcing sweep for the relokant sweet-zone channel — CIS-rooted, US-headquartered companies whose product+engineering team is still Russian-speaking, selling into US/EU, mid-size, not globalized (gold standard Improvado / Virto Commerce, anti-pattern Miro). HQ must be in the US (team may sit in a CIS hub); non-US-HQ companies are a hard reject. One run: pull a fresh batch of candidates from not-yet-swept sources, classify by sweet-zone + US-viability, dedup against both ledgers on code, append new sweet-zone to ru_friendly_targets.tsv and rejects to ru_friendly_rejects.tsv, and draft outreach for each new US-viable target. Trigger on: /relokant-sweep, or when the user asks to source / sweep / find more relokant / CIS-rooted / ru-friendly companies for a profile." --- # relokant-sweep — CIS-rooted company sourcing sweep Repeatable, **manual-launch** sourcing for the "relokant sweet zone" channel (BL-200 / RFC 061). The engine's scan adapters are deliberately out of scope — this is LLM-driven web research + judgement, not a deterministic fetch. You run it; you keep the human in the loop on the cheap stage (candidate review) before any outreach. **Default profile: `jared`.** All file paths below are under `profiles/<id>/`. Run from the repo root. --- ## What one run produces 1. New sweet-zone companies appended to `profiles/<id>/ru_friendly_targets.tsv`. 2. Rejected companies appended to `profiles/<id>/ru_friendly_rejects.tsv` with a reason (memory of the sweep — next run won't re-research them). 3. The new sweet-zone companies pushed into the per-profile **Notion Companies DB**, two-way deduped (no duplicates of companies already there from the job pipeline / `data/companies.tsv`). 4. An outreach draft for each **new US-viable** target (contact + message). **Drafts only — the user sends them by hand.** 5. A short run report + an updated source-rotation log. --- ## Classification — the sweet zone A company **passes** only if ALL five hold: 1. Founded in CIS / post-Soviet. 2. Product + engineering team still predominantly Russian-speaking (hubs: Yerevan, Tbilisi, Belgrade, Limassol/Cyprus, Warsaw, Lisbon, Almaty, Tashkent). 3. Sells into US/EU (western comp band, remote-friendly). 4. **US corporate HQ** — incorporated / headquartered in the US (Delaware C-corp + US office + US management). The product/eng team may still sit in a CIS diaspora hub; that is fine and expected (Improvado: San Diego HQ, product org was in Almaty). A company whose HQ is NOT in the US is a hard reject, even if everything else fits. **User decision 2026-06-25** — the candidate skips non-US-HQ companies by hand, so the sweep must not surface them. 5. Mid-size, NOT globalized — "globalized" means the **ru-signal is dead**: English-internal, product org no longer Russian-speaking, "we hire anyone". This is about the *team's language*, NOT the HQ address. US-HQ + a Russian-speaking product/eng org is the IDEAL, not a disqualifier. Three rejection modes (record in rejects with the reason): - **`hq_not_us`** — CIS-rooted, ru-team alive, but corporate HQ is outside the US (Yerevan, Limassol/Cyprus, Ireland, etc.). Fibery, Krisp, Playrix sit here under the 2026-06-25 rule. Reject even if the US-viability wedge looks strong — no US HQ, no entry. - **`too_globalized`** — Miro, Wrike, Preply, People.ai, Ecwid/Lightspeed. Already American AND the ru-signal is dead (English-internal product org). US-HQ alone does NOT make a company globalized — it's required. - **`wrong_market`** — Russian-speaking team but sells into CIS/LatAm/SEA, i.e. non-western comp band (inDrive, ID Finance, Skyeng, Refocus, YouTravel, Mate academy). UA-companies are excluded from targeting (user decision 2026-06-22) — record them here too. **US-viability is a SOFT signal, not a hard filter.** The question is not "does this company post a US-remote product role" but "would it make an EXCEPTION the way Virto did": the company has a US client → on-the-ground US management is valuable + the candidate is already in the US (no relocation) + green card (no visa friction). The mechanism is outreach to the founder / Head of Product, not an ATS apply. Flag the level in the `us_viability` column (HIGH / exception / WEAK / unverified) — never drop a company just because it has no public US-remote posting. --- ## Run steps ### 1. Load the ledgers Read both TSVs into a known-names set so you never re-surface a company. This is on code, not on your memory: ``` node scripts/relokant/sweep_dedup.js --profile <id> "Name A" "Name B" ... ``` It prints `FRESH\t<name>` or `DUP\t<name>` per input. You pass candidate names here in step 4 before appending. (`ru_friendly_rejects.tsv` may not exist on the very first run — the helper treats a missing file as empty.) ### 2. Pick the next source batch Rotate through sources so a run covers new ground instead of re-opening relokant trackers every time. **Read the rotation log first:** ``` profiles/<id>/.relokant-state/sources_log.md ``` It records which sources each past run covered and the date. Pick the 2–3 sources that are stalest (or never touched). Source pool: - relocant trackers / "relocation" startup lists; - VC portfolios with CIS roots (Runa Capital, Begin Capital, ex-Yandex / JetBrains / Wrike spinouts); - Crunchbase filter: founder-education CIS + HQ US/EU; - communities (RAIN, RusBase, Telegram tech channels, Yerevan / Tbilisi / Belgrade tech hubs); - LinkedIn founder-search (CIS-educated founders, US/EU HQ); - Habr company blogs of teams going global. Do the actual research with `firecrawl_search` / `web_search_exa`. Keep queries specific (founder name + city + "product", VC + "portfolio", etc.). ### 3. Classify each candidate For every company you surface, apply the 4 sweet-zone criteria and assign a US-viability level. Capture: website, ru_signal (founder + city), market, us_viability, candidate contact (founder / Head of Product), open_roles_url, ATS slug if any, notes. ### 4. Dedup Collect all candidate names and pass them through the helper (step 1). Drop everything marked `DUP` silently — those are already in targets or rejects. Only `FRESH` names proceed. ### 5. Append - **Sweet-zone (FRESH)** → append a row to `ru_friendly_targets.tsv`. Match the existing 10-column schema exactly (header in the file): `name`, `website`, `ru_signal`, `market`, `us_viability`, `channel`, `ats`, `contact`, `open_roles_url`, `notes`. Tab-separated. Set `us_viability` to the level you judged. - **Rejects (FRESH)** → append a row to `ru_friendly_rejects.tsv`: `name`, `reason` (`hq_not_us` / `too_globalized` / `wrong_market` / `other`), `note`, `date`. Tab-separated. Never write a `DUP` to either file. Never edit existing rows — append only. ### 6. Push the new companies into Notion After appending, sync the targets ledger into the per-profile Notion Companies DB — deterministically, on code, not by hand: ``` node engine/cli.js companies-upsert --profile <id> # preview the plan node engine/cli.js companies-upsert --profile <id> --apply # write to Notion ``` The command is two-way deduped: it matches each target by domain **and** name against existing Notion pages, `data/companies.tsv`, and both relokant ledgers, so a company the job pipeline already created is never duplicated. A page that already exists is back-filled on **empty fields only** (Website, Careers URL, Why Interested, Notes, Outbound Status) — nothing is overwritten and `Tier` is never touched. `--dry-run` (default) prints `N to create, M to fill, K skip`; run `--apply` once the preview looks right. Do **not** create Notion pages by hand or via the Notion MCP from this skill — page writes live in the engine (RFC 022). This step is the only sanctioned path. See RFC 062 / BL-202. ### 7. Outreach drafts (new US-viable only) For each new target with US-viability HIGH or "exception", produce: - the best contact (founder or Head of Product, with a source for the name); - a short outreach draft in the same style as the existing top-3 drafts (see `profiles/<id>/outbound-strategy.md` if present). Neutral, specific to the company's US client wedge — not a generic "I'm looking for work". **You draft; the user sends.** Do not auto-send anything. ### 8. Update the rotation log + report Append a dated entry to `profiles/<id>/.relokant-state/sources_log.md`: which sources you swept, how many candidates seen, how many new targets / rejects / dupes. Then report to the user in chat: > Swept N candidates from <sources>. K new sweet-zone (→ targets), M > rejected (→ rejects), D dupes filtered. New US-viable: <names>. --- ## Cadence Run manually every 2–4 weeks. If you later want it automated, you can layer `/schedule` on top of this skill (a routine that invokes `/relokant-sweep`) — the skill mechanics don't change. Auto-cron is not part of RFC 061. --- ## Hard rules - **Append only.** Never rewrite or delete existing TSV rows. - **Dedup on code.** Always run names through `sweep_dedup.js` before appending — do not rely on remembering what's already there. - **Notion writes go through the engine.** Push companies to Notion only via `companies-upsert` (step 6) — never create pages by hand or via the Notion MCP from this skill (RFC 022). - **Drafts only for outreach.** The user sends messages by hand. - **No engine changes.** If a sweep needs the scan engine / a new discovery adapter, stop and open an RFC — that's out of scope here. - **PII stays in profiles/.** These TSVs are gitignored personal data; never echo a real contact's details into a committed file.