BrainOS

BrainOS Architecture

Components

API

A FastAPI service exposes health, project, task, memory and supervisor APIs.

Supervisor

The supervisor owns the execution loop. It selects eligible tasks, assembles context, invokes the director, validates proposed actions and records results.

Director

The director converts goals and current state into structured plans. It must return validated structured output rather than free-form executable commands.

Scheduler

The scheduler is a clock and admission mechanism: it wakes maintenance and bounded execution cycles. It does not decide which research project or paper is scientifically best. Once deterministic code has removed unsafe, ineligible, over-budget, concurrent, or terminal options, the resident portfolio director ranks the remaining choices. A failed or invalid model decision defers selection; it never silently falls back to a numeric score.

Memory

Memory is divided into:

PostgreSQL is authoritative for persistent state. Redis is disposable.

World model

The world model stores entities, relationships, claims, evidence, uncertainty and contradictions.

Specialists

Specialists are role-scoped agents. Initial roles:

Tools

Tools are typed adapters. Every tool declares:

Context navigation

Models receive a small orientation packet rather than a dump of the complete memory store or problem tree. The packet names the active mission, current objective and exact tree path, publication disposition, constraints, and the role-relevant records and approved workspace locations. Stable kind:UUID references connect prompts, results, plans, audits, and later agents to the same durable records.

Owner chat can search/get memory, tree, research, and approved workspace files. Cortex and Supervisor planning receive orientation plus a bounded relevant memory set - genuinely necessary there, since those are single non-agentic structured-output calls with no tools of their own. The generated, Git-excluded context index inside a coding job workspace (.brainos-context/) is still exported, but as of 2026-08-17 the coding prompt no longer requires Codex to start with it or treat it as authoritative - a real live bug (a steering field silently null across a problem-tree pivot) showed that export can be stale, so the prompt instead tells Codex to verify the workspace's actual state itself (its own git log, what's really on disk) before trusting any instruction, curated or otherwise. The database-level writer exclusion remains the concurrency backstop regardless. Codex OSS also now receives real database credentials (BRAINOS_DATABASE_URL, POSTGRES_*) in every tier, hosted and local - a 2026-08-17 owner decision, so it can read and write BrainOS's own durable memory itself rather than depending on a pre-assembled export; owner-interface/chat tokens remain excluded. BrainOS still resolves durable state before launch and the export still exists, but neither the coding index nor the review lane's own status aggregation is the agent's primary source of truth anymore - it does not insert a context CLI or command-execution framework into the Codex session either way.

Interfaces

Initial interfaces:

Telegram is implemented only after the core loop and permission system pass tests.

Deployment

The MVP is a modular monolith. PostgreSQL and Redis run as containers. Ollama remains a host system service.

Do not prematurely split the Python application into network microservices. Internal modules must have clear interfaces so they can be separated later.

Cortex and the problem tree

BrainOS is not a task runner; it is a persistent system that continuously decomposes, prioritises, implements and improves solutions to important problems. The supervisor executes bounded work; the Cortex is the layer above it responsible for deciding what work should exist.

The Cortex never attempts a large objective directly. Every objective is a node in a self-referential problem tree (Module): a node may have child modules that decompose it into roughly ten smaller candidates, each annotated on expected impact, probability of success, available knowledge, required resources and estimated effort. Those values are decision evidence, not a static scheduler. The Cortex collects every safe actionable leaf and asks the resident Codex OSS portfolio director to rank them with an auditable rationale before handing one to a worker as an ordinary Task. Planning proceeds top-down; execution proceeds bottom-up. As leaf modules complete, completion propagates upward: a parent module is reconsidered, and eventually completed, only once its children are.

The problem tree is additive to, not a replacement for, Project/Goal/ Task: a Module links to a Task once it is small enough to execute, and the existing supervisor/coding-worker machinery is unchanged below that point.

Decomposition targets an explicit size gradient tied to how many levels remain before problem_tree_max_depth (ProblemTreeService. _granularity_guidance): children just below the mission root are broad strategic directions (weeks to months), the middle of the tree is project/initiative-sized (days to weeks), one level above the leaf is milestone-sized (about a day), and the leaf itself must be small enough for one bounded coding-job or research-task attempt to finish and prove done. The leaf-size target is 30 minutes of focused work; the two-hour runtime ceiling is hung-process recovery headroom, not permission to create larger tasks. This is calibrated against reality, not just guessed: each decompose() call is given the actual average wall-clock duration of completed coding jobs, bucketed by the depth their task materialized at, so the target sharpens as more work completes instead of staying a fixed guess. A leaf whose coding job repeatedly burns its full time budget without finishing is judged too big rather than broken, and is decomposed into smaller children instead of being abandoned — past the ordinary problem_tree_max_depth, up to problem_tree_oversized_max_depth_extension further levels, since advance() only ever materializes a task at exactly problem_tree_max_depth in the first place.

