Architecture flows

Subsystem diagrams for Rabbot. See AGENTS.md for the repo map and PLUGIN_INDEX.md for command wiring.


Plugin build pipeline

Dr_Weird proposes ideas; Steve holds a veto window; a human admin must run !rabbot plugin on Rabbot (bots cannot auto-build).

flowchart LR
  DrWeird --> Steve
  Steve --> VetoWindow
  VetoWindow --> HumanAdmin
  HumanAdmin --> RabbotCmd["!rabbot plugin"]
  RabbotCmd --> MetaAgent["RabbotMetaAgent"]
  MetaAgent --> MetaBuild["RabbotMetaBuild"]
  MetaBuild --> NewPlugin["plugins/new.rb + test"]

Read when changing builds: plugins/rabbot_meta.rb, lib/rabbot_meta_agent.rb, lib/rabbot_meta_build.rb, lib/channel_trust.rb.

Steve-side coordination: plugins/build_coordinator.rb, plugins/veto.rb, lib/room_reader.rb.


AI chat (!ai)

User-initiated AI requires voice, op, or registered voice level (AiAccess). All loaded bots may respond unless scoped to owner.

flowchart LR
  User --> AiPlugin["plugins/ai.rb"]
  AiPlugin --> AiAccess
  AiAccess --> AiChatCore
  AiChatCore --> AiAgent
  AiAgent --> CursorCLI["cursor-agent CLI (chat lane lock)"]

Chat AI (!ai, !rabbot ai, !aip) and plugin builds (!rabbot plugin) use separate CursorAgentRunner file locks (rabbot-cursor-agent-chat.lock vs rabbot-cursor-agent-build.lock) so IRC chat can run while a long build is in progress.

Read when changing AI replies: lib/ai_chat_core.rb, lib/ai_agent.rb, lib/ai_context.rb.

Plan mode (!aip) uses lib/ai_plan_agent.rb and lib/ai_plan_session.rb instead.


Directchat mesh

Users PM a bot with !directchat to bridge a private multi-party chat across bots on a TCP mesh.

flowchart LR
  UserPM --> DirectchatPlugin["plugins/directchat.rb"]
  DirectchatPlugin --> DirectchatSession
  DirectchatSession --> DirectchatWire
  DirectchatWire --> DirectchatMesh
  DirectchatMesh --> PeerBot

Read when changing relay: lib/directchat_mesh.rb, lib/directchat_wire.rb, lib/directchat_session_codec.rb.

Wire frame shapes: lib/CONTRACTS.md.


Thin plugin pattern (search plugins)

Most lookup plugins delegate to a search module that returns an IRC string via a report module.

flowchart LR
  IRC["IRC message"] --> Plugin["plugins/foo.rb"]
  Plugin --> LibSearch["lib/foo_search.rb"]
  LibSearch --> LibReport["lib/foo_report.rb"]
  LibReport --> IrcReply["IrcReply.card"]

Example: plugins/auslib.rbAuslibSearch.lookupAuslibReport.build_*.

Shared catalogue helpers: lib/search_query.rb, lib/search_report.rb.


Multi-bot process layout

flowchart TB
  subgraph console [bot_console TUI]
    RabbotProc[Rabbot process]
    SteveProc[Steve process]
    WeirdProc[Dr_Weird process]
  end
  config[config/bots/*.yml] --> RabbotProc
  config --> SteveProc
  config --> WeirdProc
  RabbotProc --> IRC[Undernet IRC]
  SteveProc --> IRC
  WeirdProc --> IRC

Read when changing startup: lib/rabbot_app.rb, lib/bot_console.rb, script/run_bots.