> bada: one orchestrator for every agent we pay for

A proposal for turning bada.im into a threaded, always-working orchestrator. It hands coding work to Claude Code, Codex, Kimi, Venice-backed agents and local Ollama models, keeps working through a backlog on its own, and never spends the last of any plan, so there is always room left for Jay to work by hand.

Written 16 October 2026. Nothing on this page is built, installed or keyed. Venice facts were read from Venice's own docs and model page that day (sources V1 to V8 at the end); model names and prices change monthly, so check them again before relying on them. Facts about this machine were read from it, or from the handoff README.

1. What "it" means here

Our reading of the request: "it" is the setup analysed in A second brain on one laptop, as revised in its section 7. In short:

Two more readings, both inferred rather than confirmed. "Like Claude Code with threads" means the way this project already works: each request becomes a thread with its own agent, its own checklist and its own result, and a coordinator watches them all. "Like dot" means the Codex agent that signs itself "dot/Codex" on our agent collaboration page, which picks up queued goals and keeps going without being prompted each time. If either reading is wrong, sections 4 and 5 change; the rest doesn't.

This page answers three things: how to get a Claude Code or Codex style coding agent running on Venice (section 2), where Hermes fits (section 3), and how bada would orchestrate all of it with a reserve left on every plan (sections 4 to 8).

2. A coding agent on Venice: the options

Venice serves an OpenAI-compatible API at https://api.venice.ai/api/v1, so any agent harness that accepts a custom OpenAI-style endpoint can use it. V1 Venice's own integration list names Claude Code, Codex CLI, OpenCode, Aider, Cline, Cursor, Kilo Code and Hermes Agent. V2 It does not document an Anthropic-format endpoint, which matters for Claude Code.

HarnessOpen?How it reaches VeniceFit for us
Codex CLI, a second profileApache 2.0 A [model_providers.venice] block in ~/.codex/config.toml with wire_api = "responses", selected by a profile. V3 Already installed (0.162.1). Same harness, same AGENTS.md, same telemetry; only the model changes. The cheapest experiment by far.
OpenCodeMIT Venice as a custom provider in opencode.json, models named venice/<id>. V4 The best open, vendor-neutral fallback: it speaks to Venice, Ollama, Anthropic and OpenAI alike. Not installed.
Hermes Agent (Nous Research)MIT Custom endpoint in ~/.hermes/config.yaml, key from VENICE_API_KEY. V5 The most "dot-like" of the lot: its own cron scheduler, memory, subagents and chat gateways. V6 Also the biggest and most opinionated; see section 3.
AiderApache 2.0OpenAI-compatible settings. Good git-native pair programmer for single changes; less suited to long unattended tasks.
Claude Code via claude-code-routerClaude Code no; the router is open source A local proxy translates Claude Code's Anthropic requests into Venice's OpenAI format. V7 Works, but it needs Node (not installed), puts a third-party proxy between Claude Code and every request, and Claude models through Venice are "anonymized" proxies billed per token. We already have Claude Code on its own subscription. Not recommended.

Which Venice models for code

Venice splits its catalog into "private" models it runs itself without logging prompts, and "anonymized" ones it forwards to OpenAI, Anthropic and others, who then see Venice as the customer. V5 V8 For code we'd use the private, open-weight ones, which is also what makes Venice worth having next to the subscriptions we already pay for:

Model (Venice id)Privacy$ in / out per 1MRole
Qwen3 Coder 480B Turbo (qwen3-coder-480b-a35b-instruct-turbo)Private0.35 / 1.50Bulk coding, cheap enough to leave running.
Kimi K2.7 Code (kimi-k2-7-code)Private0.75 / 3.50Harder changes; also a second route to Kimi when the Kimi plan is low.
GLM 5.3 (z-ai-glm-5-3)Private, 1M context1.75 / 5.50Long-context reading of a whole repository.
DeepSeek V4 Pro (deepseek-v4-pro)Private, 1M context1.65 / 3.30Second opinion and review.
Hermes 3 Llama 3.1 405B (hermes-3-llama-3-1-405b)Private1.10 / 3.00Writing and general tasks, not coding (section 3).

Prices as listed on venice.ai/models on 16 October 2026. V8 The ids differ between Venice's own pages, so the adapter should read them from GET /models rather than hard-coding them.

Our pick: start with a venice profile in the Codex CLI we already run, pointed at Qwen3 Coder, and add OpenCode as the open harness once that works. Two harnesses on one endpoint lets us tell a weak model apart from a weak harness. One change from Venice's own guide: it puts the key straight into config.toml as experimental_bearer_token. V3 Our rules (AGENTS.md section 13) don't allow that, so the profile reads it from the environment instead:

# ~/.codex/config.toml (proposed, not applied)
[model_providers.venice]
name = "Venice"
base_url = "https://api.venice.ai/api/v1/"
env_key = "VENICE_API_KEY"      # Jay stores the key; nothing is written here
wire_api = "responses"

[profiles.venice]
model_provider = "venice"
model = "qwen3-coder-480b-a35b-instruct-turbo"

# use:  codex --profile venice exec "…"

3. Hermes: the models and the agent

"Hermes" names two different things, and both are relevant.

Hermes the model family

Venice lists one Hermes model, Hermes 3 Llama 3.1 405B, a 2024 general-purpose model. V8 The newer Hermes 4 (70B and 405B) is not on Venice's API; there is an open user request asking Venice to add it. Hermes 4 is served by Nous Portal and OpenRouter. H1 H2 Neither is tuned for agentic coding the way Qwen3 Coder, Kimi K2.7 Code or GLM are, so we'd use Hermes for writing, summarising and general reasoning, and keep it out of the coding route unless a measurement on our own tasks says otherwise.

Hermes Agent, the harness

Hermes Agent is Nous Research's open-source (MIT) agent: a CLI with a built-in cron scheduler that runs tasks written in plain language, agent-curated memory with full-text search of past sessions, skills it writes for itself after hard tasks, parallel subagents, and one gateway process for Telegram, Discord, Slack, Signal and email. It can also serve itself as an OpenAI-compatible endpoint. V6 H3 It speaks to any /v1/chat/completions server, so Venice, Ollama or OpenRouter all work.

It is closer to "dot" than anything else here, which raises the obvious question: why not just run Hermes as the orchestrator?

Hermes Agent as the orchestratorbada as the orchestrator, Hermes as one worker
Working in days: install, point at Venice, write cron tasks.Weeks: we build the scheduler, ledger and UI.
Knows nothing about our Claude, ChatGPT and Kimi subscription windows, so it can't keep a reserve on them.The reserve is the core feature (section 6).
State lives in its own memory and skill files, which it rewrites itself.State lives in Postgres and git, where we can read, test and export it.
Python, with a curl | bash installer, outside our Ruby-first rule.Ruby and Rails, per AGENTS.md sections 5 and 9.
Chat gateways come built in.Threads are web pages on bada.im; chat can come later.

Our pick: Hermes Agent is a worker behind an adapter, the same as Codex or Kimi, so we can try its memory and skills on real tasks without handing it the keys to every plan. If it turns out to do the orchestration better than our own code, swapping the adapter is cheap. Read its installer before running it, and run it with the local terminal backend in a worktree, never with access to ~/.config/environment.d.

4. What bada would be

bada is a Rails app on this laptop. A thread is one goal written by Jay, with its conversation, its checklist and its outputs, like a thread in this project. Each thread breaks into tasks, and each task is carried out as a run: one agent CLI, in one git worktree, with a time and token limit. A scheduler loop keeps picking the next task whenever a plan has room, so work continues while Jay is away; that is the "dot" half. The public bada.im pages stay static; the app sits behind sign-in at a path on the site.

bada's parts: threads feed a scheduler, which checks the budget ledger and asks a decision model, then hands runs to agent adapters, all reporting to observability. Threads (web UI)goals, messages,checklists, approvals Standing backloglint the sites, follow-ups,recurring jobs SchedulerSolid Queue jobs, one loop1. budget gate (rules)2. route (decision model) Budget ledgerplans, windows, reserves Decision adapterLaya local · Jev hosted Agent adapters (one class each) Claude Code · claude -p, stream-json Codex · codex exec --json (ChatGPT plan) Codex · --profile venice (Venice credit) Kimi · kimi -p, stream-json OpenCode / Hermes Agent · Venice Ollama · qwen3:4b, local chores each run: own git worktree, time limit, token limit, transcript Observability (OTel → Grafana)tokens, cost, errors per provider
Every arrow out of the scheduler passes the budget gate first. The decision model only chooses among runs the budget already allows.