Module status is one of candidate, active, completed, blocked, concluded, superseded, or abandoned. superseded means feasible work that no longer belongs in the active scientific portfolio because an approved mission replaced it, it duplicates stronger work, or it cannot support a defensible CS contribution. Its history and artifacts remain, but it is terminal for selection. abandoned (abandoned_reason) means fundamentally impossible for autonomous software — recruiting real people, for instance — and is permanent. blocked (blocked_reason) is distinct and never permanent: the work is judged genuinely valuable but cannot proceed without one specific, nameable resource only the owner can provide (a paid API key, a payment processor account, hosting, licensed data, ...). A blocked module is excluded from next_actionable's selection exactly like a terminal status — so the tree moves on to a genuinely different branch instead of continuing to work other subtasks that would hit the same wall — but stays available to resume. Triage is currently the only writer of blocked; it also queues a durable, deduplicated owner notification naming exactly what is needed. Nothing yet automatically detects that a blocked module's resource has since been provided and reopens it — that is a manual, owner-initiated action today. concluded (concluded_reason) is the opposite of abandoned: the branch produced real value and reached a deliberate stopping point, not a dead end. Triage's ProblemTreeService.conclude_branch is the only writer — it abandons the branch's other live descendants and gives it exactly one final task (a report or paper synthesizing what it accomplished); the branch itself only actually becomes concluded once that task completes, not immediately when triage names it.

Active mode and sleep mode

Normal operation is active mode: the Cortex inspects the existing tree and continues scientific work — a running task, a ready module, a repairable failure, a completed set of children that unblocks a parent — before ever creating new branches. Local decomposition must organize coherent CS research programs around an important problem, scientific gap, contribution, credible baselines, controlled evaluation, validity analysis, and reproducibility artifacts; generic tooling and prose are not portfolio outcomes. New decomposition happens only when no executable module remains, a branch reaches a genuine dead end, repeated attempts fail without progress, or new evidence invalidates the current plan. This mirrors the supervisor's existing _cycle() behaviour (recover, retry, pick one eligible unit of existing work) applied one level higher, to modules instead of tasks.

Twice daily, BrainOS enters sleep mode: a bounded, callable, idempotent review (already the shape of ImprovementCycleService) that reorganises the tree rather than producing more of it — re-scoring nodes, restructuring branches that have genuinely stalled, reconciling completed children into their parents, and reviewing memory and model assignments. Sleep mode is also the only place model fine-tuning readiness is evaluated; no training job starts automatically.

Where the strongest models run

Every local generative role is wrapped by Codex OSS in YOLO mode: Cortex planning, research synthesis, classification, local review, owner chat, and workspace-changing active-mode coding. Codex selects the role-routed resident Ollama model and uses its maintained shell/workspace/edit/web harness. BrainOS supplies role-scoped state in the prompt or workspace bundle. Provider health, inventory, and embeddings alone use Ollama directly. Active coding gets one corrective pass; a failed completion gate fails closed into the normal job retry path rather than invoking a BrainOS-owned agent or command executor.

