private alpha · runs on your machine
One terminal.
Many souls.
JIVA keeps a small fleet of Claude Code sessions alive in a private tmux server. A desk talks to you, a boss splits the work, workers do it. A plain bash watchdog checks every session every 5 seconds and swaps any of them for a fresh one before it gets past 200k tokens of context.
You keep one window open. Questions reach you there. The rest of the fleet stays out of your way.
How to get it01The problem
Run four Claude Code sessions by hand and you get four terminal tabs, four permission prompts you can't see, and four contexts that slowly fill with stale tool output. Around 200k tokens a session starts forgetting its own plan. You notice later, when the work drifts.
JIVA turns that into a routine. Each session has a role, a task card of 20 lines or fewer, and a fixed exit: write a handoff of 40 lines or fewer, stop, get respawned. You watch one terminal and one status line instead of tabs.
02How it works
Three roles, all ordinary Claude Code sessions in tmux windows on a private server (tmux -L jiva-<repo>), so they never touch your own tmux.
- desk
- The only session you talk to. Relays asks and reports, and brings real decisions to you: server and deploy changes, spend, destructive ops, sudo.
- boss
- Splits a goal into task cards and assigns them. Doesn't write product code.
- workers
- One card each. They claim paths, do the work, run checks, ship.
- watchdog
- Not an LLM. A bash loop that writes
.jiva/state.json, the tmux status bar, flags and respawns.
Asks bubble up. A worker that is stuck asks the boss. If the boss can't decide, it files a typed ask (question, options, default, class) for the desk. The watchdog batches open asks into one digest for the desk, which puts them to you. You answer in one place with jiva answer <id>. Only a decision ever falls back to its default; permission, deploy, spend and the other protected classes wait for you.
03Six verbs
Sessions coordinate through six verbs on the jiva command (just j-* wraps them) and one append-only board. That's the whole protocol. Anything a verb can't express goes to a human. The desk has two more: jiva answer closes an ask, jiva pending lists panes stuck at a prompt.
claim <paths>Lock directories before editing. Overlapping claims are refused.report done|blocked|notedonerunsjiva checkfirst: files ≤150 lines, notes ≤30, scripts parse.ask <q> <opts> <default>A typed question for the desk, with a class. Always carries a default.ship <msg>Commits only the claimed paths, pushes under a lock.handoff≤40 lines of pointers to the next body, then stop.inboxThe last 15 board lines plus open desk asks.
04Reincarnation at ~200k
The context window may be larger, but JIVA caps each session at 200k tokens on purpose. Past that, quality drops before the window runs out.
- 170k (85%): the watchdog types a nudge into the pane: write your handoff.
- The session runs
jiva handoff: ≤40 lines of pointers, not a transcript. Then it stops. - The watchdog sees it idle and respawns the pane. The SessionStart hook hands the new body its handoff and task card.
- 200k without a handoff trips the
ceilingbreaker: one hard message, then a flag for you.
The kill switch
$ touch .jiva/STOP The watchdog checks for this file every tick and exits when it appears. No respawns, no nudges. The tmux bar reads STOPPED. just down kills the private tmux server and the dashboard; your own tmux is untouched.
Breakers
Six trip wires write a file to .jiva/flags/: repeat (the same tool call 4 times in a row), storm (past 170k within 3 minutes of boot, so the session is parked), ceiling, burn (60k tokens without a board line), time (a life past 90 minutes) and usd (a life past $15); all three are env-tunable defaults. A parked session stays down until you remove .jiva/parked/<name>. jiva doctor breakers trips each one on purpose.
05The watchdog view
just dash serves a one-page dashboard on 127.0.0.1, on a random port between 20000 and 60000. It reads state.json every 5 seconds, greys out if the data is older than 30 seconds, and goes red when anything is flagged.
Sample. Static numbers, not live data. Labels are the real state.json field names; table columns are sessions[].
| name | status | waiting | tok | pct | usd | up |
|---|---|---|---|---|---|---|
| desk | idle | – | 38k | 19 | 0.61 | 2h 10m |
| boss | busy | – | 91k | 46 | 1.72 | 1h 48m |
| w1 | busy | – | 64k | 32 | 1.30 | 41m |
| w2 | busy | – | 152k | 76 | 2.09 | 58m |
| w3 | busy | – | 67k | 34 | 1.12 | 37m |
06Security, plainly
JIVA adds no server and no account. It's bash, tmux and the Claude Code CLI you already run, on your machine.
- Local only. Every session runs in tmux on your machine, on a private socket per repo (
tmux -L jiva-<repo>). - Permissions stay yours. Sessions run in Claude Code's auto mode with your own allowlist. Anything outside it prompts natively in that session's pane, and only a human answers. JIVA ships no hook that auto-approves anything (an opt-in relay can forward a prompt to the desk, never decide it), and never clicks through the workspace-trust dialog.
jiva pendinglists the panes waiting on you. - No inbound ports. The dashboard binds
127.0.0.1only, serves two files, and rejects..paths. - State is numbers and enums.
state.jsonholds token counts, percentages, status words and session names. No prompts, no output, no file contents. - Secrets are never printed. Keys are read inside scripts only. Sessions are told not to cat them, and
just secscans the full git history for leaks. - This page: static files, a strict Content-Security-Policy, self-hosted fonts, no cookies, no analytics, no third-party requests.
07Built with itself
The watchdog, the verbs, the dashboard and this page were written by JIVA sessions, each working from a task card and ending in a handoff. The fleet that runs the work is the fleet that wrote the runner.
Open source: coming later. The repo is private for now.
Install (private alpha)
You need git, tmux (tested on 3.4), jq, just and Claude Code. With access to the private repo:
$ git clone [email protected]:saintpetejackboy/jiva.git ~/jiva $ export PATH="$HOME/jiva/bin:$PATH"
Then, inside any repo:
$ jiva init # .jiva/, gitignore, CLAUDE.md pointer $ jiva up 3 # watchdog + boss + 3 workers $ jiva doctor # budgets as tests: payload, handoffs, hooks $ jiva down # kill the private tmux server
Workers: soft cap 6 (above it, JIVA_CONFIRM=1), hard cap 12. Each one burns quota like a session of its own. Hooks reach each pane through a --settings file, or through the optional plugin (jiva plugin install); jiva up prints which one it used.
First run in a new repo:jiva up stops at Claude Code's workspace-trust dialog, once per repo. Attach with tmux -L jiva-<repo> a and accept it yourself. JIVA never auto-accepts it.
Not yet. Once the repo is public:
$ npx github:saintpetejackboy/jiva 08Reference
Every verb and recipe, read from jiva help and just --list when this page was built. Nothing here is typed by hand.
| verb | what it does |
|---|---|
jiva plugin [install|uninstall|status|mode] | local plugin at user scope (plugin/install.sh); mode = hooks source |
jiva init | make this repo fleet-ready (.jiva/, .gitignore, CLAUDE.md pointer if absent) |
jiva up [workers] | watchdog + boss + N workers (default 2) |
jiva spawn <role> <name> | start one session in its own window |
jiva respawn <name> | kill the pane and boot a fresh body (same role/name, re-reads boot payload) |
jiva assign <w> <card> | install a task card for worker <w>, respawn it, kick it off |
jiva restart-watchdog | respawn the watchdog pane (picks up core/watchdog.sh edits; fleet untouched) |
jiva say <name> <text> | type a line into a session |
jiva down | stop everything (kills this target's tmux server + dash only) |
jiva status | one-line fleet summary from .jiva/state.json |
jiva doctor [live|breakers|asks|perm|lease|plugin] | budgets as tests; live kill -9 self-heal; others run only that set |
jiva dash [start|stop|url] | tier-1 dashboard on 127.0.0.1:<random port> |
jiva mine [n] | rank repeated Bash commands from this repo's transcripts (recipe candidates) |
jiva roster [gen|check|show] [pack] | name/color/avatar pack tooling (scripts/roster.sh; default pack) |
jiva pick <paths…> | best idle worker for these paths (affinity table; boss still chooses) |
jiva check | files ≤150 lines, notes ≤30, scripts parse, shellcheck (run in the target) |
jiva spike | re-test version-sensitive assumptions on scratch socket jiva-spike |
jiva claim | session verbs (core/verbs.sh); see Six verbs |
jiva report | session verbs (core/verbs.sh); see Six verbs |
jiva ask | session verbs (core/verbs.sh); see Six verbs |
jiva answer | session verbs (core/verbs.sh); see Six verbs |
jiva ship | session verbs (core/verbs.sh); see Six verbs |
jiva handoff | session verbs (core/verbs.sh); see Six verbs |
jiva inbox | session verbs (core/verbs.sh); see Six verbs |
jiva pending | session verbs (core/verbs.sh); see Six verbs |
jiva help | this list. Workers: soft cap 6 (JIVA_CONFIRM=1 above it), hard cap 12. |
| recipe | what it does |
|---|---|
| j-* · verb wrappers | |
just j-answer id text="" | desk/human: answer an open ask (no text = its default); the asker gets "JIVA answer <id>: <text>" |
just j-ask question options="" default="" class="decision" | verb: typed ask for the desk: question, options, default, class (decision|permission|deploy|spend|…) |
just j-assign worker card | boss: give worker a ≤20-line task card (fresh body boots with it) |
just j-claim +paths | verb: claim paths before editing (directory-level, no overlaps) |
just j-handoff file="" | verb: save a ≤40-line handoff from stdin or a file, then stop (watchdog respawns you) |
just j-inbox n="15" | verb: recent board + open desk asks |
just j-pending | desk: sessions stuck at a native prompt and where to answer them |
just j-perm-answer id decision | human: answer a relayed permission ask (only if perm-relay.sh is wired in) |
just j-report status msg | verb: report done|blocked|note "<msg>" (done runs core/check.sh) |
just j-ship msg | verb: commit claimed paths only and push under a lock |
| site-* · this page | |
just site-build | site: generate partials/reference.html (jiva help + just --list), include partials, bundle + minify css/js into site/build/ |
just site-check | site: html validity, no third-party urls / inline js+css, CSP parity, drift vs CLI, a11y, ≤150 lines, < 400 KB |
just site-dev | site: build then serve site/build on 127.0.0.1:<random high port> (foreground; Ctrl-C stops) |
just site-verify url | site: read-only header/status/weight/SRI checks against a url, curl only (127.0.0.1 allows meta-only) |
| * · everything else | |
just card worker file | boss: size-check a task card (≤20 lines) then assign it — just card w1 path/card.md |
just check | budgets as tests: files ≤150 lines, notes ≤30, scripts parse, json valid |
just dash action="start" | runtime: tier-1 dashboard on 127.0.0.1:<random port> — start|stop|url |
just doctor mode="" | budgets as tests: boot payload, handoff/card sizes, state freshness, hooks, plugin mode; live adds the kill -9 self-heal test |
just down | runtime: kill the jiva tmux server (never touches your own tmux) |
just fleet | boss/desk: fleet at a glance — status, last 8 board lines + open asks |
just init | repo: git init, hooks path, skeleton dirs |
just keepalive action="start" | wsl: hidden Windows-side keepalive so tmux survives closing the terminal (run it yourself: ! just keepalive) |
just mine n="10" | growth: rank repeated Bash commands/bigrams from this repo's transcripts (recipe candidates) |
just plugin action="status" | plugin: local jiva plugin at user scope — status (exit 0 = installed) | mode (hooks source for up) | install | uninstall (ask the human first) |
just restart-watchdog | runtime: respawn the watchdog pane on this target's socket (after watchdog.sh edits; sessions untouched) |
just review sha="HEAD" | boss: review a worker commit — stat, then check, then doctor (only non-ok lines) |
just roster action="check" pack="default" | souls: name/color/avatar pack tooling — gen|check|show |
just sec | security: secret scan over full history |
just spike | runtime: re-test version-sensitive assumptions on scratch socket jiva-spike (run after claude updates) |
just status | runtime: one-line fleet status from .jiva/state.json |
just up workers="2" | runtime: watchdog + boss + N workers on the private tmux -L jiva server (soft cap 6, hard 12) |