cv-2026/.claude/skills/triage-jobs/SKILL.md

14 KiB
Raw Blame History

name description
triage-jobs Triage one or more job vacancies using Oleg's canonical apply/skip playbook (vacancy-filter-and-triage-2026.md). Applies 4 hard gates, classifies the CV track, runs the research protocol, checks for prior applications, and outputs a consolidated verdict. For batch runs from telegram_inbox.json, stratifies by priority and delegates p2/p3 bulk to a Haiku subagent to protect the main session.

triage-jobs

Operational implementation of base/reference/vacancy-filter-and-triage-2026.md. That file is the authoritative playbook — read it before running this skill if you don't have it in context.

Posture: trying-friendly, not filtering-friendly. Hard skip is rare and requires a concrete objective blocker. On every ambiguous case, default to "подаём".


When to use

  • Oleg provides a job posting URL, raw JD text, or says "разбери вакансию".
  • After running scripts/fetch_telegram_jobs.py — triage tracking/telegram_inbox.json.
  • Any "should we apply?" question about a specific role.

Input modes

Mode What Oleg provides
Single URL One job posting link — fetch, triage, output verdict
Raw JD Pasted text — triage directly
Batch (inbox) No specific job — triage all entries in tracking/telegram_inbox.json

Step 0 — Read the playbook (if needed)

If vacancy-filter-and-triage-2026.md is not already in context:

Read: base/reference/vacancy-filter-and-triage-2026.md

Step 1 — Fetch the JD

For URL input:

  1. Try WebFetch first.
  2. If blocked (403, bot wall, login wall, JS-only, empty body) → switch to chrome-session skill immediately, no confirmation needed.
  3. If neither works → halt and report. Never reconstruct a JD from memory.

For Greenhouse / Lever / Ashby / Freshteam ATS: SSR usually works; confirm the "Apply" button is active (not a JS overlay saying "not accepting applications").


Step 2 — Extract fast facts (< 1 min)

Pull from the JD:

  • Role title and seniority signals
  • Must-have stack (vs. nice-to-have)
  • AI involvement: must-have / nice-to-have / not mentioned
  • Location & remote policy
  • Timezone / overlap requirements (explicit or inferable from location)
  • Compensation signals (range, equity framing, "scrappy" language, funding stage)

Step 3 — Run 4 hard gates

Evaluate gates in order. First failure → SKIP with one objective reason. All four pass → continue.

Gate 1 — Geography / hiring

Passes if the role can hire Oleg via any of:

  • Global remote (non-US/UK/EU-restricted)
  • Contractor via Deel or equivalent EOR covering Thailand
  • B2B contract for remote work
  • Russian-speaking team / Russian-speaking founders, hiring remotely (excluding RU/BY companies explicitly requiring presence)
  • Russian companies hiring remotely (presence in RU not required)
  • Relocation offered AND comp ≥ $10k/month
  • Temporary contract fully geography-agnostic (Mira, Algery, similar aggregators)

Skip if: location-locked / US-only / UK-only / EOR doesn't cover Thailand and no contractor option.

Gate 2 — Timezone (comp-scaled, not binary)

Oleg's flexible window: 9:0022:00 GMT+7. Comfortable day: 11:0020:00.

Required overlap Pass condition
Fits within 9:0022:00 GMT+7 Passes at any comp ≥ floor
Partially outside the window Passes if comp > $9k
Full US-day / PST core hours / night work Passes if comp > $10k

Skip only if: comp ≤ $9k AND required overlap falls outside 9:0022:00 GMT+7.

Gate 3 — Compensation

Tier Range Treatment
Target $812k/month Main funnel
Floor $68k/month Normal lower bound
Fallback $4.56k/month Temporary bridge only — штучно и осознанно
Skip < $4.5k/month Hard skip

No explicit comp? Read signals: pre-seed + equity-heavy framing + "scrappy team" → likely below floor. Founding-engineer at Series AB AI startup can stretch to $15k+ if profile matches.

Gate 4 — Seniority

Passes for: Senior / Staff / Tech Lead / experienced middle+.

  • Skip if: explicitly Junior or mid with no growth ceiling.
  • Do NOT skip if: role title is Lead / Principal / Head of — treat as "they don't have that person internally, try it."
  • Do NOT skip if: role looks like middle but comp fits floor/target AND the role offers interesting new experience (AI, client-facing, English immersion).

Step 4 — Anti-pattern self-check

