Skip to main content
Glama
README.md
# Witness

**Witness does not auto-apply to jobs.** It never submits anything for you — there is no submit button in
the codebase. It does the opposite of a spam bot: it makes each application *fewer, better, and unfakeable*,
then hands it to you to send.

> An AI job tool that refuses to lie for you — and refuses to hit submit for you.

It pulls a company's **real** application questions (from public Greenhouse/Ashby APIs, not a guessed form),
traces **every claim in your draft back to a real line in your CV** (a proof-map — over-claiming is a bug it
catches, not a feature it maximizes), scores drafts for genericness before you ever see them, and writes it all
to an **offline dashboard** you click through yourself. Built for Claude Code (MCP + skills) and as a CLI.

![Witness catches an inflated, cliché answer (TRIVIAL) and passes a grounded, company-specific one (NON-TRIVIAL)](assets/demo.gif)

**Adversarially tested against 40 failure modes.** If a company's real form can't be loaded, you see a
`fetch_failed` flag and a red banner — Witness does not fake a form and call it done.

---

## Why it's different

- **Real ATS fields, not guesses.** Greenhouse + Ashby return the exact questions a company asks (custom ones
  included). Others fall back to a standard set — and say so. Fetch failures are surfaced, never hidden.
- **Every claim has a receipt.** The proof-map binds each statement in a draft to a real fact in your CV; an
  honesty check flags anything unbacked. (AI-inflated resumes now get detected ~76% of the time and
  auto-rejected by half of hiring managers — Witness is built so you're never the one caught.)
- **You submit, it never does.** Human-in-the-loop is an enforced design contract (see `TRADEMARK.md` /
  `CONTRIBUTING.md`), not an MVP gap. No auto-apply, no proxy/CAPTCHA bypass, no fake accounts — ever.

Plus a **non-trivial** layer nothing else does: it reframes a role onto the axis where you win and drafts a
short behavioural teardown of the company's own product — a witness only you could produce.

## Your data folder

Witness is local and bring-your-own-data. Point it at a folder with your CV-derived profile; outputs are
written back into that same folder. Nothing personal lives in this repo.

```
my-jobsearch/
  profile.json          # from `parse-cv`, or copy examples/profile.example.json
  config.json           # optional; copy examples/config.example.json
  output/jobs.json      # written by Witness
  applications/*.json   # written by Witness (+ a non-trivial kit each)
  dashboard.html        # written by Witness — open it or serve on localhost
```

## Quickstart (60 seconds)

```bash
python3 -m venv .venv && source .venv/bin/activate        # Python 3.10+
pip install -r requirements.txt
export ANTHROPIC_API_KEY=…                                 # optional (LLM CV-parsing + drafted answers)

D=~/my-jobsearch
python -m src.cli --data-dir $D parse-cv --cv ~/MyCV.pdf   # CV -> profile.json
python -m src.cli --data-dir $D scrape                     # -> output/jobs.json
python -m src.cli --data-dir $D apply --url "<job_url>"    # -> applications/<company>.json (+ kit)
python -m src.cli --data-dir $D dashboard                  # -> dashboard.html
python -m http.server -d $D 8899                           # then open http://localhost:8899/dashboard.html
```

## Claude Code (MCP + skills)

Add the server from `.mcp.json` and set `JOBSEARCH_DATA` to your folder, then just ask Claude:
*"find jobs"*, *"apply to <link>"*, *"make this application non-trivial"*, *"build my dashboard"*. The MCP
server (`src/mcp_server.py`) exposes `get_profile`, `read_jobs`, `refresh_jobs`, `get_application_fields`,
`generate_application`, `make_nontrivial`, `score_triviality`, `build_dashboard`, `list_companies`. Skills
live in `.claude/skills/`.

## Architecture

```
CV ─parse_cv─▶ profile.json ─┐
job boards ─scrape_jobs(JobSpy)─▶ output/jobs.json
job URL ─ats(Greenhouse/Ashby public APIs)─▶ exact fields ─┐
                                      generate_application ─┴─▶ applications/*.json (+ nontrivial kit)
                                                build_dashboard ─▶ dashboard.html (offline, copy buttons)
```

## Tests

```bash
python -m tests.adversarial          # offline (40 checks)
python -m tests.adversarial --net    # + live ATS probes
```

## Using it responsibly

Job discovery uses [JobSpy](https://github.com/speedyapply/JobSpy) to read public listings. **LinkedIn, Naukri,
Indeed and others prohibit automated access in their Terms of Service.** Witness makes no warranty of ToS
compliance; whether and how you run discovery is your own decision and responsibility. A conservative delay is
on by default — keep it, and don't run Witness as a scheduled/always-on service. Full terms in
**[DISCLAIMER.md](DISCLAIMER.md)**. Design invariants (no auto-submit, no circumvention) in
**[CONTRIBUTING.md](CONTRIBUTING.md)**.

## License

[Apache-2.0](LICENSE). The **name** and its human-in-the-loop guarantee are covered by
[TRADEMARK.md](TRADEMARK.md) — fork the code freely under a different name; don't ship a guardrail-stripped
build as "Witness".