An AI operating system whose most important feature is what it refuses to do.
Seventeen specialised agents run research, a job-search pipeline, investment research, study support and security monitoring on one Mac, unattended. Nothing is sent, deleted, paid or traded without a human tapping approve, every action is logged to a hash-chained ledger, and the whole thing runs with zero pay-per-token API spend.
Specified, governed and operated by an undergraduate Commerce/Law student. Code written by AI coding agents to those specifications, reviewed change by change.
Runs on its own when asked. Search, status, describe the screen on request.
Reversible and local. Runs on a voice command, logged and shown on the overlay as it happens.
Anything that leaves the machine. A fresh human confirmation every time; no standing authorisation exists.
Every action goes through one audited gateway, jarvis-do: registry lookup, tier check, mechanism, ledger entry. No agent or script calls the operating system directly. Deleting files, moving money and placing trades are not registered at all.
Every number with where it was counted
| Count | What it is | Counted from |
|---|---|---|
| 17 | specialised agents, each scoped to the minimum tools it needs | agent definition files |
| 37 | scheduled jobs that run the system unattended (macOS launchd) | LaunchAgents |
| 43 | registered computer-control actions: 15 read, 26 reversible, 2 human-gated | action registry |
| 19 | LLM providers in the failover ladder, cloud to local, ending in deterministic templates | router config |
| 17 | deterministic hook scripts that gate, meter, audit and kill agent tool calls | hooks directory |
| 33 | architecture decision records | ADR log |
| 30 | incident post-mortems, including deliberate chaos and planted-bug drills | incident log |
| 25 / 25 | agent-behaviour evaluation fixtures passing live | eval run, 19 Jul 2026 |
| 9,566 | job advertisements ingested by the Career Hub from 14 sources | jobs.db |
| 1,695 | automated tests in the Career Hub alone, across 92 files | pytest --collect-only |
| ~700 | commits across four repositories since 9 Jul 2026 | git log |
| $0 | pay-per-token API spend: one subscription, free tiers and local models | ADR-016, ADR-032 |
Assistants answer questions. This one does the standing work.
Read the news at 6am and write the brief. Find and score the day's job ads. Turn a lecture transcript into flashcards. Watch the stack's health. Research a stock and write the memo. Take a spoken instruction from across the room. All without being watched, and, the harder problem, safe to leave running.
The design premise from the original brief: the point is not a smarter base model; it is to get far more out of the models you already pay for, through decomposition, delegation, memory, verification, parallelism and cost-aware routing, inside an interface you control.
If it is not written down, it did not happen as far as the next agent is concerned.
Hooks run deterministically before every tool call. They can deny or meter; they can never grant. Nothing runs with permission-bypass flags.
After two fabricated "done" events, only artefacts count: ledger rows, audit lines, transcripts on disk.
One machine, four surfaces, one set of rails
Every agent tool call passes through 17 deterministic hooks before it runs.
kill switchbudget gatespawns debited before they runtool-call gate500 per sessionsecrets and workspace guardsprotected-files guardrelay checkHuman gates: send, delete, pay, trade. A fresh confirmation each time.
Seventeen hooks that only tighten
Deterministic scripts run around every agent tool call. They are the enforcement layer; prompts are not.
- Kill switch. Stops every agent on a single flag.
- Budget gate. Debits every agent spawn into a ledger before it runs and denies at the cap: 15 per session, 4 concurrent, depth 3, 5 children per task. Nested spawns share the session budget (proven live).
- Tool-call gate. 500 calls per session; past the cap every call becomes an "ask": a conscious click-through when interactive, a cold stop for a headless runaway.
- Secrets and workspace guards. Deny reads of key files and .git, and writes outside the workspace.
- Protected-files guard. No agent can edit the operating rules it runs under.
- Relay check. Flags any division lead who cites a health check the ledger shows never ran.
Zero spend, by invariant
One subscription, free-tier providers and a local model. The router walks up to 19 providers per call and, when every model is down, renders a deterministic template rather than going silent. A later proposal to add a paid rung was withdrawn and the invariant restored.
Sensitive data goes only to the subscription model or the local model. The one exception is an opt-in, per-call redacted path to two providers that contractually retain nothing, adopted after the research showed redaction is a leak-reducer rather than a blocker, with the residual risk written into the decision record.
An audit trail you can argue with
- Hash-chained activity log in Postgres: every action, in order, tamper-evident.
- 33 decision records, from typography to "no paid rung".
- 30 incident post-mortems, including a planted-bug drill, a credentials-wipe outage, fabricated completion events and a chaos test that killed the workflow engine on purpose.
- A lessons log fed mechanically by a hook from every agent's result contract, reviewed weekly, promoted or deleted.
A delegation tree with mechanical bounds
One protocol at every level. A parent receives a task with a budget and a deadline, decides whether to do it or decompose it, and each child returns a structured result contract: output, cost, status, notes, lessons learned. The parent verifies the result with a separate reviewer, aggregates, and returns up.
Person
└── Chairman main thread only, never a subagent
├── Minerva research & analysis lead → Scout, Ledger, Herald
├── Daedalus product & building lead → Forge, Muse
├── Aegis security, ops & QC lead → Warden, Fix, Sentinel, Archivist
└── Arbiter standing reviewer; review only, never fixes
Corporate titles are persona labels, not tree levels. Division leads may spawn only their own workers plus the Arbiter; cross-division, lead-to-lead and self-recursion all deny. The observer (Sentinel) stays independent of the fixers so a lead cannot launder a fix through its mouth (ADR-027).
Evaluation
Twenty-five behaviour fixtures probe the tree live: does a lead decompose or do the work itself; does it relay a health check verbatim; does it refuse to launder a fix. The full set passed 25 of 25 after two rulings: transient failures retry, and a required-field miss is a NEEDS_REVIEW verdict, not a pass.
Bounds, and how each one is actually enforced
| Bound | Value | Enforcement |
|---|---|---|
| max depth | 3 | workers are not given the spawn tool; the budget gate also denies any spawn whose caller is a worker |
| concurrent agents | 4 | a stop hook marks ledger rows complete; the gate counts open rows per session and denies at the cap; rows older than 60 minutes age out so a dead parent cannot brick spawning |
| children per task | 5 | per-caller ledger count, in session |
| agents per goal | 15 / session | every spawn debited into the ledger before it runs; tree-wide, so nested spawns share the budget |
| tool calls | 500 / session | past the cap every call answers "ask": a click-through when interactive, a cold stop for a headless runaway |
Nothing spoken leaves the machine
- Always-on wake word (openWakeWord on ONNX), local speech-to-text (whisper.cpp) and local text-to-speech (Kokoro).
- A speech-aware overlay with a four-state machine and a media guard that pauses or ducks whatever is playing, re-entrantly, with a 120-second watchdog so a crash can never leave the room muted.
- Screen questions. "What's on my screen" captures, OCRs and describes the display, on request and only on request.
- A local HUD with twelve panels behind token, origin and rate-limit middleware; an ambient read-only view doubles as the wallpaper.
Benchmarked, not deployed
A newer speech model was benchmarked against the incumbent and deliberately not deployed. The decision record shows the numbers, which is the point: a decision you can re-open later is worth more than a faster model you cannot explain.
Gated actions can be approved from a phone. The live proof produced a lesson worth more than the feature: three consecutive approvals were tapped, including two whose text said "tap deny". Remote approval is a liveness gate, not a review gate, so approval summaries now lead with the consequence, not the mechanism.
A job-search pipeline with a strict honesty model
The largest subsystem, and the one closest to analyst and consulting work: a product-owned data pipeline that reads the Sydney market every day and drafts, but never sends.
The honesty model
- The profile file is the only source the drafting pipeline may draw facts from, and every drafting prompt carries a no-fabrication contract. A missing fact stays missing.
- Four independent submit guards: a halt flag, an empty vendor allowlist, an evidence gate that measures form-fill quality per vendor, and payload-hash pinning. The system has never submitted an application and cannot.
- Content rules live in code and tests, not only in prompts: dash normalisation on every draft, and a seniority guard measured on the pool (40 of 52 senior-titled roles had slipped past the old pattern and sat above the internships).
- Four closing signals so dead roles stop scoring, including a link checker that treats a rate-limit response as "try again", after one vendor was made to look 95% dead by a 429.
9,566 ads · 7,182 scored · 166 firms · 21 pipeline modules · 11 fetchers · 26 agent modules · 38k lines of Python · 1,695 tests · an MCP server for agents
What two reviews found
Scored 76 then 79 out of 100. Six defects were invisible in the source and only visible in the data:
- an absent employer field had merged four different employers' ads into one identity;
- a field documented as shipped existed nowhere;
- the top-scoring role was an unpaid internship;
- one source regenerated its URLs per fetch, so a URL was never an identity there;
- a vendor's "48% clean" fill rate had been measured the day before its own fix landed (fresh benchmark: 15 of 15);
- cached scores went stale after profile edits with no signal; fixed by hashing profile content into every score row.
The rule that came out of it: a code fix to anything cached or exported is only half a fix; backfill the stored copies. And review the data, not just the code.
Promoted from the log, each with the evidence that earned it
Two fabricated "stop" events claimed pending gates had passed and urged the next phase, with nothing in the ledger, the audit log or the transcripts. Trust artefacts only.
The human pattern is green-button-by-default. Approval requests now lead with the consequence; anything that needs real review does not go through a phone.
An agent that returns a "done" contract it could not have earned yet is reporting intent as fact.
"Subagents cannot reach the keychain" turned out to be an outage wearing a rail-shaped costume. The rule was amended, with the evidence, rather than left standing.
The naive reading of the hub's score distributions was wrong five times running.
A commit collision from a second concurrent session looked exactly like a bug.
Specification first, rulings not vibes
Every stage began as a written brief: the goal, the constraints, the out-of-scope boundaries, the verification required before the next phase. The JARVIS 7 brief runs to 23 sections and opens with "re-verify the fast-moving platform facts and record what you found versus what this document assumed" before any code.
AI coding agents wrote the code. Claude Code agents implemented each feature against the brief. I reviewed every change, ran the tests and the eval fixtures, and recorded the decision. A claim that could not be verified from an artefact was not accepted. This is stated plainly because it is the actual division of labour, and because directing, verifying and governing agent-written systems is the skill the project demonstrates.
When the brief and reality disagreed, a ruling settled it and was logged: no API keys, no permission-bypass flags, no paid rung, sensitive data stays local. Later proposals that conflicted with a ruling were rejected and the rejection recorded.
Self-improvement is propose-then-approve. An autonomous "engineering lead" run produced ten improvements on an unmerged branch pair, every behaviour change behind a default-off flag, with a restore checklist and a per-flag enable order for the human to work through.