Skip to main content

Agent System

The Society is not one agent. It is specialists who know when to call each other.


Overview

The Agenthood uses a multi-agent architecture where a central Orchestrator
coordinates all specialized members. No member tries to do everything.
Each receives only the tools and context relevant to their specialty.

This design avoids the failure mode of monolithic agents: an agent given every
tool and every responsibility becomes unpredictable, slow, and hard to debug.


The Orchestrator

The Orchestrator is the Society's dispatch system. It:

  • Receives incoming requests and classifies them by type
  • Routes work to the appropriate member(s)
  • Manages the publish/subscribe event bus between members
  • Tracks the state of multi-step tasks across member handoffs
  • Never does the work itself — it only coordinates

Key principle: Every member communicates through the Orchestrator,
never directly to each other. This decouples the system and makes behavior
predictable and auditable.

User Request
     ↓
 Orchestrator
  ↙  ↓  ↓  ↘
Scribe Reviewer Tester Doorman ...

The Members as Subagents

Each member is a subagent with:

PropertyDescription
RoleA single, well-defined specialty
Tool scopeOnly the tools needed for their role
Permission profileRestricted / Standard / Trusted
Handoff protocolHow they signal completion to the Orchestrator
Escalation pathWhat to do when they can't proceed alone

Member → Tool Scope

Full tool-scope definitions live in built-in-tools.md and are
implemented in src/members/MemberRegistry.ts.

MemberPermission ProfileKey Tools
The Scribestandardfile.write, code.write, code.refactor
The Architectstandardfile.write, code.write, code.refactor
The Builderstandardfile.write, code.write, code.refactor
The Reviewerrestrictedfile.read, file.search, code.explain
The Testerstandardfile.write, code.write, code.refactor
The Debuggerstandardfile.write, code.write, code.refactor
The Auditorrestrictedfile.read, file.search, code.explain
The Heraldstandardfile.write, code.write, code.refactor
The Librarianstandardfile.write, code.write, code.refactor
The Doormanrestrictedfile.read, file.search, code.explain
The Oraclerestrictedfile.read, file.search, code.explain
The Envoyrestrictedfile.read, file.search, code.explain
The Sentinelrestrictedfile.read, file.search, code.explain
The Wardenrestrictedfile.read, file.search, code.explain
The Strategistrestrictedfile.read, file.search, code.explain
The Stewardrestrictedfile.read, file.search, code.explain
The Operatorrestrictedfile.read, file.search, code.explain
The Mailmanstandardfile.write, code.write, code.refactor
The Inspectorstandardfile.write, code.write, code.refactor

Core Agents (Runtime)

The standalone core-agent classes carry narrower tool sets than the member
profile grants below — a deliberate fail-closed choice from the agent lifecycle
hardening wave. They only receive what their executor path needs: Developer,
Architect, QA, and Reviewer are wired in ApplicationContext.setupAgents,
Oracle in setupOracle, and Strategist/Operator are not wired into the
ApplicationContext at all — they are instantiated by tests or callers directly.

AgentTools
DeveloperAgentReadFileSkill, WriteFileSkill, WriteCodeSkill, RefactorSkill, SearchCodebaseSkill, ExplainCodeSkill, SubagentTaskSkill (delegation, opt-in)
ArchitectAgentReadFileSkill, WriteFileSkill, WriteCodeSkill
QAAgentReadFileSkill, WriteFileSkill, WriteCodeSkill
ReviewerAgentReadFileSkill (read-only)
OracleAgentReadFileSkill, SearchCodebaseSkill (read-only)
StrategistAgent / OperatorAgentnone — pure reasoning, output rendered against a fixed format

Member execution (via MemberAgent) remains governed by MemberRegistry profile
grants. delegate_task for members is opt-in per spec via canDelegate;
DeveloperAgent's SubagentTaskSkill is a separate core-agent delegation path,
not governed by member profile grants — it is also opt-in via
DeveloperAgentOptions.canDelegate (enabled in ApplicationContext.setupAgents).

Delegation is bounded at two levels. First, the role allowlist (DELEGATION_ALLOWED_ROLES)
admits only read-only analysis roles — never write-capable agents. Second, tool
isolation: every agent and each member run constructs its own ToolRegistry +
ReActLoop (ApplicationContext.setupAgents, runMemberTask), so a delegated
subagent's tool schemas are always its own load-out and never the caller's write
tools. The delegated task itself travels inside an untrusted <delegated_task>
boundary, and the only surface genuinely shared is the ExecutionContext
(memory, tracer, artifacts). A compromise of the caller therefore cannot reach
writes through delegation that the caller could not already reach with its own
tools.


