Ryanhub - file viewer
filename: README.md
branch: main
back to repo
# 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.