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:
- working memory: Redis;
- episodic memory: timestamped observations and actions;
- semantic memory: concepts, claims and vector embeddings;
- procedural memory: reusable procedures and evaluated skills.
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:
- researcher;
- software engineer;
- reviewer;
- verifier;
- summarizer.
Tools
Tools are typed adapters. Every tool declares:
- input schema;
- output schema;
- side-effect level;
- permission requirement;
- timeout;
- audit behavior.
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:
- command-line interface;
- HTTP API.
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:
- the exactly twice-daily sleep-mode architecture review, with Claude first
and Codex fallback, selected independently of a local
model_rolesrow. 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; - 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; - 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_scoreon 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. - 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: anabandonedbranch is the tree's own verdict that the line of work was a dead end, and asupersededone 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 therender_deferredbacklog 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 becomesuperseded). 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.