Add worker-level message flow topology with force-directed graph
visualization on a dedicated /topology web page.
- topology.rs: worker_topology() derives graph from cross_sends/local_sends
stats (TopologyNode, TopologyEdge, TopologySnapshot)
- /topology page with interactive force-directed graph layout:
- Nodes sized by actor count, colored by worker
- Edges show local sends (green self-loops) and cross-worker sends (blue)
- Edge thickness proportional to message volume
- Physics simulation with repulsion, attraction, and gravity
- SSE "topology" event emitted every ~1s (every 5th stats tick)
- /api/topology REST endpoint for on-demand snapshot
Infrastructure ready for future per-actor topology with core instrumentation.
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
Add automated detection of 6 runtime anomaly types with severity levels:
- PoisonedActor (critical): actor panicked
- StalledActor (high): no message processing while mailbox > 0
- GrowingMailbox (medium): consecutive increases in mailbox depth
- MailboxOverflow (medium): messages dropped (backpressure triggered)
- WorkerImbalance (low): one worker has >2x average actor count
- EmptyWorker (low): worker has 0 actors while others have many
Configurable thresholds with sensible defaults. 7 scenario tests covering
all warning types, threshold behavior, and streak reset logic.
Web: warning banner at top of overview page with severity-colored alerts
TUI: warning count in summary bar (yellow when active)
SSE: new "warnings" event sent with each stats tick
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
Replace the basic canvas bar chart on the web overview with rich worker
cards showing:
- Stacked phase-timing bars (processing/delivery/spawns/overhead)
- Load percentage derived from tick timing active ratio
- Inline sparklines from history (message rate trends)
- Actor count, messages processed, mailbox depth stats
- Color legend for phase identification
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
TUI:
- Press / to enter search mode (vim-style), type to filter actors in
real-time by address, message type, or worker ID
- Enter locks the filter, Esc clears it
- Navigation bounds respect filtered results
Web (actors page):
- Worker dropdown filter (dynamically populated from live data)
- Status filter (All / Healthy / Poisoned)
- Mailbox depth threshold filter (min depth)
- Text search now also matches message type names
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
Add dedicated actor detail page accessible from both web and TUI surfaces.
Web:
- /actor/<hex> page with live-updating stats, sparkline charts for message
rate and mailbox depth, status badge, worker assignment
- Actor addresses in overview and actors pages now link to detail page
- Actors page detail panel links to dedicated detail page
TUI:
- ViewMode::ActorDetail with per-actor sparklines (rate + mailbox)
- Enter on actor row opens detail, Esc returns to previous view
- Per-actor ring buffer history (60 samples) tracked in App state
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
Add in-process ring buffer history for per-worker and per-actor stats,
with sparkline rendering on both web (SVG) and TUI (ratatui) surfaces.
- history.rs: DashboardHistory with bounded VecDeque ring buffers, LRU
actor eviction, thread-safe RwLock, 4 unit tests
- SSE producer records stats every tick, sends initial history snapshot
- /api/history REST endpoint for on-demand history JSON
- Web: inline SVG sparklines in worker detail headers (rates + mailbox)
- TUI: per-worker Sparkline widgets in overview layout
Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
Runtime dashboard now features a TUI option and an interface for LLM tool use. Removed some bloat from stats collecting and replaced with a hook function to dump runtime stats into.
Adds some basic benchmarking, stress tests. They still need to be properly examined to ensure they are testing the correct properties, but fit for "good enough". Implements the HybridChannel type, which features a channel buffer that can withstand overflows. It does so by providing a dequeue behind a mutex. Without overflow, will push messages into the lock free ArrayQueue implemented by crossbeam_queue; when that buffer fills, will use the locking portion provided by the Mutex<VecDequeue>.
In the future we can even further optimize this, perhaps with some linked list implementations of lock-free channels, but, like the benchmarks, this fits the "good enough" bar for now.
Did not like the requirement of a tokio runtime and async/await. Rewrote
to use lock free queues (`crossbeam_queue::ArrayQueue`) as the basic
primitive to enable a runtime consisting of many pseudo-processes that
can pass messages to each other.
Co-authored-by: Zachery Aaron Shores-Chmielewski <zachanon@gmail.com>
Reviewed-on: http://zachery.lol/code/code/zacheryasc/swactor/pulls/1