# Job hunt CRM This is a markdown-first, Python-validated job/company/contact CRM for a Cursor-driven job search. Markdown files are the source of truth. `data/leads.csv`, `data/companies.csv`, and `data/contacts.csv` are generated indexes. Use scripts to create leads, companies, contacts, and log interactions. --- ## Architecture ``` profile/ personal positioning, target thesis, voice, proof points leads/ job/role opportunities, one markdown file per lead companies/ target companies, one markdown file per company contacts/ people to contact, one markdown file per contact outputs/ generated resumes, notes, outreach drafts data/ generated CSV indexes and interaction log scripts/ deterministic creation, syncing, validation, reports .cursor/ Cursor rules and skills ``` **ID model:** `L0001` = lead · `C0001` = contact · `CO0001` = company **Cursor** browses, reasons, and drafts. **Python scripts** create IDs, sync indexes, validate, and report. --- ## Setup ```bash python3 -m venv .venv .venv/bin/pip install -r requirements.txt ``` Open the repo in Cursor. Enable Playwright MCP via `.cursor/mcp.json` for job-board browsing. --- ## Common commands ```bash python scripts/new_company.py --name "Example Labs" --website "https://example.com" python scripts/new_lead.py --title "Research Engineer Intern" --company "Example Labs" --url "https://example.com/jobs/123" --source "company_site" python scripts/new_contact.py --name "Jane Doe" --company "Example Labs" --role "Founder" python scripts/log_event.py --type message --contact C0001 --summary "Sent intro manually" --next-followup 2026-07-07 python scripts/sync_indexes.py python scripts/validate.py python scripts/report.py --today ``` ### End of every session ```bash python scripts/sync_indexes.py && python scripts/validate.py && python scripts/report.py --today ``` ### Report flags ```bash python scripts/report.py # full report python scripts/report.py --today # compact daily view python scripts/report.py --companies # company-focused sections python scripts/report.py --contacts # contact-focused sections python scripts/report.py --followups # follow-ups due python scripts/report.py --strong # strong leads not drafted ``` --- ## Entity creation (never hand-assign IDs) | Script | Creates | |--------|---------| | `new_lead.py` | `leads/L0001-*.md` + company if missing | | `new_contact.py` | `contacts/C0001-*.md` | | `new_company.py` | `companies/CO0001-*.md` | | `log_event.py` | row in `data/interactions.csv` + status updates | Duplicate job URLs are rejected. After any frontmatter edit, run `sync_indexes.py`. --- ## Lead status flow ``` found → researched → contact_needed → draft_needed → drafted → messaged → applied → followed_up → interviewing → closed | archived ``` Valid `match` values: `strong` · `moderate` · `weak` · `bad` Priority: `1`–`5` --- ## Profile and positioning | File | Purpose | |------|---------| | `profile/target-thesis.md` | What kinds of companies and work to pursue | | `profile/company-fit-rubric.md` | 1–5 scoring dimensions for company fit | | `profile/outreach-angles.md` | Normal and loud outreach modes | | `profile/voice.md` | How Ryan sounds in outbound text | | `goal.md` | Search keywords, categories, batch limits | --- ## Cursor skills | Skill | Purpose | |-------|---------| | `job-hunt` | Orchestrator — routes to the right workflow | | `company-scout` | Company-first discovery (YC, VC portfolios, labs) | | `collect-leads` | Job-board collection via Playwright + `new_lead.py` | | `job-eval` | Score fit against target thesis and rubric | | `review-leads` | Pipeline review + `report.py` | | `resume-tailor` | Per-role resume notes | | `compose-message` | Outreach drafts (normal + weird variants) | | `update-profile` | Refresh `profile/` sources of truth from links + your input | Always-on rules: `.cursor/rules/communication.mdc`, `.cursor/rules/safety.mdc`, `.cursor/rules/efficiency.mdc` --- ## Rules - Do not manually edit generated CSV indexes except through scripts. - Do not manually invent IDs. - Do not use old lead slugs as primary identifiers (IDs are canonical). - Do not auto-apply, auto-send, auto-DM, or auto-connect. - Prefer company-first discovery over job-board-only discovery. - Mark `applied` only when Ryan applied or explicitly asked to log it. --- ## Gitignored System tooling: `data/browser/`, `outputs/`, `.venv/`, `__pycache__/`, `.env*` Live CRM data is kept local (the public repo ships the system, not real records): `leads/*.md` (except `leads/_template.md`), `companies/*.md`, `contacts/*.md`, and the generated `data/leads.csv`, `data/contacts.csv`, `data/companies.csv`, `data/interactions.csv`. Running the scripts regenerates the CSVs locally.