Before marking skip, run through the false-blocker list. If you're about to skip on any of these, escalate to the next tier instead:

  1. Role looks senior-heavy (Lead/Principal/Head) → that's a try signal.
  2. One missing skill → ask Oleg first (see Step 6), not skip.
  3. "Not an AI-first company" → Track B or Hybrid, not skip.
  4. Superficial domain mismatch → look at actual technical tasks (orchestration, LLM workflows, structured extraction).
  5. "Not a Russian-speaking scale-up" → neutral, not negative.
  6. Timeline outside 8-week window → affects sequencing, not eligibility.
  7. Comp below $8k but in floor/fallback → consider, especially strategic or interesting roles.
  8. Tech stack mismatch with fast ramp → lean toward apply, mention ramp honestly.
  9. Doesn't fully pass triage but ≥50% match + low application effort (LinkedIn Easy Apply, simple form, DM) → quick-apply mode: note it explicitly as "fast/training apply."

Step 5 — Research protocol

Run for all roles that cleared the gates (and for borderline cases to resolve ambiguity).

5.0 — Check for prior application

Before deep research, check whether Oleg already applied to this role or company:

  • Trello (mcp__trello__set_active_board → board 6a1a9a5af082cb0526b22704, then search cards or scan the "Applyed" list).
  • tracking/applications.md — grep for company name.
  • Telegram — search in job-tracking chats if applicable.
  • Gmail — search for company name if accessible.

If already applied → note it in the output, don't re-triage as new.

5.1 — Research the company

What the company does, product, stage, funding, team size, recent news, reputation (Glassdoor / Blind if available). Goal: context + ghost/red-flag filter.

5.2 — Cross-platform posting check

Find the same vacancy on: company careers page, LinkedIn, ATS link (Greenhouse/Lever/Ashby/etc.), job boards, aggregators. Consolidate:

  • Posting date — earliest appearance. 90+ days without update = ghost signal.
  • Comp range — different platforms often show different bands. Collect all.
  • Geo restrictions — any platform saying US Only / UK Only / location-locked / eligible countries list?

5.3 — Restriction priority rule

Restrictions are authoritative. If one source says "remote" and another says "US only" → US only wins → Gate 1 skip. Less restrictive wording wins only if it explicitly and clearly overrides/removes the restriction.


Step 6 — Missing skills

One missing skill is not a skip if it isn't flagged as explicit MUST HAVE.

Action: ask Oleg before applying — "JD asks for X, I don't see it in your materials — did you have any experience with it?" Many skills exist but were trimmed from CV (examples: Redux Toolkit/RTK Query, Vitest, Playwright, Jest, eCommerce/CMS work).

Real gaps — can name without checking: Go, Rust, Java, C++, Ruby, PHP, heavy DevOps (K8s orchestration at scale, SRE), native mobile (Swift, Kotlin). React Native and Python are bridgeable, not gaps.

Never flag a gap explicitly in a cover letter — don't write "one thing to flag" or "I notice a gap here."


Step 7 — Classify track (for roles that cleared gates)

JD condition Track CV file
AI in must-have: LLM / agents / MCP / RAG / orchestration / embeddings in core requirements Track A base/cv-2026-05-base.md
Pure Node.js / backend, AI as nice-to-have or "significant plus" Backend-first base/cv-backend-variant-hostinger-2026-05.md
Senior / full-stack / frontend, no AI in must-have Track B base/oleg_proskurin_fullstack_techlead_cv.md
Senior + AI-tooling fluency as requirement (build with AI assistance, not AI product) Hybrid CV-B with AI moved up 23 positions in Skills

Russian-speaking scale-ups (Manychat, inDrive, Wheely, Joom, Adapty, similar) → Track B by default, even if AI not mentioned.

Tiebreakers:

  • Track B vs. skip → Track B wins.
  • Track A vs. Track B for hybrid JD → AI in must-have → A; otherwise → B.

Step 8 — Output format

One consolidated block per vacancy. No separate research section — merge everything.

## [Company] — [Role Title]

**Verdict:** APPLY (Track A) | SKIP | QUICK-APPLY

**Gate check:**
- Gate 1 (Geo): ✅ global remote / ❌ US-only
- Gate 2 (TZ): ✅ EMEA overlap fits / ⚠️ partial, comp > $9k ok / ❌
- Gate 3 (Comp): ✅ $XYk (target) / ⚠️ floor / ❌
- Gate 4 (Level): ✅ Senior / ❌ Junior

**Track:** A / B / Backend-first / Hybrid — CV: [filename]