How a thread runs

  1. Jay writes a goal in a new thread, or the standing backlog adds one (for example, the weekly stale-page check from the second-brain plan).
  2. A planning run (a cheap model by default) splits it into tasks with acceptance checks, per AGENTS.md section 4, and posts them as the thread's checklist.
  3. The scheduler picks a ready task, asks the budget ledger which plans can afford it, asks the decision model which of those should take it, and starts a run.
  4. The run works in its own worktree and streams its transcript into the thread. When it finishes, a different provider reviews the diff, because the same generation is never the only judge of its own work (AGENTS.md section 17).
  5. Anything that leaves the machine or can't be undone (publishing a page, pushing, spending past a cap, sending a message) stops at an approval in the thread. Everything else merges into a branch for Jay to look at.
  6. The run may propose follow-up tasks. They join the backlog as proposals; only Jay's standing rules or a tap make them ready.

5. The data model

Data first (AGENTS.md section 7). Every table carries organization_id and rooftop_id from the first migration, with PostgreSQL row-level security, as section 15 requires; today there is one organization and one rooftop.

TableHolds
threadsGoal, status (open, working, waiting on Jay, done), owner, standing or one-off.
messagesThe thread conversation: Jay's words, agent replies, approvals.
tasksOne unit of work: acceptance checks, state (proposed → ready → running → review → done, or blocked), estimate, repository and base commit.
runsOne attempt at a task: provider, model, worktree, start and end, exit, transcript location, tokens in and out, cost.
providersEach adapter and its models: Claude Code, Codex, Codex-on-Venice, Kimi, OpenCode, Hermes Agent, Ollama.
plansWhat we pay for and how it's limited: window type (rolling hours, weekly, daily epoch, monthly money), limit, reserve, and how remaining quota is read.
usage_eventsAppend-only: every run's usage, and every reading of a plan's remaining quota, with its source.
decisionsEvery routing or "is it done" question asked of the decision model, its options, answer, probability, and the outcome we saw later.

Transcripts and diffs stay as files in git worktrees and a data folder named in config; the database points at them. Everything exports as SQL dumps and plain files.

6. Keeping tokens in reserve on every plan

This is the part no off-the-shelf harness does for us, and the reason bada is worth building. The everyday habits behind it, done by hand today, are in Token maxxing.

The rule

For each plan, unattended work may only spend up to limit − reserve in the current window. The reserve belongs to Jay. A run starts only if its estimated cost, at the 90th percentile of similar past runs, fits under what's left. If no plan has room, the task waits; it never borrows from a reserve. Interactive use by Jay counts against the same ledger but is never blocked by it.

This is deterministic Ruby, not a model's judgment. The decision model picks among the plans the rule allows and can't widen the list.

What each plan tells us, and what it doesn't

PlanWindowHow we'd read remaining quotaDefault reserve
Claude (Claude Code subscription)Rolling hours plus weekly Our own count of tokens per run from claude -p --output-format stream-json and the OTel data it already sends. The remaining allowance isn't something we've confirmed Claude Code exposes to scripts, so the limit is set by Jay and corrected whenever a run reports "limit reached".30%
ChatGPT (Codex)Rolling hours plus weekly codex exec --json emits token counts per turn, and a rate-limit block when the server sends one. In our latest local session it was empty, so we fall back to our own count, as for Claude.30%
KimiPlan quotaOur own count from kimi -p --output-format stream-json; limit set by Jay.30%
VeniceDaily epoch (DIEM) or a money balance (USD) The best of the lot: GET /api_keys/rate_limits returns USD, DIEM and bundled-credit balances, per-model limits and when the next epoch begins. V9 One DIEM is $1 of compute a day; USD credits don't expire. V1025% of the day
Ollama (local)None, but one 4 GB GPUNot money but time: one run at a time, and paused while the radio app or Whisper needs the GPU.n/a
Jev (TypeSafe)Pay per callMonthly money cap set by Jay; Laya on this machine is the default, so Jev calls should be rare.monthly cap

The reserve percentages are starting guesses for Jay to change, not measurements. Plan names and limits aren't quoted because they change; the plans table holds whatever is true this month.

Routing with the reserve in mind

Where Laya or Jev helps

Typed questions only, each logged in decisions so we can score them later (AGENTS.md section 17): choice of which allowed provider takes a task, condition for whether a run's result meets its acceptance checks well enough to send to review, and score for how likely a task is to need a strong model. A wrong answer costs a retry, never a reserve or an unapproved release. Laya runs here by default; Jev sits behind the same adapter and can be compared on the same logged questions once Jay's key is stored.

7. How it breaks, and what holds

bada.im is an adversarial research site, so the proposal has to survive its own threat model.

