Skip to content
Sankalp
system · armed
mission · job-application autopilot · portfolio

Apply with a draft already in the box.

Sankalp scrapes Naukri and Turing listings through a browser MV3 extension and the Claude-in-Browser side panel, persists every posting under Supabase RLS, then wakes a dedicated Claude Code session on sankalp-channel to enrich, match, and draft the application before the portal even opens.

832
jobs captured · 30d
126
auto-drafts queued
9
mcp tools · sankalp-channel
RLS
per-user isolation

queue · last 5

match · score

  • Anthropic

    Senior · MCP infra

    queued92
  • Vercel

    Staff · Next.js team

    draft88
  • Supabase

    Sr. Postgres engineer

    queued85
  • Modal

    AI infra engineer

    applied79
  • Cursor

    Founding · agent infra

    queued96

next wake · 06m 14s · sankalp-channel

11.2k

tokens / draft

<2s

capture latency

0

manual paste

System map

Three bays. One mission deck.

Capture every posting, reason about each with a dedicated Claude Code instance, apply with a draft already in the box. Each bay isolates state so a stalled scrape never blocks an outgoing draft.

map · sankalp.livescan · armed

01 · Capture

browser-side

  • Naukri

    ok

    mv3 extension · sankalp-chrome

  • Turing

    ok

    mv3 extension · sankalp-chrome

  • Claude-in-Browser

    live

    side-panel Act capture

02 · Reason

desktop Claude Code

  • sankalp-channel CC

    live

    dedicated brain · sutra/brains/sankalp

  • 9 MCP tools

    ok

    enrich · score · draft · log

  • sankalp_applications

    ok

    rls per-user · pgvector match

03 · Apply

back to browser

  • Application draft

    queued

    queued for human approval

  • Auto-fill via MV3

    queued

    naukri form prefill

  • audit_log

    ok

    every state transition recorded

p50 capture

1.8s

p99 draft

14.2s

tokens / draft

11.2k

auth

shared supabase JWT

Capabilities

What the autopilot does, and what it won't.

The boundary is intentional. Overclaiming would either burn portal accounts or turn the autopilot into a fraud machine. Neither ships.

[ active capabilities ]

  • A.01

    Scrape Naukri + Turing without rate-limiting yourself

    A browser MV3 extension drives the portal pages cooperatively — page-of-30 cursor, randomized human-scale delay, per-domain back-off. Captured rows write to sankalp_applications under RLS.

  • A.02

    Reason about each posting before you see it

    Every captured row gets enriched by a dedicated sankalp-channel CC instance: stack-match against your profile (pgvector cosine), salary triangulation from public ranges, red-flag detection (visa, location, contract terms).

  • A.03

    Draft the actual application

    Cover note, custom Q&A, role-tailored bullet list — written in your voice from your saved brand spec. The draft lands in the queue with a match score, not in your inbox.

  • A.04

    Auto-fill the portal form

    When you approve a draft, the MV3 extension prefills the Naukri / Turing form fields straight from the row. You see the screen, you click Submit. The autopilot never sends without consent.

[ scope wall · honest ]

  • B.01

    Apply silently on your behalf

    There's always a human-in-the-loop click. Submitting on behalf of a candidate is fraud-adjacent on most portals and a portfolio risk — Sankalp won't cross that line.

  • B.02

    Work with portals that lack a stable DOM

    Highly-obfuscated portals (lattice, anti-bot scrapers) need real Playwright residential sessions. Sankalp covers Naukri + Turing today; LinkedIn capture rides on Claude-in-Browser Act, not on a scraper.

  • B.03

    Replace your real network

    The autopilot widens the funnel; it doesn't replace warm intros. Use it to keep applying when you're busy, not as a substitute for a referral conversation.

Operations log

Four decisions that earned their keep.

Each is in production traffic. Each has a debug session behind it. The kind of detail recruiters skim past on a resume.

OPS-01

Two scrapers, one schema

Naukri and Turing have nothing in common — different DOM, different anti-bot posture, different listing shapes. A naive scraper produces two parallel datasets that never merge.

one shapeacross every source
  1. A browser MV3 extension hosts per-portal adapters. Each adapter normalizes into the same sankalp_applications row shape: company, role, comp_range, location, source_url, raw_html, captured_at.

  2. Claude-in-Browser handles the high-friction listings (LinkedIn-style obfuscation) via Act capability dispatched from the panel. Same row shape lands in the same table.

  3. Per-portal back-off + page-of-30 cursor + jittered click cadence keep the autopilot quiet enough that the operator account is never flagged.

