Architecture Decisions
The lab's Architecture Decision Records (ADRs) — context, decision, reason, and consequences for each significant design choice.
Purpose
This page is the canonical reference for the lab's Architecture Decision Records. An ADR is a short document that captures a significant decision, the context in which it was made, and the consequences.
The lab has 13 ADRs. They are listed below in chronological order. The first 9 are accepted; the last 4 are planned or in flight.
ADR Template
Each ADR has the following structure:
ADR-001: Isolate the main agent and the specialized agents
Status: Accepted
Date: 2026-05-09
Context. The lab started with a single agent that handled everything: research, coding, media, web. The single-agent design was simple but created several problems: (1) the agent's context was polluted by unrelated tasks; (2) a crash in one task took down the others; (3) the security boundary between low-risk and high-risk operations was unclear.
Decision. The lab splits the agents into two groups: the main agent (the Coordinator) and the specialized agents (the Coding Assistant, the Research Worker, the Media Agent, the Web Agent). The two groups run in separate processes and communicate through defined interfaces.
Reason. The split provides (1) clean context per agent, (2) fault isolation, (3) a clear security boundary, and (4) the ability to scale or replace each agent independently.
Consequences. Positive: cleaner code, clearer boundaries, easier to test. Negative: more processes to manage, more interfaces to maintain. The cost is worth it for the lab's scale.
ADR-002: The Coding Assistant never writes code directly
Status: Accepted
Date: 2026-05-09
Context. The Coding Assistant is the lab's implementation arm. In the early design, the Assistant could write code directly when the task was small. This created several problems: (1) the Assistant's outputs were inconsistent, (2) there was no review step, (3) the user had no way to verify the Assistant's reasoning.
Decision. The Coding Assistant delegates all code-writing to a sandboxed coding sub-agent. The Assistant reviews the code, integrates it, and tests it. The Assistant never writes code by hand.
Reason. The sub-agent is designed for code generation. It has a larger context window, a sandboxed environment, and a deterministic review process. The Assistant's value is in the design and the review, not in the code generation.
Consequences. Positive: consistent code, review process, verifiable reasoning. Negative: slower turnaround, dependency on the sub-agent. The cost is worth it for the lab's quality bar.
ADR-003: Memory is per-agent, not shared
Status: Accepted
Date: 2026-05-09
Context. The lab's agents needed memory. The early design had a single memory layer shared by all agents. This created problems: (1) the memory was polluted by agent-specific data, (2) the agents competed for write access, (3) the audit trail was unclear.
Decision. Each agent has its own memory. The Coordinator has its own MEMORY.md and daily logs. The Research Worker has its own mission artifacts. The Media Agent has no persistent memory. The agents do not share memory.
Reason. The per-agent memory provides clean boundaries, eliminates write contention, and produces a clear audit trail. The cost is that some data needs to be duplicated (e.g., the user's preferences), but the duplication is small.
Consequences. Positive: clean boundaries, clear audit trail. Negative: some data duplication. The cost is worth it.
ADR-004: The research framework writes typed artifacts
Status: Accepted
Date: 2026-05-10
Context. The research framework's early version wrote artifacts as untyped JSON or markdown. This made it hard to validate the artifacts, hard to reproduce the runs, and hard to reason about the data flow.
Decision. Every artifact the research framework writes is validated by a Pydantic schema. The schemas are the contract between the framework and its consumers. A new schema requires an ADR.
Reason. Typed artifacts provide validation, reproducibility, and a clear contract. The Pydantic schemas are easy to write and easy to test.
Consequences. Positive: validation, reproducibility, clear contract. Negative: more boilerplate (the schemas), more coupling between the framework and its consumers. The cost is worth it.
ADR-005: External API keys are behind a token pool
Status: Accepted
Date: 2026-05-10
Context. The lab uses paid APIs (Perplexity, Tavily). A single API key was a single point of failure: a rate limit on the key stopped the lab's work.
Decision. The lab uses a token pool for paid APIs. The pool is configured in token_pool_config.json and supports round-robin, weighted round-robin, least-used, and failover strategies. The pool writes its state to a runtime file for observability.
Reason. The pool provides redundancy, load distribution, and observability. The pool's state file is the foundation of the lab's audit trail for external API usage.
Consequences. Positive: redundancy, load distribution, observability. Negative: more configuration to manage, more complex error handling. The cost is worth it for the lab's reliability.
ADR-006: Every external call is recorded in a request journal
Status: Accepted
Date: 2026-05-10
Context. The lab makes many external calls. The early design did not record the calls. This made it impossible to answer "what did the lab do last Tuesday?" or "why did this mission fail?".
Decision. Every external call is recorded in an append-only request journal. The journal is rotated when it exceeds a configured size. The journal is the foundation of the lab's audit trail for external API usage.
Reason. The journal provides complete observability of external calls. The journal is append-only to prevent tampering. The journal is rotated to keep file sizes manageable.
Consequences. Positive: complete observability, tamper resistance. Negative: storage overhead, the need to redact sensitive data. The cost is worth it for the lab's auditability.
ADR-007: The lab is local-first
Status: Accepted
Date: 2026-05-10
Context. The lab could be cloud-based, but the user wants a local-first design for control, privacy, and learning.
Decision. The lab runs on the user's machine. The only network access is to external providers (model, search, streaming) and to the local network (mDNS for device discovery). There is no cloud control plane.
Reason. Local-first provides control, privacy, and learning opportunities. The user can inspect every component, modify every configuration, and recover from every failure without depending on a cloud service.
Consequences. Positive: control, privacy, learning. Negative: limited by local resources, requires user-side backups, requires the user to manage dependencies. The cost is worth it for the lab's values.
ADR-008: Documentation is a deliverable
Status: Accepted
Date: 2026-05-10
Context. The lab's projects started without documentation. The user realized that without documentation, the projects were hard to maintain, hard to onboard collaborators, and hard to recover from failure.
Decision. Every project must have documentation. The documentation includes README.md, code-reference.md, and architecture.md. The documentation is updated with every commit that changes the architecture, the components, or the public interfaces.
Reason. Documentation makes projects maintainable, learnable, and recoverable. The cost of writing documentation is small compared to the cost of not having it.
Consequences. Positive: maintainability, learnability, recoverability. Negative: more work per change. The cost is worth it.
ADR-009: External providers are behind adapters
Status: Accepted
Date: 2026-05-11
Context. The lab integrates with several external providers. The early design had provider-specific code scattered through the framework. This made it hard to add new providers, hard to test without real providers, and hard to swap providers.
Decision. External providers are behind adapters. The adapter contract is documented in External Providers. A new provider requires a new adapter; the rest of the framework does not change.
Reason. Adapters provide a clean contract, testability, and swap-ability. The cost of writing an adapter is small compared to the cost of not having one.
Consequences. Positive: clean contract, testability, swap-ability. Negative: more files, more boilerplate. The cost is worth it.
ADR-010: Smart Orchestrator V2
Status: Planned
Date: TBD
Context. The current orchestrator is deterministic at the orchestration level. The phases are predefined and the DAG is fixed. The user wants the orchestrator to be smarter: to choose the right phases based on the query, to skip unnecessary phases, to retry with different parameters, and to parallelize more aggressively.
Decision. The orchestrator is redesigned to be adaptive. The orchestrator uses a planner that selects the phases based on the query, an executor that runs the selected phases, and a verifier that checks the results. The DAG is generated per mission, not per project.
Reason. The current orchestrator is rigid. The adaptive orchestrator is more flexible, more efficient, and more capable.
Consequences. Positive: flexibility, efficiency, capability. Negative: more complex, more failure modes, harder to test. The cost is worth it for the lab's ambitions.
Open questions.
- How is the planner trained? With examples? With a rule engine? With a model?
- How is the verifier designed? What constitutes success?
- How is the adaptive orchestrator tested? With recorded missions? With synthetic queries?
ADR-011: Plugin system for custom domain tools
Status: Drafting
Date: TBD
Context. The current research framework has 8 domain tools hardcoded. Adding a new domain tool requires modifying the orchestrator. The user wants a plugin system that allows third parties to add domain tools without modifying the framework.
Decision. The research framework exposes a plugin API. A plugin is a Python package that implements the plugin contract. The orchestrator discovers plugins at startup and registers them.
Reason. A plugin system allows the lab to extend without modifying the core. The cost is a plugin API and the security review of plugins.
Consequences. Positive: extensibility, community contributions. Negative: more API surface, more security review. The cost is worth it for the lab's openness.
Open questions.
- How are plugins discovered? By file? By entry point? By configuration?
- How are plugins sandboxed? What can a plugin access?
- How are plugins versioned? How are conflicts resolved?
ADR-012: SQLite or PostgreSQL for artifact storage
Status: Planned
Date: TBD
Context. The current artifact storage is the filesystem. The artifacts are JSON files in a directory tree. The filesystem is simple but has limitations: (1) no querying, (2) no transactions, (3) no concurrent writes, (4) no replication.
Decision. The artifact storage is migrated to SQLite (for single-host) or PostgreSQL (for multi-host). The migration is transparent to the consumers; the artifact API is the same.
Reason. A database provides querying, transactions, concurrent writes, and replication. The cost is a migration and a database to manage.
Consequences. Positive: querying, transactions, concurrent writes, replication. Negative: migration effort, database management. The cost is worth it for the lab's scale.
Open questions.
- SQLite or PostgreSQL? The decision depends on the lab's growth.
- How is the migration done? Online? Offline?
- How is the schema designed? One table per artifact type? One table for all?
ADR-013: Cross-mission artifact reuse
Status: Drafting
Date: TBD
Context. The current research framework does not share artifacts across missions. A mission that researches "hotels in Barcelona" cannot reuse the artifacts from a previous mission on the same topic.
Decision. The framework introduces a shared artifact store. Missions can declare inputs from previous missions. The shared store is content-addressed; the same inputs always produce the same outputs.
Reason. Cross-mission artifact reuse saves time, reduces API usage, and improves consistency. The cost is a shared store and a content-addressed scheme.
Consequences. Positive: efficiency, consistency. Negative: more complex storage, more complex invalidation. The cost is worth it for the lab's ambitions.
Open questions.
- How is the shared store structured? By topic? By user? By project?
- How is the invalidation done? By TTL? By event?
- How is the consistency ensured? With locks? With CRDTs?