fullbench-opencode
v0.2.0
Published
Opencode-first orchestration for durable teams of specialist agents.
Maintainers
Readme
FullBench
FullBench forms and coordinates durable teams of specialist agents. A Chief Agent Officer selects the smallest useful team for an outcome, while a deterministic kernel owns authority, task state, budgets, checkpoints and recovery.
Resident builder service
Long-running builds are owned by one per-user fullbenchd service, not by the
terminal or coding UI that started them. On macOS, fullbench service --action
install writes private configuration and bootstraps the LaunchAgent; start,
status, stop and uninstall map only to launchd. Run controls are separate:
run-register, run-attach, run-subscribe, run-detach, run-status,
run-inspect, run-pause, run-resume and run-stop use the authenticated
mode-0600 Unix socket. Event subscription is ordered and reconnects from an exact
--after-sequence cursor. Registration includes
the run's own --db, so one resident service can supervise separate projects
without combining their ledgers.
The service passes only a private config-file path in the process list. Provider
configuration and task envelopes are stored in mode-0600 files, never argv or
the daemon environment. Adapter workers are replaceable processes; only the
daemon owns coordinator epochs, task leases and accepted state transitions.
Service installation requires --codex-path and --codex-auth. The installer
resolves the executable to an absolute real path, records its SHA-256 identity
in the private service config, and records the authentication file as a private
locator. Every Codex CAO and specialist dispatch re-verifies that executable;
project configuration and PATH cannot replace it.
This repository is deliberately independent of NuOS Builder. The v0.1 canary contains a run kernel, dynamic team plans, provider-neutral JSON-command adapters and a visible CLI roster. It has no vector database or fixed role pipeline.
pnpm canary:autonomous is the mandatory offline release proof. It exercises the same resident-daemon lifecycle used in production, but uses only local fixtures and a loopback browser; it makes no paid model calls. A real-provider canary is intentionally deferred until its certified provider configuration and spend controls are independently reviewed.
Current principles
- Capabilities, not inherited roles.
- Deep modules own stable operational intelligence; agents are formed dynamically around them.
- Exact run state, not chat history.
- One parent model: every chat inherits the operator's selected runtime model. Reasoning effort is tiered automatically — low for procedural work, medium for ordinary verification, high for architecture, diagnosis, privacy/security judgment and adversarial challenge.
- Every chat is a budgeted resource: bounded context in, reported token usage out, refusal before overspend.
- Reversible local work proceeds autonomously inside a run grant.
- Destructive actions, release, live data, credentials and additional spend remain explicit boundaries.
- Semantic search may enrich context later; it can never own operational truth.
Every run receives durable standing permission for reversible local reads, edits, tests and non-sensitive local browser-test prompts. FullBench does not interrupt the operator again for those actions. Coding-harness use by the agents is not charged against the run's external API ceiling. The ceiling applies to paid API calls made by the software or tests being built. Destructive operations, credentials, live personal data, external communication, release/deploy and external API spend above the run ceiling are not in the default grant.
An autonomous run is owned by a durable supervisor lease rather than by a chat message. One explicit controller derives every legal next action from FullBench's SQLite ledger. There is no second graph checkpoint, recursion limit or turn budget: CAO proposals become work only after the deterministic controller admits them, and completion is possible only from the accepted ledger state. If a controller process disappears, a replacement derives the same next action from that ledger without replaying an admitted team plan. FullBench reports an agent as working only when its current attempt and lease, participant, operating-system process identity and daemon coordinator epoch all agree. Process inspection is three-state: a confirmed live identity can renew, a confirmed dead or mismatched identity can recover, and an inspection fault is shown as uncertain and retried without creating a second attempt. Direct CLI reads and mutations are rejected while the resident daemon owns the run, preventing a second control path.
Browser verification is a first-class planned capability. It is admitted only when FullBench has a certified loopback-contained Chrome executable with a host certificate; otherwise the daemon raises one deterministic blocker before leasing the task. Browser completion requires host-ingested screenshot evidence, fresh assertions and no browser-console errors.
Every mutation also receives a separate implementation-review task. The authoring agent cannot approve its own work. Risk-bearing modules automatically route that review to frontier judgment; routine modules use the economical execution route. Workspace and dependency preparation happen before participant creation, so an infrastructure defect stops with zero invented recovery agents.
NuOS Builder is outside the FullBench trust boundary. Adapter configuration rejects its runtime/hooks and generic agent environments do not inherit its state or backend credentials. Supabase and Trigger work uses durable, target-pinned non-production grants: routine additive development migrations and preview work can proceed for the life of a run, while production and destructive operations are absent from the contract. See docs/authority-and-isolation.md.
Operator reports are always written in plain English. They answer whichever questions matter at that moment: what needs doing, what done looks like, what has been done, whether the operator needs to do anything, and what happens next. They do not mechanically include every heading. Internal routes, leases, model labels and protocol codes remain in the optional technical view.
Install into a product
Requires Node.js 24 or newer.
npm install --save-dev fullbench
npx fullbench initThis safely adds `.fullbench/` to the product's ignore rules, creates the canonical `docs/fullbench/` structure and writes a starter provider binding. Running it again is idempotent and never overwrites an existing config or build document. FullBench's own repository remains reusable and contains no product plans or run state.
The product folder does not need to be a Git repository, and it does not need an existing commit, to initialise or run the planning flow. Git is required only when a later code-changing task needs FullBench's isolated worktree.
The bare npm package name `fullbench` was unclaimed when checked on 28 August 2026. Publication still requires the normal npm account and release process.
Try the kernel
fullbench init also installs opencode slash commands into the product, so the
whole flow is short commands in the coding session:
/fb-plan <objective>— create the run and produce the walkthrough blueprint/fb-accept <digest>— accept the reviewed blueprint by its exact digest/fb-build [slice]— start the next slice from the accepted plan/fb-run— orchestrate the agent team on the latest build run/fb-status— plain-English status including what the agent chats cost/fb-brief— the exact run brief the CAO sees/fb-resume— resume a paused run from the ledger
The commands wrap the same deterministic CLI: they resolve the latest ledger and run id, and any argument you pass overrides the run id. Authority stays in the SQLite ledger, never in the chat.
pnpm verify
node src/cli.mjs run-init \
--db .fullbench/run.sqlite \
--objective "Create the first FullBench demonstration" \
--base-revision local \
--max-cost-micros 5000000 \
--max-calls 100The command returns a run ID. Use it to add work and inspect the deterministic brief:
node src/cli.mjs task-add --db .fullbench/run.sqlite --run RUN_ID \
--title "Implement the CLI" --capability implementation
node src/cli.mjs brief --db .fullbench/run.sqlite --run RUN_IDPlan before building
FullBench planning is one guided flow, not a chain of slash commands. The CAO may
form whatever temporary research, UX, architecture, privacy or domain team the
idea needs, but the durable outcome is one PlanningBlueprint@1.
The blueprint explains in plain English:
- what is being built, who it is for and the problem it solves;
- the intended journeys, surfaces and structured UI mockups;
- the architecture, modules, data/privacy rules, integrations and risks; and
- the ordered delivery slices and how each will be validated.
Install and render the proposed blueprint:
node src/cli.mjs plan-install --db .fullbench/run.sqlite --run RUN_ID \
--file planning-blueprint.json
node src/cli.mjs plan-render --db .fullbench/run.sqlite --run RUN_ID \
--output planning-blueprint.htmlWith a configured CAO and runtime adapters, the normal path is one command. The CAO forms the temporary planning team, gathers its findings, produces the blueprint and writes the walkthrough:
node src/cli.mjs plan --db .fullbench/run.sqlite --run RUN_ID \
--config fullbench.config.json --output planning-blueprint.htmlThe HTML is the operator walkthrough: it includes the product description,
visual mockups, system shape and build sequence in one accessible document.
FullBench refuses to create build tasks while this blueprint is still a draft.
After review, accept the exact digest shown by plan-install or plan-render:
node src/cli.mjs plan-accept --db .fullbench/run.sqlite --run RUN_ID \
--digest BLUEPRINT_DIGESTEditing the proposal changes its digest, so an earlier acceptance cannot silently authorise a different build. See docs/planning.md.
When a build slice starts, FullBench automatically writes its plain-English
kickoff brief under docs/fullbench/slices/. When all work and independent
assurance have passed, it writes the completion record in the same directory.
The run is not marked complete if that durable record cannot be written safely.
Form an agent team
FullBench accepts a TeamPlan@1 from a CAO adapter. The plan names capabilities and dependencies rather than permanent roles. FullBench independently promotes declared privacy, security, money, release, migration, concurrency, credential, live-data and destructive boundaries to frontier judgment.
FullBench is opencode-first. Every chat inherits the operator's selected opencode model — no model names in the configuration — and reasoning effort is tiered automatically from the task's capability and route. Mutating work is not trusted to the runtime: each build-phase dispatch runs inside a kernel-owned macOS Seatbelt boundary that confines writes to the disposable task workspace and scratch roots, closes the network except certified loopback, keeps credential stores unreadable, and is verified by an escape-probing conformance suite. A mutating dispatch without that boundary is refused, never silently uncontained.
Every agent chat is also a budgeted resource. Run briefs carry bounded summaries and a compact module catalogue, dependency and finding summaries are capped with ledger tail digests, and a dispatch whose assembled prompt exceeds its route ceiling (24K economy, 48K implementation, 64K judgment/CAO injected tokens by default) is refused before a provider is charged. Runtime-reported token usage is bound to the attempt receipt and shown in the operator status view.
{
"version": 1,
"workspace": { "sourceRoot": ".", "workspaceRoot": "../.fullbench-workspaces/product" },
"cao": { "type": "opencode_cli" },
"adapters": {
"economy_execution": { "type": "opencode_cli" },
"frontier_judgment": { "type": "opencode_cli" }
},
"capabilityAdapters": {
"balanced_implementation": { "type": "opencode_cli" }
}
}Set containment: "none" on an opencode binding to keep it read-only; set an explicit model, reasoningEffort or contextBudgetTokens per adapter when you want to pin one.
A Codex CLI adapter remains available as an alternative mutating runtime. It runs each mutating specialist in its own Git worktree with Codex workspace-write sandboxing, a certified executable and no direct network access; a configured model is recorded as requested and the runtime-reported model separately. OpenCode, Cursor and Claude Code read-only adapters are also available for planning and research chats; Cursor and Claude Code are not currently eligible to write product workspaces, because their CLI-level permissions are not a FullBench-controlled OS boundary. Absent runtime metadata is always not_reported, never inferred.
Run:
node src/cli.mjs orchestrate \
--db .fullbench/run.sqlite \
--run RUN_ID \
--config fullbench.config.json
node src/cli.mjs status-view --db .fullbench/run.sqlite --run RUN_IDThe configuration provides one CAO command and one command for each abstract route. Requested and runtime-reported models are recorded separately.
Operational intelligence
FullBench keeps the useful part of deep work units without recreating their fixed role pipeline. A source-controlled ModuleMap@1 describes each deep module's purpose, public provisions, owned paths, dependencies, invariants, acceptance checks and risk boundaries. Installing it snapshots exact manifest digests into the run ledger.
CAO tasks cite one or more module IDs. FullBench then:
- supplies the exact manifests and digests in every agent handoff;
- promotes work at privacy, security, money and other hard boundaries to frontier judgment;
- adds module invariants and acceptance checks to the task contract;
- derives mutating path claims from module ownership rather than trusting an agent-authored path list; and
- exposes the module map and task/module relationships in the deterministic run brief.
This separates architecture from staffing. Modules remain stable project knowledge; the CAO can recruit whatever temporary capabilities are useful for the outcome. Work spanning several modules becomes several module tasks plus an explicit integration task, rather than one oversized work unit.
node src/cli.mjs modules-install \
--db .fullbench/run.sqlite \
--run RUN_ID \
--map ../sensight/docs/agent-conversation/module-map.jsonMemory boundary
FullBench treats memory as four different things:
- Project truth: Git and accepted contracts at exact revisions.
- Run state: this transactional SQLite ledger.
- Artefact evidence: immutable content-addressed outputs referenced by the ledger.
- Reusable learning: typed and validated patterns, added in a later slice.
Agent scratch context is temporary. Raw transcripts and private reasoning are not durable team memory.
See docs/architecture.md and docs/next.md.
