All projects

Nerve

A platform that runs a 14-agent engineering org: a program checks everything every ten minutes, and one model cycle a day does the judging, recovers its own crashes and rewrites its own prompts.

2026–Present
Period
Private
Status
Internal tool
Built and run by me
Runnerevery 10 min, no model55 checksfindingconfirmed twiceissueone per fingerprintpicked up at the daily cycleDevSecurityMarketingOrchestratordaily, 06:30 UTCReport
01

The problem

I build and run my own products beside client work, so hours are the constraint. Every hour spent reviewing code is an hour not spent shipping, and every hour spent on marketing is an hour the security backlog grows. The usual answer is to hire. I wanted to test a different one: how much of a small engineering org can run on agents, unattended, before quality falls apart?

I had already built three internal tools circling this idea: a memory system, an agent runner, and an org layer. Each worked; none knew the others existed. Nerve consolidated them into one product — a platform that runs 14 AI agents across three departments (development, security, and marketing) with no human in the loop for routine work.

02

How it works

Everything runs on two clocks. A Windows scheduled task fires the check runner every ten minutes: Python, no model, done in seconds. Each tick reaps the agent sessions that have finished, runs the checks that are due, routes what changed into the issue tracker, and decides what to launch next. Once a day, on the 06:30 UTC tick, the runner opens the daily tier: a one-call canary proves the Claude login still works, a file-only pre-gate decides who is due, and the orchestrator cycle launches as a headless Claude Code session. That cycle wakes each department in turn: development agents review and verify each other's fixes before anything merges, security agents triage what the checks found, and marketing agents write content. A full day completes without me because the loop is built to be checked rather than trusted: every return is validated before it is kept, every merge passes review and CI, spend has a ceiling, and anything that touches a red line waits for my approval. My job is reading the output, not producing it.

Under the hood it is Python and FastAPI, with MCP as the wiring between agents and the tools they are allowed to touch. The engine's dashboard is the window into the org: a Checks page that lists every probe by cadence with its history, a Connections page that shows each login and token's state with the exact fix command and never the token itself, and the proposals, budget and memory pages for what the agents want to change, what they are spending, and what they carry between cycles.

03

Program detects change, a model judges it

The runner's inventory is a YAML file of fifty-five checks, each a Claude-free command with a cadence, an expectation and a route. Twenty-five run every tick: the live sites' status codes and security headers, certificate expiry, repository state, open pull requests, the Slack inbox, and the Claude, GitHub and engine logins. Twenty-nine run once a day: Search Console pulls, meta tags, npm and pip audits, a secret sweep, the merge-gate test suite, lint, the engine's own deploy, and the Slack, Vercel, Railway and phone-alert tokens. One runs weekly, the merge audit. Every result is a record on disk: a verdict, the parsed fields, what failed, what drifted from the last good run, and a fingerprint that names the failing expectations but not their values, so a status flapping between 502 and 503 is one finding, not two.

A change has to be confirmed before it counts: two consecutive runs with the same fingerprint, twenty minutes on the fast tier. A confirmed change files one issue, assigned to the check's agent at the check's severity, with the observed and expected values, the diff of the watched fields, the last good time and the exact command. While the issue is open, identical results only update it. Two clean runs close it with the recovery as evidence, except for the daily audits, which keep theirs open until an agent has looked. A check with no route never files; it alerts and shows. A probe that crashes routes to ops, never to the product agent. A broken checks file is refused whole and the last good one stays loaded, because a dropped check must never be silent.

The agents that used to run a fixed battery every cycle, the monitor, the web monitor, the code scanner and the SEO worker, now wake only on an assigned finding, with the check's last record in their prompt. The orchestrator cycle still runs once a day, launched by the runner as the daily tier's last session, and the runner reaps it: when the session ends, the next tick reads its result, validates the returned report and persists it, or writes a failure sentinel. On-demand sessions, where a confirmed finding launches its agent within the hour under a daily cap of eight, are the next migration step and are not switched on yet. Each step is one flag in the org's config, watched through a daily boundary before the next, and reversible by one command; at every step there has been exactly one scheduler, never two and never none.

0 min102030405060second fail: one issue, to its agentsecond clean run: resolvedfast tier: a change counts on its second consecutive run, twenty minutes; values are not in the fingerprint, so 502 then 503 is one findingdaily audits keep their issue open until an agent has looked

662 ticks since 15 October 2026: 25 checks every 10 minutes, 29 once a day, 1 once a week; 35 of them file an issue to an agent when they change. On-demand agent sessions are the next step and are not switched on yet. As of 20 October 2026.

04

Keeping agents honest

Autonomy without accountability is just noise, so the platform is built around checkpoints. Agent work surfaces on the proposals page where I can inspect it: a proposal that touches a red line waits for my approval, and the rest is applied and reversible. The budget page turns model spend into a gauge I check, not a number I discover on an invoice.

The strongest evidence the loop works: the security agents filed issues against Nerve itself — missing backend auth, unguarded subscription tiers, absent CSP headers. Those became a tracked hardening workstream. Nerve is private and internal today. It runs my org; that is the point.

05

The cycle that recovers itself