**Strong matches:** [24 bullets: specific tech/scope from JD that map directly to Oleg's background]

**Open questions:** [missing skills to ask Oleg about; 12 items max]

**Research notes:**
- Company: [stage, product, funding, red flags if any]
- Posting date: [earliest found] — [fresh / stale signal]
- Comp across platforms: [consolidate bands found]
- Geo/restrictions: [what each platform says; which is authoritative]

**Prior application:** none found / ⚠️ already applied on [date], see Trello card [name]

**Proof-points for letter:** [23 concrete bullets that directly answer the JD's key asks]

For SKIP: one-liner after gate check explaining the objective blocker. No research section needed unless it was needed to determine the gate outcome.


Batch mode — stratified triage from telegram_inbox.json

When triaging tracking/telegram_inbox.json:

Pre-step: build prior-applications list (do this once before spawning any subagent)

grep -E '^\|' tracking/applications.md | tail -n +2 | awk -F'|' '{print $3}' | sort -u

Also call mcp__trello__get_cards_by_list_id for all BestJob board lists to extract card titles. Merge both into a known_applied list (company name → date/status where available). Pass this list to every Haiku subagent prompt (see template below).

Stratification rules

  1. Read the file. Group entries by channel priority field (p1 / p2 / p3).
  2. p1 entries — ≤ 15 messages: triage fully in the main session (full Step 18 per entry).
  3. p1 entries — > 15 messages: Haiku first pass (same prompt as p2/p3). Main session then reviews only APPLY and VERIFY verdicts; SKIP verdicts from Haiku are accepted without re-review.
  4. p2 and p3 entries: delegate to a Haiku subagent to protect main context.
    • Pass the raw entries, the playbook summary, and the known_applied list to the subagent.
    • Subagent returns a structured verdict list.
    • Review, escalate any APPLY and VERIFY passes to main session for full triage.
  5. After all verdicts: promote confirmed APPLY entries to tracking/applications.md.
  6. For QUICK-APPLY entries: note explicitly, ask Oleg if he wants to proceed.
  7. For VERIFY entries: run a fast WebSearch "{company} remote hiring countries" to resolve geo; then apply the gate.

Haiku subagent prompt template

You are triaging job vacancies for Oleg Proskurin (Tech Lead / AI Engineer, based in Thailand GMT+7, available for remote work).

Apply these 4 hard gates — SKIP on first failure:

Gate 1 (Geo): Must allow: global remote non-US/UK/EU, contractor via Deel/EOR from Thailand, B2B remote, Russian-speaking teams hiring remotely (not RU/BY presence-required), relocation with comp ≥$10k, geography-agnostic temp contracts.
Gate 2 (TZ): Oleg's window 9:0022:00 GMT+7. Outside window: ok if comp > $9k. Night/PST core: ok if comp > $10k. Skip only if comp ≤ $9k AND overlap is outside window.
Gate 3 (Comp): Skip if < $4.5k/month. Floor $68k, target $812k.
Gate 4 (Level): Skip if explicitly Junior or mid with no growth ceiling.

Posture: trying-friendly when data IS PRESENT and borderline. When key gate data is ABSENT from the message text, return VERIFY — not APPLY. Lean toward APPLY only when geo and comp are explicitly stated and borderline (e.g. "global remote", "$7k/month").

Geo rules (Gate 1):
- Message explicitly says "global remote" / "worldwide" / "anywhere" / "любой город" / contractor-friendly → Gate 1 passes, proceed.
- Message says "United States" / "US only" / "United Kingdom only" / specific country list excluding Thailand → SKIP Gate 1.
- Message says "Remote" with no geo qualifier → VERIFY geo (cannot confirm Thailand eligibility without JD).
- Message has no location info at all → VERIFY geo.

Comp rules (Gate 3):
- Explicit salary ≥ $4.5k/month or ≥ $54k/year → Gate 3 passes, proceed.
- Explicit salary < $4.5k/month → SKIP Gate 3.
- No salary mentioned → VERIFY comp.
- Timezone offset explicitly stated (e.g. GMT-GMT+6) → treat as geo restriction, apply Gate 1.

Known applied companies — flag these as SKIP (already applied):
[INSERT known_applied LIST HERE — one line per company]

For each vacancy below, output one line:
APPLY | SKIP | QUICK-APPLY | VERIFY — [company/role] — [gate failed or what's missing] — [track: A/B/Backend-first/Hybrid]

Vacancies:
[paste entries from telegram_inbox.json]

After triage — update tracking

For every APPLY verdict:

  • Add a row to tracking/applications.md with status todo (not yet applied) or applied if Oleg confirms.
  • Create a Trello card in the TODO column (6a1aa59555aab72a261c42aa) on board 6a1a9a5af082cb0526b22704 with: company, role, track, verdict summary, link to JD.

For SKIP: no tracking entry needed unless Oleg says to keep it for reference.