The Reason → Act → Observe Loop

Each member operates on a three-step cycle:

REASON    → Read context, form a plan, identify tools needed
   ↓
ACT       → Execute tools, make changes, call external services
   ↓
OBSERVE   → Read output, assess result, decide next step
   ↓
(repeat until task complete or escalation needed)

The loop continues until:

  • The task is complete (success)
  • A safety limit is reached (see built-in-tools.md)
  • Human approval is required (destructive action gate)
  • The member escalates to the Orchestrator for handoff

Self-Healing

When a member encounters an error during execution:

  1. Read the full error output — not just the first line
  2. Classify: is this recoverable or not?
  3. If recoverable: apply correction and retry
  4. If not recoverable: escalate with a clear description of what failed and why
  5. Never silently swallow errors or add empty catch blocks to proceed

Multi-Member Tasks

Some tasks span multiple members. The Orchestrator manages the handoff:

Example: "Review and ship this PR"

Orchestrator
  → The Doorman     (validate commit messages on the branch)
  → The Reviewer    (five-axis code review)
  → The Tester      (verify test coverage)
  → The Auditor     (security pass)
  → The Scribe      (generate PR description)
  → The Herald      (prepare release notes if merging to main)

Each member signals done → Orchestrator routes to next → human approves final output.


Persistent Memory

The Society remembers across sessions:

  • Project scope — conventions, rules, recurring patterns in this codebase
  • User scope — preferences, feedback, workflow patterns
  • Session scope — current task state, in-progress work

Memory is backed by a tiered store: LanceDB for vector storage (.agenthood/memory/), ResidualMemory (.agenthood/residual.json), KnowledgeGraphStore (.agenthood/society-graph.json), and ShortTermMemory (in-memory ring buffer). Multiple namespaces — shortTerm, longTerm, episodic, project — keep concerns separated.

On top of the tiers sit the decision and provenance records. Every member run
writes one entry to the decision log (.agenthood/decisions/) and one to the
provenance store (.agenthood/provenance/), linked by the run's
executionId. Decisions connect with causal edges (CAUSED, INFLUENCED,
PRECEDENT_FOR) in edges.json, and the provenance chain is tamper-evident
(SHA-256 hash chain, verifyChain()). See
decision-intelligence.md.


Runtime Implementation

The architecture described in this document is implemented as a TypeScript CLI in
this repo (src/), per ADR-008.

This docImplemented asStatus
Members (skill files)skills/<name>/SKILL.md✅ Shipped
Core agent roles (runtime)developer → The Builder, qa → The Tester, architect → The Architect, reviewer → The Reviewer, the-oracle → The Oracle (src/agents/)✅ Shipped
Member subagent specs (tools, permissions)src/members/MemberRegistry.ts✅ v2.0.0
Tool scoping per memberMemberSpec.tools in MemberRegistry✅ v2.0.0
Permission profilesMemberSpec.permissions in MemberRegistry✅ v2.0.0
Per-member preferred LLM providerMemberSpec.preferredProvider✅ v2.0.0
ReAct loopsrc/reasoning/ReActLoop.ts✅ Shipped
BaseAgentsrc/agents/base/BaseAgent.ts✅ Shipped
Concurrency queuesrc/core/ConcurrencyQueue.ts✅ v2.0.0
Safety capssrc/core/SafetyGuard.ts✅ v2.0.0
Provider failover + circuit breakersrc/llm/ProviderFailover.ts✅ v2.0.0
Persistent memory (IMemoryStore, ResidualMemory, InMemoryStore, VectorStore, ShortTerm, LongTerm, Episodic, Project)src/memory/✅ Shipped
Decision intelligence (DecisionLog + causal chains, ProvenanceStore, DecisionSearch, GraphSnapshot)src/memory/✅ ADR-015
RAG pipeline (ChunkStrategy (FixedSize + MarkdownHierarchical), Indexer, Retriever, AgenticRAG, TreeSitterParser, ProjectIngestion)src/rag/✅ Shipped
Society index (members, ADRs, conventions → KGS + VectorStore)src/project/SocietyIndexer.ts✅ Shipped
MemberOrchestrator Phase 1 — detectionsrc/reasoning/MemberOrchestrator.ts✅ v2.6.0
Orchestrator (event bus, multi-step handoff)src/orchestrator/📋 Planned — Phase 3
Member → Member direct handoff (today)SubagentTaskSkill✅ Shipped (no bus)

The Markdown skill files in skills/ are never modified — each is parsed at runtime
by MemberRegistry and used as the system prompt for the corresponding BaseAgent.