Job statuses — track your own pipeline, locally
Once you've matched against more than a handful of roles, you need somewhere to track what you've actually done about each one. Job statuses are that pipeline — and, like everything else, it never leaves your machine.
The funnel
| Status | How it's set |
|---|---|
clicked |
Automatic, the moment you open a job link |
applied |
You mark it explicitly |
saved |
You mark it explicitly |
dismissed |
You mark it explicitly |
clicked is deliberately never upgraded to applied on its own — Terminalhire
can see that you opened a link, not what you did on the employer's site, so it
never claims to know more than that.
Commands
terminalhire jobs # your matches, statuses shown inline
terminalhire jobs --stable # same list every run, in pure rank order
terminalhire jobs --status applied # filter to one status
terminalhire jobs mark <id> applied # applied | saved | dismissed
terminalhire save <jobId> # shortcut: save a job
terminalhire saved # list everything you've saved
terminalhire unsave <jobId> # remove a saved job
A job you dismiss drops out of your default views (spinner and jobs alike) —
reachable again only with an explicit --status dismissed — so your list stays
about what's still open, not what you've already ruled out.
Bare jobs rotates; paging does not
Run terminalhire jobs twice and you'll see different roles. Roles you were shown
recently sink and un-shown ones lead, so the list works down your matches instead of
restarting at the top every time. Nothing is dropped — the count is still every role
that matches you, just in a different order.
--page N, --all and --status deliberately keep pure rank order over one frozen
snapshot: a rotating page 2 would show a different slice than the page 1 you just
read. --stable gives you that same fixed order on the bare view when you want to
look at exactly the list you saw a minute ago.
Which roles you've been shown is recorded in a local file and never leaves your machine — same as your statuses.
The CLI is the single source of truth
Status lives in one place: the CLI, in a local file on your machine. The
/dashboard view on terminalhire.com mirrors clicked/dismissed as browser-local
state for convenience, but it's a read-only view — it never becomes a second,
conflicting pipeline. There is no server-side record of which jobs you've
applied to, saved, or dismissed: nothing to leak, nothing to sync, nothing a
breach could expose.
That still holds, and telling a poster why you're passing does not change it.
Passing is a separate, deliberate act with its own key (d<number> on the
bounties list) and its own consent — it is not what dismissed does, and it
never sends your status file. See below.
Telling a poster why you're passing
A poster whose work nobody takes gets silence, and silence can't tell "the price is too low" apart from "there's no CI, so I couldn't check my own work". Only the first is fixed by paying more, so the poster guesses — usually wrong.
On the bounties list, d3 passes on the third posting and asks why. You pick
one of five fixed answers; there is no free-text box. The first time, the CLI
prints the exact bytes it would send and waits for you to type yes; after that
it's one keystroke. terminalhire decline --forget revokes that consent, and the
next pass asks again.
What the poster sees is a count — never your name. Answers are pooled across everyone who passed, and the breakdown stays hidden on a posting until at least three people have answered, so no single answer can point back at one person. We store no login against your answer: the row carries a keyed hash that is different on every posting, so it can't be assembled into a history of what you turned down.
This only works on first-party postings. Bounties scraped from public trackers have nobody on the other end to tell.
Why it matters
An "applied 5 this week" count that's actually true — because it's computed from your own explicit actions, not inferred — is worth more than one that guesses. See Privacy architecture for how this fits the broader privacy design.