External or host-agent models (Claude, Codex) are expensive and are a network dependency, not the default execution path. They run in four bounded places:

  1. the exactly twice-daily sleep-mode architecture review, with Claude first and Codex fallback, selected independently of a local model_roles row. A durable owner-timezone cap prevents a manual/catch-up third cycle. The same hosted review response owns any bounded BrainOS architecture/improvement plan; a local model does not reinterpret those findings into different system work afterward;
  2. a bounded repair pass over coding jobs whose local attempts were genuinely exhausted — diagnosing and fixing them directly rather than leaving them blocked, selected by the corresponding coding-provider configuration. This is its own six-hourly lane (host-coding-repair-cycle, scripts/install-host-repair-timer.sh), at most three hosted calls per pass. Both ordinary research repair and BrainOS self-improvement may use the configured Codex fallback. This lane used to run only inside sleep mode, and sleep review deliberately no longer adds a repair pass of its own between those slots, so that the two lanes cannot compound into the hosted-quota exhaustion they once did;
  3. a separate scientific-program triage pass — provider-agnostic and run by Codex four times daily. A duplicate Claude transport exists but is disabled by default so it cannot consume review/publication capacity. Triage may repair coding-job workspaces — including broken or fabricated-looking external links and citations in workspace documentation, not just code — and report/abandon impossible problem-tree branches, but is explicitly forbidden from changing BrainOS architecture or source. It also holds genuinely valuable but resource-blocked work rather than discarding it (see "Blocked modules" below) and may update priority_score on specific modules as an advisory signal for the portfolio director, never as the selector itself. It receives recent area-chair missing-work feedback and may supersede feasible but non-contributing or repetitive branches so local compute closes the largest novelty, method, baseline, experiment, or reproducibility gap next.
  4. a change-gated scientific-publication lane (paper-writing-cycle, PaperWritingService). Its deterministic query only establishes eligible broad areas; the resident portfolio director ranks all eligible papers, treating an owner-requested revision and completion of a viable paper as dominant preferences while retaining authority to choose necessary evidence repair instead with a recorded reason. The autonomy loop uses the same policy before creating new tree work, so a timer cannot grow backlog ahead of an actionable paper. The hosted lane then decides whether the selected depth-2 research area has enough novelty, methodology, real results, and reproducibility for at least a solid tier-2 conference. Only live areas are anchorable: an abandoned branch is the tree's own verdict that the line of work was a dead end, and a superseded one was retired by an owner-approved mission change, so neither can become a paper. Anchors must also have been created under the currently approved mission; completed legacy work does not silently re-enter a new scientific portfolio. An unchanged negative verdict consumes no more hosted calls; content changes, not file timestamp churn, change the source fingerprint and permit reassessment. Claude leads each stage and hosted Codex is the configured fallback for quota, transport, or invalid structured-output failures. Provider attempts are audited, and failures do not consume the three successful scientific stages. A ready attempt uses at most three persisted successful stages: study plan/readiness, evidence-grounded drafting, and a rigorous repair-and-review pass. The final pass attempts every feasible bounded correction, executes and verifies workspace programs or analyses when needed, applies manuscript revisions, and judges the repaired paper. It treats honest limitations and optional future strengthening as non-blocking; only defects still fatal to the bounded claim reject publication. The lane has full shell and write access throughout the configured BrainOS workspace tree but never edits BrainOS architecture or source. Codex retains the required non-interactive flags inside a filesystem namespace that mounts BrainOS read-only and the workspace root read-write. Before model calls it inventories actual result artifacts and independently reruns discoverable Python tests through a fixed, credential-scrubbed command template, once per distinct shared workspace. A passing study plan must explicitly bind credible baselines, datasets or workloads, primary metrics, statistical uncertainty, threats to validity, and exact rerun commands to existing evidence. It is also the only scheduled lane running on the host rather than in a container, so it owns the render_deferred backlog the container-side lanes cannot write out. That sweep collapses the backlog to one paper per source before rendering: a source that was redrafted repeatedly is a single paper with a history, not several, and only its newest draft is rendered and published (the rest become superseded). Only manuscripts that pass scientific review and an actual rendered-PDF length gate of 15--20 pages are visible to the dashboard; legacy one-shot drafts remain private build artifacts.

strongest_model remains a provider-neutral local registry role used by the in-process strategic-review and benchmark workflows. It does not select the host CLI reviewer. Keeping these two routing planes explicit prevents a local Ollama assignment from silently changing which credentialed host agent gets write access to BrainOS.

Routine implementation, retries and error-fixing during active mode stay entirely local. A local attempt that fails is retried locally, carrying forward what the previous attempt learned, until its bounded attempt budget is exhausted; only then does it wait for the next hosted repair pass (its own six-hourly lane, see above). No part of active-mode task execution invokes a host agent.

Domain experts and deferred adaptation

Coding roles support optional domain-qualified assignments such as coder:medicine. A qualified installed model is preferred when a problem-tree module carries that domain; otherwise routing deterministically falls back to the plain role. This mechanism never installs a model and currently has no effect unless the owner separately installs and assigns an expert.

Lightweight fine-tuning (LoRA/QLoRA), adapter lifecycle management, and automatic training remain deferred. No training job launches automatically.