Agentic layer
The opt-in autonomous side of operad. OODA-driven master controller, four specialist agents, a structured-action protocol the agents speak back, persistent memory that decays and consolidates, a personality layer you can shape, and a switchboard with kill-switches at every level.
Everything below is disabled by default. Enable through the dashboard's Switchboard when you're ready — until you do, operad is just a session manager.
What this is
operad ships a small agent runtime layered on top of the session manager. A master-controller
agent runs OODA cycles on a
periodic timer (or on demand), observing what's happening across your sessions and emitting
structured action blocks that operad parses and dispatches. Three specialist agents — optimizer,
preference-learner, ideator — sit alongside it, callable from chat or via OODA's
message blocks.
Agents persist what they learn in SQLite tables that decay, prune, and merge over time. Learnings cross-pollinate between agents (high-confidence insights from optimizer become available to master-controller next run). User preferences and personality live in their own layers — the mind-meld profile is yours to write, not Claude's.
Trust calibration tracks every agent's success/failure ratio and recommends
autonomy level changes
(observe → suggest → supervised → trusted → autonomous) based on the track record. The
Switchboard overrides
everything: a master kill-switch plus per-subsystem and per-agent toggles, persisted in
state.json so toggles survive restarts.
OODA cycle
Observe → Orient → Decide → Act. Master-controller's prompt is structured around the four phases. Each cycle ends with one or more fenced action blocks the dispatcher parses and applies.
maybeTriggerOoda ─┐
│ if (idle for > threshold && switchboard.oodaAutoTrigger)
▼
runOodaCycle
│
▼
buildAgentContext("master-controller")
│ datetime, recent decisions, learnings,
│ personality, mind-meld profile, recent
│ inbox messages, current goals, strategy
▼
sdkBridge.runStandaloneAgent(master-controller, ...)
│
▼
response text
│
▼
parseOodaResponse(text)
│ matches ```<type>\n...\n``` blocks
▼
executeOodaActions([...])
│
├──▶ goal │ insert into agent_goals
├──▶ decision │ insert into agent_decisions
├──▶ message │ insert into agent_messages (inbox)
├──▶ strategy │ bump agent_strategies version
├──▶ schedule │ re-fire after delay_minutes
├──▶ persistent_schedule │ insert agent_schedules (cron/interval)
├──▶ learning │ addLearning() → consolidation later
├──▶ personality│ setPersonalityTrait()
├──▶ tool │ invoke registered tool
├──▶ tool_sequence │ run tool list in order
└──▶ roundtable │ convene specialists on a topic Action block types
Master-controller emits these as fenced code blocks. The parser is permissive — unknown blocks are ignored, missing required fields skip the action with a debug log.
| Block | Fields | Effect |
|---|---|---|
| goal | title, description, priority, parent_id | Add a node to the goal tree |
| decision | action, rationale, alternatives, expected_outcome, goal_id | Record a decision in the journal |
| message | to, type, content | Send an inbox message to another agent |
| strategy | text, rationale | Bump the strategy version with a new directive |
| schedule | delay_minutes, trigger, reason | Re-fire OODA after a delay |
| persistent_schedule | name, cron|interval_minutes, prompt, max_budget_usd | Register a recurring agent run (cron-managed) |
| learning | content, category, confidence | Record a learning in agent_learnings (decays over time) |
| personality | trait, value, evidence | Update agent_personality trait |
| tool | name, args (per-tool) | Invoke a registered tool from the tool registry |
| tool_sequence | name, [{tool, args}, ...] | Run multiple tools in order |
| roundtable | topic, agents, context | Convene a multi-agent discussion |
Cycles can be triggered three ways: automatically (cognitive timer when idle and
switchboard.oodaAutoTrigger=true),
on user demand (POST /api/cognitive/ooda),
or by a registered cron schedule that the previous OODA cycle itself emitted.
Builtin agents
Four agents ship with operad. All start disabled;
flip them on per-agent in the Switchboard. You can also define your own agents in
~/.config/operad/operad.toml
using [[agent]] blocks
(see Configuration).
master-controller
effort: maxOrchestrator
Runs the OODA loop. Observes system state, orients against goals, decides on actions, acts via direct execution or delegation. Allowed every tool category.
optimizer
effort: mediumToken quota guardian
Tracks weekly quota utilization. Flags disproportionate consumers, suggests pruning stale data, analyzes velocity, recommends session consolidation. Read-only.
preference-learner
effort: highUser-modeling
Discovers your coding style, framework preferences, naming conventions, communication patterns, workflow habits — from session history and the mind-meld profile. Read-only.
ideator
effort: maxCreative strategist
Generates architecture alternatives, what-if analysis, new project concepts, unconventional approaches. Read-only — emits proposals, never mutates.
Two ways to invoke an agent: Run — one-shot, fire-and-forget (the prompt + response
land in agent_runs).
Chat — multi-turn replay-based (prior conversation is
replayed into context each turn, persisted in
agent_conversations).
Both surface in the Agents panel of the dashboard.
Self-improvement layer
Every agent response is post-processed by
extractAgentActions(),
which scans for learning
and personality fenced blocks
and folds them into the agent's persistent state. On the next run the new state shows up
in the agent's context — that's the "self-improvement" mechanism. There's no fine-tuning;
there's prompt accretion with decay.
learning blocks
```learning
content: pin sonnet 4.6 for routine
refactors; opus only for novel
architecture work
category: routing
confidence: 0.85
```
Stored in agent_learnings.
Decays over 30 days; pruned below 0.15 confidence; merged with similar entries in the
same category. High-confidence learnings cross-pollinate via
getSharedInsights().
personality blocks
```personality
trait: communication_style
value: concise, evidence-first
evidence: user repeatedly asked for
shorter responses with citations
```
Stored in agent_personality.
Re-injected into the agent's prompt prefix on every run — so an agent that learns "user
prefers terse explanations" stays terse without you reminding it.
What gets injected into an agent's context
buildAgentContext(agentName) →
current datetime + system memory state
┊
recent decisions (last 5 from agent_decisions)
recent learnings (top by confidence)
shared insights (high-confidence learnings from OTHER agents)
personality (current trait values)
recent inbox (last 5 from agent_messages)
current goals (open from agent_goals)
current strategy (latest agent_strategies)
mind-meld profile (your written file, if enabled)
┊
──→ prepended to user prompt as context block Memory consolidation
Agents accumulate learnings indefinitely if you let them. The consolidation worker runs when the daemon detects user idle for > threshold and squashes the noise. Four operations:
decay
Learnings older than 30 days lose 0.1 confidence per pass. Stale insights fade out naturally instead of dominating the prompt forever.
prune
Learnings below 0.15 confidence are deleted. Once decayed past the floor, they're gone — the prompt budget recovers.
merge
Same-category learnings with similar content (hash-prefix match) collapse into a single entry, taking the max confidence. Stops the same insight from showing up five times.
cross-pollinate
High-confidence learnings (≥ 0.75) become "shared insights" surfaced to other agents through their context. Optimizer's quota observations show up in master-controller's prompt next cycle.
Daily snapshots of the full agent-state bundle (learnings, personality, goals, decisions,
strategies, specializations) write to
~/.local/share/operad/snapshots/
with retention. Lets you roll back if a consolidation pass deletes something useful.
Multi-agent orchestration
Three coordination primitives: message bus, specialization registry, and roundtable protocol.
Inbox / message bus
Every agent has an inbox in agent_messages.
Master-controller emits message
blocks targeting specific agents (or "all"). Recipients see unread messages prepended to
their next context. Read receipts persist via
read_at.
```message
to: optimizer
type: request
content: weekly token usage spiked 40%
in cleverkeys. investigate cause and
recommend mitigations before fri.
``` Specialization registry
agent_specializations
tracks domain expertise per agent: which categories does this agent know about,
with what confidence. Builtin agents get seed specializations
(optimizer ↔ token-quota, preference-learner ↔ user-modeling, etc.). Confidence
auto-reinforces when an agent records a learning matching one of its specialization
categories — competence in a domain compounds.
Roundtable protocol
Master-controller can convene a multi-agent discussion via a
roundtable block.
Each named agent runs sequentially with the topic + the running transcript so far.
Each contributes 2-4 focused points from its specialization. Final transcript is
delivered to master-controller as an inbox message and recorded as a decision.
```roundtable
topic: cleverkeys IME memory leak — what next?
agents: optimizer, ideator, preference-learner
context: profile data shows steady RSS growth
during long typing sessions; no obvious leak
in heap snapshot.
``` User control + influence layers
The agentic layer is opt-in and shape-able. You don't just toggle it on — you tell the agents who you are, what you want, and what to ignore. Three layers:
Mind-meld profile
A free-form file you write, prepended to OODA prompts when
switchboard.mindMeld=true.
Whatever you put here — work style, hard constraints ("never email me"), preferences,
personality notes — becomes part of the master-controller's orientation phase.
Editable from the dashboard's Mind Meld panel. Opting out strips it from prompts entirely.
Preference-learner agent
Read-only specialist. When invoked (chat or scheduled), it reads session history + the mind-meld profile and emits learnings back into agent state. Those learnings then cross-pollinate to master-controller via the shared-insights channel — so the next OODA cycle "knows you prefer X" without you having said so directly to master-controller.
Switchboard
Hard control surface. Persisted in state.json.
Six toggles + per-agent overrides:
Off-by-default ships safe defaults: SDK bridge on, everything else off. Enable as you want each piece to start running.
Trust + autonomy
Each agent has an autonomy level. The trust ledger (agent_trust_ledger)
records signed deltas — successful scheduled runs add credit, failures and bad outcomes
subtract — and produces a recommended autonomy level you can accept or override.
Tool leases
An agent at lower autonomy can request a temporary lease on a higher-tier tool — "can I run this specific Bash command for the next 60 seconds?" — and the lease is logged + bounded. Closes the gap between "always allowed" and "always denied".
Protected checkpoints
Even autonomous
agents must request approval for actions in
protected_files,
protected_git
(e.g. push --force, reset --hard), and
protected_tools.
Configured in the orchestrator section of operad.toml.
Tools, categories, schedules
Agents act through a tool registry, not free-form Claude Code tools. Each tool is tagged with a category that the autonomy level maps to.
read-only — list sessions, read files, get status
compute — token velocity, memory stats, log queries
modify state — restart sessions, edit files, write memos
external comms — termux notification, send message, broadcast
delegate to other agents, spawn sessions, schedule runs
Persistent scheduling
Master-controller can register recurring agent runs via the
persistent_schedule
block. Stored in agent_schedules;
a 30-second poll loop fires due entries. Auto-disables after consecutive failures so a broken
schedule doesn't burn quota indefinitely.
```persistent_schedule
name: weekly-quota-review
cron: 0 9 * * MON
prompt: review last week's token usage
by session. flag the top 3 consumers.
recommend pruning candidates.
max_budget_usd: 0.50
```
Either cron (5-field expression)
or interval_minutes (simple
repeating delay) — mutually exclusive.
Custom tools (TOML)
Define your own tools in operad.toml
with a [[tool]] block.
Tools are shell commands templated with the tool's args; the registry tags them with a
category so they slot into the autonomy framework.
Where each layer lives in the dashboard
| Panel | What you do there |
|---|---|
| Switchboard | master kill-switch + per-subsystem + per-agent toggles |
| Agents | list, run, chat, view runs (full prompt/response/thinking text) |
| Cognitive | goal tree, decision journal, strategy version, message bus, growth metrics |
| Mind Meld | edit your personality / preferences profile |
| Telemetry | token quota status, weekly utilization, per-agent cost rollup |
REST surface
GET /api/agents list configured agents
POST /api/agents/<name>/run one-shot run with prompt
POST /api/agents/<name>/toggle enable/disable
GET /api/agents/runs paginated runs (preview)
GET /api/agents/runs/<id> full prompt/response/thinking
GET /api/agents/<name>/learnings
GET /api/agents/<name>/personality
POST /api/cognitive/ooda fire OODA on demand
GET /api/cognitive/goals
GET /api/cognitive/decisions
GET /api/cognitive/strategy
GET /api/cognitive/messages
GET /api/quota weekly quota status
GET /api/specializations
POST /api/switchboard update toggles
Source of truth lives in
src/
—
agents.ts,
cognitive.ts,
agent-engine.ts,
consolidation.ts,
memory-db.ts,
schedule.ts.