Skip to content

Commit fa0905b

Browse files
UbuntuCopilot
andcommitted
docs: add dashboard, daemon-mode, memory, distributed-operations to README + docs/ (closes #1215)
Adds three new top-level README sections — Daemon mode, Memory architecture, Dashboard, and Distributed operations — describing what the autonomous OODA loop actually does today. Embeds three live dashboard screenshots (overview, goals, memory) under docs/assets/. Mirrors each section into a standalone docs/ page and adds them to mkdocs.yml nav: - docs/daemon-mode.md - docs/memory.md - docs/dashboard.md - docs/distributed-operations.md Cross-links the canonical sources (docs/architecture/cognitive-memory.md, docs/howto/run-ooda-daemon.md, docs/howto/spawn-engineers-from-ooda-daemon.md, src/hive_event_bus.rs README) instead of duplicating their content. distributed-operations.md is honest about scope: the hive event bus is in-process only today; multi-host federation is operator-assembled via shared on-disk state (#949 tracks a network transport). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 28a38c4 commit fa0905b

9 files changed

Lines changed: 386 additions & 0 deletions

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,96 @@ Simard exposes five user-visible operating modes, each with its own success crit
2626

2727
These are different operating modes, not cosmetic personas. Each mode owns its own command tree under the `simard` binary.
2828

29+
## Daemon mode (autonomous OODA loop)
30+
31+
Beyond the operator-driven modes above, Simard runs as a long-lived **autonomous daemon** that observes signals, ranks priorities, and dispatches engineer subprocesses without any human in the loop.
32+
33+
```bash
34+
simard ooda run # run indefinitely
35+
simard ooda run --cycles=5 # run a fixed number of cycles
36+
```
37+
38+
Each cycle:
39+
40+
1. **Observe** — pulls signals from the goal register, open issues, gym scores, meeting handoffs, and memory consolidation pressure.
41+
2. **Orient** — ranks priorities and accounts for in-flight work to avoid duplicate dispatch.
42+
3. **Decide** — selects one action: `advance-goal` (spawn an engineer subprocess), `run-improvement` (self-improvement cycle), `run-gym-eval`, `consolidate-memory`, `research`, or `assess-only`.
43+
4. **Act** — for `advance-goal`, allocates a per-engineer git worktree under `~/.simard/engineer-worktrees/<goal-id>-<epoch>-<6hex>/` and spawns an isolated engineer subprocess.
44+
5. **Review** — runs the verify gate (`src/engineer_loop/verification.rs`) before any branch push and records the outcome in episodic memory.
45+
46+
Engineer subprocesses are first-class OS processes — independent LLM sessions with their own tool budget and worktree. The daemon does not block on them; it polls completion and applies the verifier on the next cycle.
47+
48+
Inspect and control a running daemon through the [Dashboard](#dashboard) or with:
49+
50+
```bash
51+
simard ooda status # last cycle summary
52+
simard goal-curation read # active goals + backlog
53+
simard improvement-curation read # pending improvements awaiting approval
54+
```
55+
56+
Full reference: [docs/daemon-mode.md](docs/daemon-mode.md) · How-to: [docs/howto/run-ooda-daemon.md](docs/howto/run-ooda-daemon.md) · Spawn semantics: [docs/howto/spawn-engineers-from-ooda-daemon.md](docs/howto/spawn-engineers-from-ooda-daemon.md).
57+
58+
## Memory architecture
59+
60+
Simard's memory is not a flat key-value store. She uses **six distinct memory types** modeled after cognitive psychology, implemented natively in Rust via `NativeCognitiveMemory` backed by LadybugDB (the `lbug` crate). There is no Python bridge — memory operations are direct LadybugDB calls.
61+
62+
| Type | Lifetime | What it holds |
63+
|------|----------|---------------|
64+
| **Sensory** | TTL ~300 s | Raw observations: PTY output, error messages, objective text. Auto-expires unless promoted. |
65+
| **Working** | Task-scoped | The 20-slot active task context: goal, constraints, plan steps, current execution state. |
66+
| **Episodic** | Persistent | "What happened this session" — every cycle, every action, every observation. |
67+
| **Semantic** | Persistent, deduplicated | Facts and concepts promoted from episodic memory. |
68+
| **Procedural** | Persistent, indexed by trigger | Action sequences that worked for a given situation. |
69+
| **Prospective** | Persistent, time/event-indexed | Future intentions ("when CI is green for #1209, post a follow-up"). |
70+
71+
Consolidation is automatic: working → episodic at task end; episodic → semantic / procedural when the OODA daemon dispatches a `consolidate-memory` action. Cross-session recall is automatic — when the daemon spawns a new engineer for a goal it seeds the engineer's working memory with the most relevant prior episodes for that goal-id.
72+
73+
On-disk layout: `~/.simard/memory/lbug/` (LadybugDB persistent store), `~/.simard/memory/working/`, `~/.simard/memory/sensory/`.
74+
75+
Multi-agent knowledge sharing inside a single Simard process is handled by the **hive event bus** (`src/hive_event_bus.rs`) — a `tokio::sync::broadcast` channel that every subsystem (memory consolidation, meeting facilitator, gym runner, engineer dispatcher) can publish to and subscribe from.
76+
77+
Operator-level summary: [docs/memory.md](docs/memory.md) · Canonical specification: [docs/architecture/cognitive-memory.md](docs/architecture/cognitive-memory.md).
78+
79+
## Dashboard
80+
81+
Simard ships a read-only web dashboard that surfaces what the autonomous OODA daemon is doing right now: the active goal register, recent cycle actions, open PRs and issues, the cognitive memory graph, live traces, costs, and per-process resource usage.
82+
83+
```bash
84+
simard dashboard serve --port=8080
85+
```
86+
87+
A login code is generated on first start and printed to stdout (also persisted to `~/.simard/.dashkey`). Subsequent visits to `http://localhost:8080/` redirect to a login page that accepts the code and sets a session cookie.
88+
89+
Tabs: **Overview** (daemon status, recent actions, open PRs, open issues), **Goals** (active register + backlog with promote/dismiss), **Traces** (live engineer subprocess and OODA cycle traces via xterm.js), **Logs**, **Processes** (live process tree), **Memory** (per-type filters + full-text search), **Costs**, **Chat**, **Whiteboard**, **Thinking** (planner output before action dispatch), **Terminal**.
90+
91+
### Overview
92+
93+
What the daemon did this cycle, top priority, recent actions, open PRs, open issues, system status:
94+
95+
![Dashboard overview](docs/assets/dashboard-overview.png)
96+
97+
### Goals
98+
99+
Active priorities and backlog with promote / dismiss controls:
100+
101+
![Goals tab](docs/assets/dashboard-goals.png)
102+
103+
### Memory
104+
105+
Six cognitive memory types with per-type filters, graph view, and full-text search:
106+
107+
![Memory tab](docs/assets/dashboard-memory.png)
108+
109+
Full reference: [docs/dashboard.md](docs/dashboard.md).
110+
111+
## Distributed operations
112+
113+
Simard's autonomous mode is *concurrent*: a single OODA daemon dispatches many engineer subprocesses in parallel on a single host, each in its own git worktree and its own LLM session. Coordination is via shared on-disk state (`~/.simard/goals/`, `~/.simard/memory/lbug/`) and the in-process hive event bus.
114+
115+
The hive event bus is **in-process only** — there is no built-in multi-host transport today. Operators who want to federate across hosts can stage `~/.simard/goals/` and `~/.simard/memory/` on shared storage and point each daemon's `--state-root` at the shared path; engineer worktrees stay host-local. A network transport for the hive bus is tracked in [#949](https://github.com/rysweet/Simard/issues/949).
116+
117+
Full reference: [docs/distributed-operations.md](docs/distributed-operations.md).
118+
29119
## Agent Base Types
30120

31121
An agent base type is the underlying execution substrate an identity can build on. It is **not** the identity itself. Simard composes work over a pluggable set of base types and refuses to instantiate identities on substrates that cannot satisfy required capabilities.
@@ -319,7 +409,12 @@ Pre-commit and pre-push hooks enforce `cargo fmt --all -- --check`, `cargo clipp
319409

320410
- [Product architecture (PRD)](Specs/ProductArchitecture.md)
321411
- [Documentation index](docs/index.md)
412+
- [Daemon mode (autonomous OODA loop)](docs/daemon-mode.md)
413+
- [Memory architecture](docs/memory.md)
414+
- [Dashboard](docs/dashboard.md)
415+
- [Distributed operations](docs/distributed-operations.md)
322416
- [Architecture overview](docs/architecture/overview.md)
417+
- [Cognitive Memory (canonical)](docs/architecture/cognitive-memory.md)
323418
- [Simard CLI reference](docs/reference/simard-cli.md)
324419
- [Runtime contracts reference](docs/reference/runtime-contracts.md)
325420
- [Base type adapters reference](docs/reference/base-type-adapters.md)

docs/assets/dashboard-goals.png

386 KB
Loading

docs/assets/dashboard-memory.png

579 KB
Loading

docs/assets/dashboard-overview.png

392 KB
Loading

docs/daemon-mode.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
title: Daemon mode (autonomous OODA loop)
3+
description: How Simard runs as a long-lived process, observing signals, ranking priorities, dispatching engineer subprocesses, and coordinating distributed work.
4+
last_updated: 2026-04-24
5+
owner: simard
6+
doc_type: concept
7+
---
8+
9+
# Daemon mode (autonomous OODA loop)
10+
11+
When Simard is launched in daemon mode she becomes a long-lived process that runs the **Observe → Orient → Decide → Act → Review** loop on a timer. Each cycle she inspects the goal register and the world (issues, gym scores, meeting handoffs, memory consolidation pressure), ranks priorities, selects an action, dispatches it through one of her base-type adapters, and records the outcome.
12+
13+
Daemon mode is what makes Simard *autonomous* rather than *interactive*. It is the same code path that operator-driven sessions use; the only difference is that the daemon is the operator.
14+
15+
## Start the daemon
16+
17+
```bash
18+
# Run a fixed number of cycles (good for smoke tests)
19+
simard ooda run --cycles=5
20+
21+
# Run indefinitely
22+
simard ooda run
23+
```
24+
25+
The daemon sleeps `60s` between cycles by default and emits a one-line summary of each cycle to stderr. Dashboard cycle numbers map 1:1 to these iterations.
26+
27+
For a full how-to including systemd-user installation, see [Run the OODA daemon](howto/run-ooda-daemon.md).
28+
29+
## What the daemon observes
30+
31+
Each cycle she pulls signals from:
32+
33+
- **Goal register**`simard goal-curation` priorities and the proposed backlog.
34+
- **Open issues**`gh issue list` against the tracked repository.
35+
- **Gym scores** — recent benchmark results and any regressions vs. baseline.
36+
- **Meeting handoffs** — files written by `simard meeting repl` that mark decisions ready for engineering.
37+
- **Memory consolidation pressure** — when working memory crosses thresholds, a consolidation action is preferred over a new engineer dispatch.
38+
- **In-flight work** — already-running engineer subprocesses are skipped to avoid duplicate dispatch.
39+
40+
## Actions she can take
41+
42+
The daemon dispatches one action per cycle. Action kinds include:
43+
44+
| Action | What it does |
45+
|--------|--------------|
46+
| `advance-goal` | Spawn an `engineer` subprocess in a per-engineer worktree and let it pursue a single bounded task. |
47+
| `run-improvement` | Run a self-improvement cycle (eval → analyze → improve → re-eval). |
48+
| `run-gym-eval` | Execute a benchmark scenario and record results. |
49+
| `consolidate-memory` | Promote working / episodic items into semantic / procedural memory. |
50+
| `research` | Issue a focused research query and persist findings. |
51+
| `assess-only` | When a goal cannot be safely dispatched (e.g. ambiguous scope), record the assessment and defer. |
52+
53+
Each engineer dispatch:
54+
55+
1. Allocates a per-engineer git worktree under `~/.simard/engineer-worktrees/<goal-id>-<epoch>-<6hex>/` so concurrent engineers cannot collide.
56+
2. Spawns the engineer subprocess with that worktree as its CWD.
57+
3. Verifies the engineer's output via the `verify` gate (`src/engineer_loop/verification.rs`) before any branch push.
58+
4. Records the cycle in episodic memory and updates the goal status.
59+
60+
## Engineer subprocesses
61+
62+
Engineer dispatches are first-class subprocesses — independent OS processes with their own LLM session, tool budget, and worktree. The daemon does not block on them; it polls completion and applies the verifier on next cycle.
63+
64+
For the worktree contract see [Inspect and clean engineer worktrees](howto/inspect-and-clean-engineer-worktrees.md). For the spawn semantics see [Spawn engineers from the OODA daemon](howto/spawn-engineers-from-ooda-daemon.md).
65+
66+
## Inspect and control
67+
68+
Operators interact with a running daemon through the dashboard ([Dashboard](dashboard.md)) and the CLI:
69+
70+
```bash
71+
simard ooda status # last cycle summary, current state
72+
simard goal-curation read # active goals + backlog
73+
simard improvement-curation read # pending improvements awaiting approval
74+
```
75+
76+
## Distributed operation
77+
78+
A single daemon coordinates many engineer subprocesses on the same host through per-engineer worktrees and a shared goal register. For multi-host operation see [Distributed operations](distributed-operations.md).
79+
80+
## Formal contract
81+
82+
The end-to-end OODA contract — including the durable goal-board format, the verify gate, the priority ranking, and the in-flight dedup — is specified in [Specs/ProductArchitecture.md](https://github.com/rysweet/Simard/blob/main/Specs/ProductArchitecture.md). Code-level entry points:
83+
84+
- `src/operator_commands_ooda/daemon.rs` — the loop itself
85+
- `src/engineer_worktree/mod.rs` — per-engineer worktree allocation and orphan sweep
86+
- `src/engineer_loop/verification.rs` — the verify gate
87+
- `src/self_improve/cycle.rs` — improvement-cycle action
88+
89+
## Related
90+
91+
- [Dashboard](dashboard.md) — observe a running daemon
92+
- [Memory architecture](memory.md) — what the daemon writes between cycles
93+
- [Run the OODA daemon (how-to)](howto/run-ooda-daemon.md)
94+
- [Spawn engineers from the OODA daemon](howto/spawn-engineers-from-ooda-daemon.md)

docs/dashboard.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: Dashboard
3+
description: Read-only web dashboard for inspecting the autonomous OODA daemon, goal register, memory layers, processes, costs, and live traces.
4+
last_updated: 2026-04-24
5+
owner: simard
6+
doc_type: howto
7+
---
8+
9+
# Dashboard
10+
11+
Simard ships a read-only web dashboard that surfaces what the autonomous OODA daemon is doing right now: the active goal register, recent cycle actions, open PRs and issues, the cognitive memory graph, live traces, costs, and per-process resource usage. It is the primary operator-visible surface when Simard is running in daemon mode.
12+
13+
## Start the dashboard
14+
15+
```bash
16+
simard dashboard serve --port=8080
17+
```
18+
19+
A login code is generated on first start and printed to stdout. It is also persisted to `~/.simard/.dashkey` for re-use. Subsequent visits to `http://localhost:8080/` redirect to a login page that accepts the code and sets a session cookie.
20+
21+
## Tabs
22+
23+
The dashboard is a single-page app with the following tabs:
24+
25+
| Tab | Shows |
26+
|-----|-------|
27+
| **Overview** | Daemon status (OODA loop active / stopped), current cycle number, top-priority goal, last cycle's actions, recent actions stream, system status (version, OODA daemon state, active processes, disk usage), open PRs, and open issues. |
28+
| **Goals** | The full goal register: active top-N goals with priority, status, and current activity; the proposed backlog with promote/dismiss controls. |
29+
| **Traces** | Live-tailed engineer subprocess traces and OODA cycle traces (xterm.js terminal). |
30+
| **Logs** | Aggregated daemon and engineer logs. |
31+
| **Processes** | Live process tree under the daemon — engineer subprocesses, LLM sessions, and their resource usage. |
32+
| **Memory** | Cognitive memory graph (Working / Semantic / Episodic / Procedural / Prospective / Sensory) with per-type filters; full-text memory search; memory overview and per-type file listings. See [Memory architecture](memory.md). |
33+
| **Costs** | Per-provider, per-model token spend across the active session. |
34+
| **Chat** | Direct chat with Simard. |
35+
| **Whiteboard** | Shared scratch canvas. |
36+
| **Thinking** | Live thinking-cycle stream (planner output before action dispatch). |
37+
| **Terminal** | Browser-attached PTY into the daemon host. |
38+
39+
## Screenshots
40+
41+
Overview — what the daemon did this cycle, top priority, recent actions, open PRs, system status, open issues:
42+
43+
![Dashboard overview](assets/dashboard-overview.png)
44+
45+
Goals — active priorities and backlog:
46+
47+
![Goals tab](assets/dashboard-goals.png)
48+
49+
Memory — six cognitive memory types with filters and search:
50+
51+
![Memory tab](assets/dashboard-memory.png)
52+
53+
## Read-only
54+
55+
The dashboard does not let operators force shell commands or edit code through the browser. Goal promotion, status changes, and refresh are the only state-changing operations. All other panels are observational.
56+
57+
## Related
58+
59+
- [Daemon mode (autonomous OODA loop)](daemon-mode.md)
60+
- [Memory architecture](memory.md)
61+
- [Run the OODA daemon](howto/run-ooda-daemon.md)
62+
- [Dashboard E2E tests](reference/dashboard-e2e-tests.md)

docs/distributed-operations.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Distributed operations
3+
description: How Simard coordinates many engineer subprocesses concurrently on one host today, and what the architecture leaves open for multi-host extension.
4+
last_updated: 2026-04-24
5+
owner: simard
6+
doc_type: concept
7+
---
8+
9+
# Distributed operations
10+
11+
Simard's autonomous mode is *concurrent*: a single OODA daemon dispatches many engineer subprocesses in parallel, each in its own git worktree and its own LLM session. This page describes what is true today and what is explicitly not.
12+
13+
## What is distributed today
14+
15+
**Multi-engineer concurrency on a single host.** A running daemon can have many engineer subprocesses in flight simultaneously. They are coordinated through:
16+
17+
- **Per-engineer git worktrees** under `~/.simard/engineer-worktrees/<goal-id>-<epoch>-<6hex>/` — each engineer gets an isolated checkout so concurrent edits never collide on the working tree. The orphan-sweep guard in `src/engineer_worktree/mod.rs` reclaims worktrees only when their owning subprocess is no longer alive.
18+
- **Shared goal register** at `~/.simard/goals/` — the daemon's single source of truth for what each engineer is supposed to do. In-flight goals are marked busy so they cannot be double-dispatched.
19+
- **In-process hive event bus** (`src/hive_event_bus.rs`) — a `tokio::sync::broadcast` channel that every in-process subsystem (memory consolidation, meeting facilitator, gym runner, engineer dispatcher) can publish to and subscribe from. This is the substrate for cross-agent knowledge sharing.
20+
- **Shared cognitive memory** (LadybugDB at `~/.simard/memory/lbug/`) — semantic, procedural, and prospective layers are visible to every engineer dispatch on the host.
21+
22+
The dashboard's **Processes** tab makes this concurrency visible: the live process tree, per-engineer worktree paths, and per-process resource usage are all surfaced in real time. The **Active Processes** counter on the Overview tab shows how many child processes the daemon currently owns.
23+
24+
## What is *not* distributed today
25+
26+
**The hive event bus is in-process only.** From `src/hive_event_bus.rs`:
27+
28+
> The bus is **in-process only**. It does not cross process or machine boundaries. A future workstream may add a network adapter that bridges this bus to a remote transport; nothing in this module assumes one.
29+
30+
There is no built-in multi-host transport. Two daemons running on two different hosts do not share an event bus, do not share working/sensory memory, and do not coordinate goal dispatch through any network protocol that ships in the binary today.
31+
32+
## What you can do across hosts (out-of-band)
33+
34+
The on-disk artifacts under `~/.simard/` are designed so operators can manually federate state when they want to:
35+
36+
| Artifact | Path | Federation pattern |
37+
|----------|------|--------------------|
38+
| Goal register | `~/.simard/goals/` | Stage on shared storage (NFS / object store) and have each daemon point its `--state-root` there. Goal-locking is file-based. |
39+
| Persistent memory | `~/.simard/memory/lbug/` | Single-writer; safe to snapshot and rsync between hosts when no daemon is writing. Cross-session recall works after restore. |
40+
| Engineer worktrees | `~/.simard/engineer-worktrees/` | **Do not share across hosts** — worktrees are bound to the host's filesystem and process table. |
41+
| Gym results | `~/.simard/gym/` | Append-only JSONL; safe to merge between hosts. |
42+
| Cost ledger | `~/.simard/costs/` | Append-only JSONL; safe to merge. |
43+
44+
A common pattern is one "primary" daemon host that owns the goal register and persistent memory, and ephemeral "worker" hosts that mount the same `~/.simard/goals/` and `~/.simard/memory/` over a network filesystem and run engineer dispatches against shared state. This is operator-assembled today, not a built-in feature.
45+
46+
## What is on the roadmap
47+
48+
A network transport for the hive event bus, plus a goal-dispatch lock service, would turn the multi-engineer concurrency model into a true multi-host one without changing the agent code paths. Tracking issue: [#949](https://github.com/rysweet/Simard/issues/949).
49+
50+
## Code entry points
51+
52+
- `src/operator_commands_ooda/daemon.rs` — the cycle that dispatches engineers
53+
- `src/engineer_worktree/mod.rs` — per-engineer worktree allocation and orphan sweep
54+
- `src/hive_event_bus.rs` — in-process pub/sub
55+
- `src/memory_hive.rs` — hive-aware memory layer
56+
57+
## Related
58+
59+
- [Daemon mode (autonomous OODA loop)](daemon-mode.md)
60+
- [Memory architecture](memory.md)
61+
- [Inspect and clean engineer worktrees](howto/inspect-and-clean-engineer-worktrees.md)

0 commit comments

Comments
 (0)