FailureWhat stops it
A web page or file an agent reads tells it to push, publish or exfiltrate (prompt injection). Runs get only their own worktree, no secrets beyond their own provider key, and no push or publish rights. Those actions happen only in bada, after an approval in the thread.
An unattended agent runs with its "never ask" mode on and deletes or rewrites things. Each harness's sandbox stays on; work is in a disposable worktree; the merge into a branch is a separate, reviewed step.
A loop of follow-up tasks burns a whole plan overnight. Reserves, a per-thread token cap, a per-day cap on new tasks, and follow-ups start as proposals, not ready work.
A model decides its own work is finished.A different provider reviews, and acceptance checks are commands that pass or fail.
A provider goes away or changes prices.Every provider is one adapter class and one row in plans (AGENTS.md section 11).
A key leaks into a transcript or a page.Keys only through Secrets.fetch; transcripts are scanned for secret patterns before they are stored or shown.
The decision model is fooled into routing badly.It only chooses among options the budget gate allowed, and its choices are logged and scored.

8. Following the ruby.im standards

Rule (AGENTS.md)How bada meets it
5, 9: Ruby first, Rails for a real app with a databaseRails with its defaults: Postgres, Solid Queue for the scheduler, Hotwire for live thread pages. One app in apps/bada/.
11: open, self-hosted, two swappable providersSeven agent adapters, two decision adapters (Laya, Jev), Venice reachable through two harnesses. Data in Postgres and git.
12: observabilitybada-web and bada-worker registered in observability/services.yml; every run is a span with provider, model, tokens, cost and outcome.
13: secretsVENICE_API_KEY and TYPESAFE_API_KEY stored by Jay, read with Secrets.fetch; names listed in apps/bada/.env.example.
14: twelve-factorPort from PORT on 127.0.0.1, config from env, logs to stdout, one systemd unit per process type, safe to restart mid-run (runs resume or are marked failed).
15: identityTenant columns and row-level security from the first migration; sign-in through ngrok's Google sign-in today, OIDC to our broker when it exists.
17: testingMinitest. The budget gate, reserve maths and state transitions get hand-worked examples; adapters are tested against recorded CLI output.

9. Build plan, if approved

Each step has a check, and each is useful on its own if we stop there.

  1. Venice in Codex. Jay stores VENICE_API_KEY; we add the profile from section 2. Check: codex --profile venice exec fixes a seeded bug in a scratch repository, and the run shows up in Grafana.
  2. A ledger before a scheduler. A Ruby script that reads usage from all agents and Venice's balance into Postgres and prints remaining room per plan. Check: its numbers match each tool's own /status or dashboard within a stated margin for one week.
  3. The budget gate. Minitest cases worked by hand: a run that would cross a reserve is refused, one that fits starts, a "limit reached" marks the plan full until reset. Check: those tests fail against a gate that ignores reserves.
  4. Threads and runs. The Rails app with one adapter (Codex), worktrees and a thread page. Check: a goal written in the browser ends as a reviewed branch.
  5. The other adapters, one at a time: Claude Code, Kimi, Ollama, OpenCode, then Hermes Agent as a trial. Check: the same task through each yields a transcript, usage and a diff.
  6. Continuous work. The standing backlog and scheduler loop, starting with the site lint job. Check: it runs a night unattended and every plan still shows at least its reserve in the morning.
  7. Decision routing. Laya behind the decision adapter; Jev compared on the same logged questions. Check: on 50 held-out tasks, routing by the model costs less than "always the strongest" with no drop in review pass rate.

Missing on this machine for this plan: Postgres and Node (Node only for claude-code-router, which we don't recommend). OpenCode and Hermes Agent install as user-local tools. No Venice key is stored yet.

10. Decisions for Jay

Sources

  1. V1. Venice API docs: overview.
  2. V2. Venice: AI agents and coding tools.
  3. V3. Venice: Codex CLI guide.
  4. V4. Venice: OpenCode guide.
  5. V5. Venice: Hermes Agent guide.
  6. V6. NousResearch/hermes-agent on GitHub (MIT).
  7. V7. Venice: Claude Code guide (via claude-code-router).
  8. V8. Venice model library, read 16 October 2026.
  9. V9. Venice API: rate limits and balances.
  10. V10. Venice: pricing and How do I access the API?
  11. H1. Venice feedback: "Add Hermes 4 to the API".
  12. H2. Cline docs: Nous Research provider (Hermes 4 70B and 405B).
  13. H3. Hermes Agent docs: API server.

Provided as is, for information only, with no warranty and no liability. Not legal or professional advice. Security and radio material is for authorized, lawful use only. Full disclaimer.

Visits are logged on our own server: IP address, browser and device details, and pages viewed. We use them to understand traffic and spot attacks, and never share or sell them.