excerpt · OPS-01.code
-- shared schema for every source
create table sankalp_applications (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users not null,
  source text not null check (source in
    ('naukri','turing','claude_in_chrome','manual')),
  company text not null,
  role text not null,
  raw_html text,
  match_score int,
  status text default 'captured'
);

create index on sankalp_applications (user_id, captured_at desc);
OPS-02

Reason on a dedicated brain

Mixing job-application reasoning with the operator's live Claude Code chat means a single Naukri burst could pre-empt whatever the operator was working on. Same attention head, two tasks, bad outcome.

9 + 5mcp tools · sankalp-channel
  1. A separate Claude Code instance is launched against sutra/brains/sankalp/CLAUDE.md and attached to sankalp-channel. Different cwd, different MCP server endpoint, different attention.

  2. Nine sankalp-channel MCP tools cover the workflow: enrich_application, score_match, draft_cover_note, draft_qa, log_application, mark_submitted, queue_followup, replay_capture, and dispatch_to_chrome.

  3. Every state transition writes a row to audit_log with app_actor=sankalp. Failed enrich runs surface as "needs code fix" escalations; the operator sees them in the dashboard, the autopilot doesn't silently drop.

excerpt · OPS-02.code
// sutra/brains/sankalp launch
$ cd sutra/brains/sankalp
$ claude --dangerously-load-development-channels \
         server:sankalp-channel \
         --dangerously-skip-permissions

# attaches to /sankalp/api/mcp at 127.0.0.1:9000
# registers 9 sankalp_* + 5 chat_respond_* tools
# CLAUDE.md primes the agent on the brand voice spec
OPS-03

Match score before any draft

Drafting a custom cover note for every captured row would burn ~12k tokens per posting. At 800 captures/month that's a six-figure token bill for a portfolio app. We needed a pre-draft filter.

< 5%token burn vs naive draft-all
  1. Each posting is embedded once with text-embedding-3-small and stored in sankalp_applications.embedding (vector(1536)).

  2. A pgvector cosine-similarity match against the operator's pa_profiles.brand vector produces a 0-100 match score. Postings below the threshold never reach a draft tool — they sit in the dashboard for a quick human glance.

  3. Drafts are written only for top-N (operator-configurable, default 25 per day). Cost stays bounded; the funnel stays full.

excerpt · OPS-03.code
-- match score = cosine similarity vs operator brand vector
select id, company, role,
       1 - (embedding <=> $1::vector) as score
from sankalp_applications
where user_id = auth.uid()
  and status = 'captured'
order by embedding <=> $1::vector
limit 25;
OPS-04

Auto-fill that never auto-submits

The biggest temptation in a job-application autopilot is to also click Submit. That's how portal accounts get banned and how the entire product becomes ethically suspect. We needed a firm line.

0auto-submits, by design
  1. When a draft is approved, the MV3 extension reads the row and prefills the visible portal form. The operator sees the screen, scans the answers, clicks Submit themselves.

  2. No "submit on behalf" code path exists in the codebase. The button literally is not wired. This is the kind of constraint that survives the year because the wire was never there to begin with.

  3. A signed receipt of every submit is logged to audit_log with submit_actor=human. Compliance posture is auditable for any future portal integration.

excerpt · OPS-04.code
// chrome-mv3/content.ts
async function prefill(row: ApplicationRow) {
  for (const [selector, value] of Object.entries(row.form_fields)) {
    const el = document.querySelector<HTMLInputElement>(selector)
    if (!el) continue
    el.value = value
    el.dispatchEvent(new Event('input', { bubbles: true }))
  }
  // intentionally: no document.querySelector('button[type="submit"]').click()
}

Open to work

I scraped it, scored it, drafted it, and bound it to RLS — I can do the same for you.

Sankalp is one of seven dogfooded apps I ship in parallel. Same Supabase project, same MCP fabric, same Claude Code stack. Happy to walk a hiring panel through any layer live — the browser extension, the brain, the pgvector match, or the audit log.

Senior / staff full-stackAI engineer · MCP & agent infraNext.js · TypeScript freelanceBrowser automation · browser MV3RAG + pgvector match-scoring