Internal · outreach machine

This one’s not for prospects.

Targets, KPIs, prompt inventory and the ICP pools. Client-side gate only — it keeps the page out of casual view, it is not security.

Not it. The passphrase is in your password manager under “machine”.
Internal · four sheets and the wiring

The machine’s own desk.

Everything the routine reads and writes, in the four sheets it actually maintains. The routine is the only thing that edits these — I read them.

targets.csv

written by 01-source-opportunities · 100 rows held · 8 shown
CompanyPoolDecision makerSignalScoreStatusUpdated
{{ t.co }} {{ t.pool }} {{ t.who }} {{ t.signal }} {{ t.score }} {{ t.status }} {{ t.updated }}

kpis.csv

written by 12-log-replies and the nightly tick
MetricNowTargetSource of truthCadenceLast updated
{{ k.name }} {{ k.now }} {{ k.target }} {{ k.src }} {{ k.cadence }} {{ k.updated }}

prompts.csv

the inventory — every prompt, what it reads, what it writes
PromptFileReadsWritesRuns
{{ p.name }} {{ p.file }} {{ p.reads }} {{ p.writes }} {{ p.runs }}

icps.csv

read by 02-qualify to assign a pool and a score
PoolWhoWhy they fitThe signalEmail difficultyShare
{{ i.pool }} {{ i.who }} {{ i.why }} {{ i.signal }} {{ i.email }} {{ i.share }}

How the routine updates a sheet.

One nightly pass. The clock wakes the worker, the worker runs a skill, the skill writes exactly one sheet, and the sheet’s last updated cell is the receipt that it ran.

01 · CLOCK Netlify scheduled fn 03:00 · enqueues, never works 02 · QUEUE job table, Netlify DB prospect · research · generate 03 · THE ROUTINE Claude Code, headless GitHub Actions, nightly reads prompts/skills/*.md 04 · COLLECTORS LinkedIn · Ad Library their site · email cascade targets.csv rows appended, score set icps.csv read only, edited by me prompts.csv rewritten from the folder kpis.csv recomputed after replies 05 · ME This page, read-only approve the package fire the invite queue edit icps.csv by hand ~23 min/day Every write stamps its own last-updated cell. A stale timestamp is the alarm — no run, no report, no guessing.
Fig. 1 — the nightly loop · solid = automatic, dashed = my hand
{{ s.k }}
{{ s.title }}
{{ s.body }}

One write, in full.

What actually happens when the routine adds a target — the sequence I’d expect to see in the log.

03:00 clock tick → pool at 88, want 12 enqueue prospect×1 03:04 worker claim job 4471 · kind=prospect 03:05 routine read prompts/skills/00-profile.md 03:05 routine read icps.csv → pools A–F, weights 03:11 collector LinkedIn + Ad Library + their site 03:19 routine score 12 candidates against profile 03:21 routine append 12 rows → targets.csv 03:21 routine stamp targets.csv last_updated=2026-09-04T03:21Z 03:22 worker report job 4471 done 03:23 clock recompute kpis.csv · pool=100 · stamp 07:00 me open this page, read two cells