how it works
The whole machine, and what it would take to run it.
Every service, every hop a request makes, what is encrypted, what is exposed and what is watching — written out of the source rather than described from memory, so it can be checked.
01
What is actually required
Three things, and only one of them costs anything to obtain.
| You need | Why |
|---|---|
| Google Chrome | The extension fills the forms, and filling a form is the browser. There is no server-side substitute for this step. |
| A Mistral API key | Reading descriptions, ranking them and profiling your résumé all run on your key, not ours. A free-tier key works. |
| A résumé, as a PDF | It is parsed into the profile every form is filled from, and it is the document that gets attached unless tailoring is on. |
| Docker Desktop | Only if you are running the whole stack yourself. Not needed to use a deployment somebody else is running. |
Nothing here asks for a Google account sign-in, and nothing asks for the password to any account you already have. The two credentials the system ever holds are an API key and — only if you switch outreach on — a mail app password, which is a revocable token that grants sending and nothing else.
02
Install the extension
Three minutes, once. It never has to be repeated.
Everything upstream of the last step — sweeping boards, ranking roles, rewriting your résumé — happens on a server. The last step does not. A form is submitted by your own browser, in your own session, because that is the only way an application arrives as genuinely yours.
- Open the applyNchill listing on the Chrome Web Store and press Add to Chrome, then Add extension.
- If Chrome warns “Proceed with caution”, press Continue to install. Only Enhanced Safe Browsing shows it, and it says that about any publisher new to the store.
- Click the applyNchill icon in the toolbar to open its side panel, and pin it so it stays one click away.
- Sign in on the panel’s Account tab with the same email and password as this website — the two are signed in separately, and this is the step people miss.
Self-hosting and loading the extension unpacked instead? With Docker, load the folder the extension container writes rather than the source folder. That is also where your uploaded résumé and profile are written, so loading the other one presents as a setup page that looks finished and an agent that fills nothing.
03
Add your Mistral key
Two minutes. It is applied immediately and needs no restart.
Three stages spend the key: reading each job description into structured facts, profiling your résumé once so the ranking has something to rank against, and — if you turn it on — tailoring a résumé per job. Fetching spends nothing; applying spends nothing except where a form needs a field reasoned about.
- The key is yours and stays yours. It is stored encrypted, shown back to you as a few characters so you can tell which one it is, and used from your account only.
- Give it more than one if you can. Free keys rate-limit constantly, so keys are held as a pool: requests spread round-robin, a rejected key is marked dead, a rate-limited one sits out a cooldown and rejoins.
- One expired key stops being an outage the moment there are two.
04
Set up your profile
The longest step, about ten minutes, and the one that decides the quality of everything after it.
Upload a résumé and it is parsed into a profile: your details, your skills, your history. Correct it once and every application after it is right. The same record is written to both the matcher and the extension, so the thing that decides which jobs to chase and the thing that types into the form can never drift apart.
- Your stated years of experience sets the experience window that is searched, and it is authoritative over anything a model reads off the document. Get it wrong and nothing matches.
- Your skills become the gate. A job mentioning none of your leading core skills is removed before ranking rather than ranked low.
- Fields the profile editor has no interface for are carried through a save untouched, so anything a portal starts asking for survives rather than being dropped.
- End dates given as “present” are materialised as today’s date at the moment a form is filled, and only into blanks — never stored back as a fixed date that quietly ages.
Applying at more than one level? Tracks let a fresher profile and an experienced profile coexist, each with its own ranked queue, its own CV, and — where the answers differ — its own profile overrides. The site shows one tab or two depending on how many are switched on.
05
Choose what it hunts
The role list is the one setting that changes the cost of a run.
Target roles are a per-account list you edit rather than a constant in a build. Each role is paired with the boards that role actually appears on, and a sweep is planned for every pair — so the length of a run is linear in how many roles you keep. Four well-chosen roles find more than twelve vague ones and finish in a third of the time.
- The list is never allowed to be empty. A sweep with nothing to look for and a service that is simply broken look identical from the outside.
- The limits — how many roles, and the minutes each one adds — come from the server and are shown in the editor, so the estimate is the real one rather than a copy that drifts.
- Editing is a draft until you save. That is what makes undo work, and what stops a half-finished list reaching the sweep.
06
The two optional stages
Both are off by default, and everything else works identically without either.
Per-job résumé tailoring rewrites your résumé for each job before applying. It needs a coding agent you already have — nothing new to buy — and a master record saying what a tailored résumé is allowed to say: your skill vocabulary, your verified figures, your employment dates. Every generated document is a selection and rephrasing of that record and nothing else, checked before it can be used, and every failure path ends with your base résumé going out instead.
Recruiter outreach finds and verifies addresses at the companies you are applying to, drafts something specific to each person, and holds the batch until you approve it. It needs a mail app password: a token you generate in your own account settings, that grants mail sending and nothing else, that is stored encrypted here and shown back as four characters, and that you can revoke in one click without changing anything else about your account.
If you would rather not hand over a mail token, leave outreach switched off. Fetching, ranking, tailoring and applying are unaffected — it is a parallel loop, not a stage the pipeline waits on.
07
Running the whole thing yourself
Clone, fill in two files, and build. No registry account, no Java, no Python, no Node on your machine.
Everything is built and run inside containers from the repository itself. The first build takes a while — it compiles the Java services, installs the browser service’s dependencies and packages the extension — and later starts reuse the layer cache and come up in seconds.
git clone <repository-url>
cd app/app
cp .env.example .env
cp config/resume-profile.example.json config/resume-profile.json
./start.sh --dev # macOS / Linux
.\start.ps1 -Dev # Windows- Every value in those templates is invented — made-up names, made-up employers, made-up numbers. Replace all of them: anything left behind gets typed into a real application form.
- All of the configuration files are ignored by git and none of them is baked into an image, which is why one build works for everybody.
- The dev flag is not a development mode. It selects the compose file that builds the services locally, which is the supported path.
- On a single-machine install everything binds to the loopback address. These services hold your résumé, salary and contact details; they are not meant to be reachable from your network.
| Port | What is on it |
|---|---|
| 8083 | apply-service — the dashboard, the queue, the API |
| 8081 | fetch-service — the board sweep |
| 8082 | enrich-service — description extraction and enrichment |
| 8000 | scraper-service — the containerised browser |
| 3307 | MySQL, for your own client |
| 3000 | Grafana, if the monitoring profile is running |
A shared deployment is a different shape: the services move onto an internal network, a gateway becomes the only published port, and a reverse proxy in front of it terminates TLS. That arrangement is described in full on the Architecture tab.
08
What the first run looks like
One button, and a dashboard that tells you what is behind each number.
- Jobs found, descriptions read, skills extracted, applications queued — each showing what is still behind it rather than a total with no denominator.
- Now applying: the job in progress, its live log, and a heartbeat that turns amber and then red if it goes quiet.
- Up next: the queue in order, so you know exactly what happens if you close a tab.
- Matched jobs: ranked, filterable, with the skills you are missing struck through.
- Recently finished, including the failures and the reason for each.
Stopping is a first-class action rather than a crash. A sweep can be stopped mid-run, and the work already done is kept — every stage writes its progress to the database as it goes.
09
When it asks for you
Some applications stop and hand you two or three fields. Nothing here needs configuring — but it is the one part of running this that expects you to be reachable.
A driver that reaches a question your profile cannot answer does not guess at it. It holds the tab open, raises exactly the fields it is stuck on, and waits for you. Three things reliably cause it: a question the employer wrote themselves, a document that was never supplied, and a check that exists to establish that a person is present.
- Inside the browser profile the extension is loaded into, the ask is drawn over whatever tab you are on. You do not have to be looking at the application, and you should not go hunting for it.
- Outside that profile — another Chrome profile, an editor, another screen — a small window opens instead. It deliberately does not take your focus, and answering it there releases the waiting run.
- Four commands: Application goes to the form, Done resumes the run, Battle Report lists what it is stuck on, Close dismisses the panel without answering anything.
- Fill the fields in the form itself, then press Done. The run picks it up within a couple of seconds and continues on the same job.
- The clock is three minutes. Miss it and nothing is lost: the driver submits once and records whatever the employer actually said back.
The one decision to make up front is which Chrome profile you install the extension into, because that is the profile the ask appears in. The whole mechanism — the escalation when a page tries to suppress the widget, the relay that carries an answer given in another profile — is on the Architecture tab under “The human in the loop”.
walkthroughs