Operations
Runbook
Day-to-day operation: logs, restarts, pausing, backups.
Day-to-day operation: the ten-minute routine, where to look when something seems off, and how to stop, start and back up safely.
The daily routine#
- Morning: open Best bets for today's company — fill it or ask its referrer, then mark it. Then the Queue: read each draft and its flags, fix lines that don't sound like you, approve or reject. Ten minutes.
- 10:00–19:00: keep the laptop open and on power — approved mail leaves one email every ~20 minutes.
- Evening: glance at Replies and Scraping health.
Starting and stopping#
the API
python scripts/run.py serve # foreground
nohup .venv/bin/python scripts/run.py serve >> logs/serve.log 2>&1 & # detached
pkill -f "scripts/run.py serve" # stopThe API does not reload on code changes; restart it after editing backend code. Check nothing is mid-task first:
before restarting
curl -s localhost:8000/api/tasks | jq '[.[] | select(.status=="running") | .name]'background jobs
python scripts/run.py tick status
launchctl unload ~/Library/LaunchAgents/com.zonuly.tick.send.plist # pause sending
launchctl load ~/Library/LaunchAgents/com.zonuly.tick.send.plist # resume sendingWhere to look#
| Question | Look at |
|---|---|
| Did the last cycle run, and what did it do? | tick status |
| Is anything stuck or failing? | Scraping health page · audit show · notify watchdog |
| Did emails go out? | Tracker page · outreach ledger · logs/tick-send.log |
| Why is a company still empty? | Graph → Fill now — the result names the reason for each missing part |
| Is LinkedIn blocking us? | actor status |
| How much Apify is left today? | Mixer panel on Best bets · actor apify · mixer history |
| Why is an approved email not leaving? | Outreach page (“why mail might not be leaving”) · outreach preflight — a per-domain cap or a spam hold waits, it doesn't fail |
| How much have models cost? | models costs --month |
| Log | Written by |
|---|---|
| logs/tick-free.log · tick-paid.log · tick-send.log | The three tick kinds (JSON summary per run) |
| logs/referrals.log | The referral job |
| logs/apify.log | The Apify job |
| logs/audit-run.log · audit.log | The hourly audit |
| logs/serve.log | The API |
| data/actors/runs.jsonl | Every actor run |
Backups#
copy the live database safely
sqlite3 jobhunter.db ".backup data/backups/jobhunter-$(date +%F-%H%M).db"Careful
Never commit jobhunter.db or data/backups/ — both are git-ignored on purpose, and the repository is public.Recording work#
After any change worth remembering: python scripts/run.py kg note "what changed" --about <node ids>. See Knowledge graph.