fullbench
v0.1.18
Published
Provider-neutral orchestration for durable teams of specialist agents.
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. npx fullbench init installs, upgrades
or starts that private LaunchAgent automatically on macOS. The lower-level
fullbench service actions remain available for repair and administration;
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.
- Luna performs mechanical test/browser execution and scoped online research; Terra performs standard isolated coding; Sol performs complex judgment and assurance.
- 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. Codex harness use—including Luna, Terra and Sol specialists—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, such as Sensight calling OpenAI. 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. The same invocation is the everyday operator entrypoint. It initialises the project without overwriting existing configuration or build documents, ensures the per-user resident service is running, and stays open. If planning has not created a run yet it truthfully shows READY and waits; once the plan or build is admitted it discovers that run and automatically opens the reconnecting live dashboard in the browser. There is no separate watch command.
The dashboard is served only on a random local 127.0.0.1 port. Its one-time
authentication secret is carried in the URL fragment, exchanged for an
HttpOnly, SameSite session cookie, and immediately removed from browser history;
it is never sent in a query string or written to server logs. The browser keeps
the last known snapshot visible if the daemon restarts or briefly disconnects,
while clearly marking the view as reconnecting and making no fresh progress
claim. If a browser cannot be opened, the same information remains available in
the terminal.
The dashboard reports exact completed-task counts and separately shows daemon health, worker-process liveness and meaningful work activity. A current lease only proves that FullBench still owns the task; it never resets the activity age or causes a quiet worker to be labelled as progressing. A live worker therefore moves from STARTING to QUIET and then STALLED when no file, tool, test, checkpoint or other admitted activity arrives. UNCERTAIN means telemetry cannot currently prove the worker state. Before a model process exists, a currently fenced workspace checkout or dependency install is shown separately as PREPARING, including bounded installer byte activity where available; it is never labelled as model work or recovery. Ctrl-C detaches the dashboard without stopping the resident build.
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
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. Sol 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.
Read-only runtime adapters use a small JSON-over-stdin/stdout protocol, so Cursor or another agent host can be connected without changing the kernel. Generic commands are never trusted with code-changing tasks. FullBench includes a dedicated Codex CLI adapter which runs each mutating specialist in its own Git worktree with Codex workspace-write sandboxing, no interactive approvals, no direct network access, no inherited project rules and no additional writable directories.
The Codex configuration is explicit. FullBench binds read-only economy_execution work to GPT-5.6-Luna, standard isolated mutations to GPT-5.6-Terra through capabilityAdapters.balanced_implementation, and frontier_judgment to GPT-5.6-Sol. Luna is limited to mechanical focused-test or browser execution and clearly scoped online research. Terra owns ordinary multi-file implementation and settled integration work. Repository diagnosis, source interpretation, architecture, integration judgment, privacy/security reasoning, recovery planning, implementation review, final acceptance and adversarial challenge use Sol at high reasoning. Unknown or ambiguous capabilities fail upward to Sol rather than downward to Luna. Risky code still requires separate Sol assurance over the same deep module. After a bounded Terra implementation failure, the CAO may issue a recorded recovery plan that upgrades that exact task to Sol. This build policy is separate from any model/effort policy inside Sensight itself.
{
"type": "codex_cli",
"name": "codex-terra",
"model": "gpt-5.6-terra"
}An OpenCode CLI adapter is available for non-build experimentation, but it is not yet admitted for product writes or build verification. OpenCode has no OS-level sandbox, and prompt permissions, command-name guards and after-the-fact fingerprints are not a sufficient mutation boundary. It remains disabled for build work until the same containment conformance suite used by the other mutating runtimes passes. A configured model is recorded as requested; if the runtime does not report what actually ran, FullBench records not_reported rather than inferring it.
Cursor Agent and Claude Code also have dedicated streaming CLI adapters for read-only planning and research. Cursor uses its -p --output-format stream-json interface; Claude Code uses print-mode stream-json with plan permissions. Neither is currently eligible to write product workspaces or perform browser verification: their CLI-level permissions and FullBench command guards are not evidence of a FullBench-controlled OS filesystem, network and credential boundary. Their requested model is recorded separately from runtime-reported model and session metadata; absent or conflicting metadata is not_reported.
{
"type": "opencode_cli",
"name": "opencode-host",
"model": "opencode-go/qwen3.8-flash"
}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.
