# Open-source candidate sourcing you can read and change

> Open-source candidate sourcing puts the rules that decide who gets contacted in a repo your team can read and change. Kortix is the open-source CompanyOS: your agents, their skills, your company memory, and every connector in one git repo you own, with the agents working on real cloud computers.

URL: https://candidatesourcingguide.com/open-source-candidate-sourcing

Candidate sourcing

**The open-source CompanyOS**

`skills/outbound-sourcing/SKILL.md`

```
Read the role's Greenhouse pipeline first: applicants, candidates already contacted, and anyone rejected or passed on.
Search LinkedIn against the sourcing profile I give you: title, seniority and skills.
Drop every match that is already in the pipeline before you draft anything.
Write each email from one or two real details in the candidate's background.
Draft at most 20 candidates per run. Never send an email, and never create, update or tag a Greenhouse record.
```

Source: https://kortix.com/use-cases/candidate-sourcing

One isolated sandbox per session. Each session has its own isolated machine and branch.

[Try Kortix](https://kortix.com) · [How to source candidates](https://candidatesourcingguide.com/how-to-source-candidates)

Open source · Self-host is free · Connector credentials stay server-side

## What open source changes in a sourcing job

Sourcing a candidate comes down to two decisions and one message. Is this person already in your pipeline, and is anyone on your team about to email them? Open-source candidate sourcing puts both decisions in files your team can read. The rule that drops a name is then as visible as the draft that arrives.

Inside a closed product, the dedupe logic sits inside the product. You get back the profiles it kept. The condition that removed someone already in Greenhouse stays with the vendor, where you cannot diff it. A repo changes that. The rule is a line in a file next to the prompt and the schedule, so a change to who gets contacted arrives as a diff you can read before it applies.

The rest is ordinary work, most of it covered in [how to source candidates](/how-to-source-candidates). Read the role's Greenhouse pipeline. Search LinkedIn against a profile of title, seniority and skills. Drop everyone already known. Write an email for each new match from real details in that person's background. Kortix publishes one version of this as a setup you can put into your own project ([Kortix](https://kortix.com/use-cases/candidate-sourcing)).

## The dedupe rule, before the first draft

A candidate who receives the same cold email twice remembers it, and the second one costs you the first. The agent reads the role's pipeline for applicants, anyone already contacted, and anyone rejected or passed on. Then it drops every match it finds there before writing a word. The rule names the stages it checks, so a team whose pipeline has an unknown stage adds it to `skills/outbound-sourcing/SKILL.md`, and the next run applies it. One line removes the failure that is hardest to apologize for.

A sourcing product that ranks profiles stops at the list, and [AI candidate sourcing](/ai-candidate-sourcing) covers that shape. The list is where the expensive part starts. Someone still has to check every name against the pipeline before a message goes out, and that check is the one skipped on a busy day.

## The send boundary is a capability the agent does not have

Instructions in a prompt can be argued with. The sourcing agent's boundary is an action that does not exist: each run ends with one batch in the review inbox, and sending is a step a person performs. Drafts carry the candidate's current role and the reason they matched, so the review is mostly a read. The Greenhouse connection stays read-only, which makes the ATS a source the agent consults and never a place it edits.

## The profile and the run cap are lines you can argue with

Most weak batches start with a profile that is too broad or too narrow. Review time is set by how many drafts one run produces, and both are written down. The profile is text in the skill. The cap is the sentence "Draft at most 20 candidates per run." A team that wants ten drafts a day edits 20 to 10, and the change request shows the edit to whoever reviews it. A cap that lives in a vendor's settings panel gets negotiated with a support ticket instead.

## Where the rules live

Three files hold the job. `agents/candidate-sourcing.md` carries the prompt for one sweep. `skills/outbound-sourcing/SKILL.md` carries the rules that prompt loads: the dedupe, the profile, the rewrite instruction and the cap. `kortix.yaml` carries the agent block and the `daily-sourcing-sweep` trigger that fires it every morning at 07:00 UTC. Session work reaches `main` through a change request. Merge is default-deny for agents.

That arrangement matters most for the rule that decides who gets contacted. The person who owns the pipeline can review the change, and the review shows the old line next to the new one. A rule nobody outside the vendor can read is a rule you can only trust or leave.

## What self-hosting means for candidate data

Candidate data is other people's information: a name, a current employer, the detail that made them a match. Self-hosting decides which network holds it. Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free.

The connections work the same way in either place. Connector credentials are brokered server-side and never enter the machine. That covers the LinkedIn and Greenhouse connections the sweep uses. The Greenhouse connector reads the role's pipeline. The batch comes back through the review inbox as plain text a recruiter can edit. Each sweep is scoped to one open role, and only the drafted emails are written back out.

## What you still do yourself

Open source moves the rules into your repo. It leaves three jobs with the recruiter: reading every draft, sending the ones worth sending, and deciding who goes into the ATS.

Kortix's own walkthrough shows one worked run with this caption: "Illustrative example. Your counts depend on the role and the sourcing profile." In that example, 31 LinkedIn profiles are reviewed, 13 are dropped as already in the pipeline, 18 emails are drafted, and nothing is sent.

Expect different numbers in your first week. Note how many profiles a sweep drops as already known. Note how many drafts you would send without editing, and which edit you make twice. The repeated edit belongs in the skill file, where it changes every later run. If you are still comparing options, [candidate sourcing tools](/candidate-sourcing-tools) covers the pieces each one ships.

## Starting with one role

Pick one open role with a bar you can describe, write its sourcing profile as three lines, and run one sweep by hand before any schedule exists. Read every draft in the batch. The first batch tells you three things: whether the profile is right, whether the drafts sound like your team, and whether the dedupe catches the people you already know.

Then let the cron take over and keep the review step. The agent's value is a morning batch that has already searched and deduped. The send stays a decision a person makes, which is what makes the setup reasonable to run against real inboxes.

## The two files that hold the rules.

Both sit in your repo, so an edit arrives as a diff in a change request.

### Skill rules

`skills/outbound-sourcing/SKILL.md`

```
Read the role's Greenhouse pipeline first: applicants, candidates already contacted, and anyone rejected or passed on.
Search LinkedIn against the sourcing profile I give you: title, seniority and skills.
Drop every match that is already in the pipeline before you draft anything.
Write each email from one or two real details in the candidate's background. If the draft reads the same without them, rewrite it.
Draft at most 20 candidates per run. Never send an email, and never create, update or tag a Greenhouse record.
```

Source: https://kortix.com/use-cases/candidate-sourcing

### Trigger

`kortix.yaml`

```yaml
triggers:
  - slug: daily-sourcing-sweep
    name: Daily candidate-sourcing sweep
    on:
      cron: "0 0 7 * * *"
    run:
      agent: candidate-sourcing
      prompt: Load the outbound-sourcing skill and run one complete sourcing sweep for the open role.
```

Source: https://kortix.com/use-cases/candidate-sourcing

## Common questions about open-source sourcing

### Is there an open-source candidate sourcing tool?

Yes. Kortix is open source, and its candidate sourcing job is an agent you write into your own repo: one prompt, one skill file, one daily trigger. The rules that decide who is dropped and who is drafted sit in those files, where your team can read them.

### Can you self-host candidate sourcing?

Yes. The job is a prompt, a skill file and a trigger inside your repo, so it goes wherever you host the repo and the run. Self-host is free.

### Where do the sourcing rules live?

In your repo. The prompt is `agents/candidate-sourcing.md`, the rules are `skills/outbound-sourcing/SKILL.md`, and the daily schedule is a `cron` trigger in `kortix.yaml`. Edits arrive as a change request you can review line by line.

### Does an open-source sourcing agent send email itself?

No. The agent has no send action and no write access to Greenhouse, so a run ends with a batch of drafts in the review inbox. A recruiter edits each one, sends it, and decides who enters the ATS.

## Run one sourcing sweep from your own repo.

One open role, one batch of drafts, a rule file you can read.

[Try Kortix](https://kortix.com) · [Read the docs](https://kortix.com/docs)