Nothing in the loop assumes the last cycle finished. The runner reaps every session on the tick after it ends, and step zero of every daily wake looks for the returns a crashed cycle left behind, validates them, persists them and sends an alert to my phone. A second check reads the session's own exit record, because the headless CLI exits clean even when a usage limit killed it halfway through. Who runs is decided before any model is called, by a script that reads only files; if that script errors it fails safe and dispatches everyone, because a wasted cycle costs minutes and a silently skipped one costs a day. The runner carries the same asymmetry: on-demand spending fails closed, the daily tier fails open with an alert.

Every return goes through a validator before it is kept: frontmatter, body caps, artifact paths that must exist, and a scan for closure claims, because an agent closes an issue by editing the tracker, never by saying so in prose. A rejected return gets a failure sentinel instead of a report, and nobody hand-edits it to pass. Readers run after writers: the council and the cycle reviewer dispatch in a second wave with a hashed manifest of the files they may quote. A dead-man alert runs hourly outside the loop and pages my phone when the runner's heartbeat is more than forty minutes old, and an engine guard, also hourly, restarts the memory engine when it is running code older than the deployed commit. The runner is a separate process from the engine on purpose: a monitor that shares its subject's failure domain is not a monitor.

06

The org that writes its own lessons

Every cycle ends with a scorecard: open issues, tests passing, lint, search clicks, open pull requests, how many lessons are live, how long my own queue has waited. Plain arithmetic, a closed schema, no model involved. The cycle reviewer runs the retro on it: judge every lesson whose deadline has passed against its own criterion, verified with evidence or failed with a reason; find the worst regression; draft at most one new lesson. Silence is a valid retro.

A lesson is a small JSON record with a closed schema: a signal (an issue id or a scorecard field), an observation that names a path, a hypothesis, a change at one layer (a prompt, a script, the org tree, the engine, or me) and a falsifiable criterion with a deadline. The guardrails are mechanical: five active at most, one proposal per retro, expiry in fourteen days, and a lesson nobody judges within a week fails on its own. Prompt-layer lessons are applied by the script as dated, cited sections appended to the agent's prompt, which is the only way a prompt changes without a human, and a failed lesson's section is reverted. Anything that touches a red line, schedules, budgets, what gets published, engine code, or the lesson machinery itself, waits for my approval, hash-checked against the file.

Wake06:30 UTC, by the runnerPre-gatefiles only, no modelDispatchtwo wavesValidateevery returnPersistsentinelsScoreclosed schemaRetroone lesson at mostlessons append to the prompts,verified or revertedstep 0 recoversorphaned returnsa rejected returngets a failure sentinel

40 lessons filed since July 2026: 22 verified, 12 failed and reverted, 5 expired, 1 waiting on me. 2,033 issues filed by the agents and the runner's checks, 1,824 resolved, as of 20 October 2026.

07 — Tradeoffs

Decisions I'd defend

A Claude-free runner every ten minutes and one model cycle a day, instead of event-driven agents or a cycle that dispatches everyone
Events are responsive, but an agent that wakes on every event has unpredictable cost and behaviour. A cycle that wakes everyone is predictable and wasteful: by October every daily cycle dispatched twelve or thirteen agents, and over thirty days the monitoring and manager agents ran about ninety times to file about eighteen issues, most of them re-checks. Since the runner took the clock the cycle has dispatched seven to ten. The runner splits the job. A program detects change on a ten-minute tick for nothing, and a model is woken only to judge what changed. The daily cycle keeps a known ceiling on spend, because the loop shares my own Claude subscription, and the pre-gate makes an idle wake cost nothing. The worst case for routine work is a day's wait, which an org of one can absorb.
One orchestrator (Claude Code) and one scheduler rather than 14 independent agent loops
Central orchestration is a single point of failure, but also a single point of observability. Every action flows through one engine where budgets, memory, and review gates are enforced consistently. Debugging one loop beats debugging fourteen, and the migration to the runner kept the rule: at every step there has been exactly one scheduler.
Consolidating three tools into one product instead of keeping them composable
Separate tools sound cleaner, but I was maintaining three deployments and three versions of the truth. Merging memory, execution, and org structure means agents share state by default — what one writes in a cycle is what another reads in the next.
08 — Outcome

Where it stands

  • 14 agents across development, security, and marketing, running unattended since April 2026: eight cycles a day until September, one a day since, and launched by the runner since 18 October
  • A check runner on a ten-minute tick since 15 October 2026: 55 Claude-free checks across three products, one issue per confirmed change, the daily cycle as its last step
  • Replaced three separate internal tools with one platform
  • Security agents surfaced their own hardening backlog — backend auth, subscription tier guards, CSP headers — as tracked issues
  • Every change the org makes to its own prompts arrives as a lesson with a falsifiable criterion, and is verified or reverted
  • 2,033 issues filed and 1,824 closed in the tracker since April 2026, each closure recorded there rather than claimed in prose; 40 lessons filed since July, 22 verified and 12 reverted
09 — Hindsight

What I'd do differently

I would design the security posture in from day one instead of letting the agents find the gaps. Watching the security department flag missing auth and CSP headers on its own platform was validating, but auth should never be a retrofit. More broadly, I would be slower to add agents and faster to add constraints. The hard engineering in Nerve turned out to be the guardrails — cycles, budgets, review gates, the validator, the lessons ledger — not the agents themselves, and I under-invested in them early. The ledger arrived in July, three months in; it should have been there from the first cycle. And the runner should have come first: the instrument layer was Claude-free from the start, and it took six months to notice that a program could run it on a timer and wake a model only when something changed.