Rho architecture
Rho is the application container for an intelligent workspace. Functional components provide what users and Agents do; Rho connects their interfaces and resources to a shared workspace. Agents use their native tools normally, with existing permissions. Core supplies optional managed execution and retained activity observations; it is not a prerequisite for an Agent computation.
This document defines the design boundary. Status records implementation; Technology stack records the selected libraries.
Source owners
| Owner | Responsibility |
|---|---|
| Rho-core | Managed execution, original request identity, retained execution facts, resident Host and public CLI |
| Rho-plugins | Actual functionality, native conditions, resource semantics and results; optional CLI, Skills, MCP and UI entries |
| Rho | Component selection and assembly, local service, layout, shared interaction routing and presentation; native windows in a later client |
A functional component may be an Agent bridge, editor, file tool, runtime/object adapter, table, media/chart view or reusable native operation. It can use maintained R, Python, Rust, TypeScript, native tools or ordinary files. Components expose the entries their consumers need, with the same implementation and conditions across those entries. Managed execution entries preserve the original request identity.
The Plugins capability model defines reusable plugin ownership and optional entries. A plugin may contribute several views over one state owner. Specific analysis workflows remain project scripts/recipes or acceptance examples; their dataset, design, contrast and sequencing do not belong in the base catalog or application routing. The extraction plan records removal of the 0.1 coupling and the gates before plugin UI integration. The 0.4 application selects eight independent plugin packages and retains the 0.2 action/view contracts; extraction acceptance records their actual consumers.
Each component declares the schemas of the operations it owns in a pure package entry (./operations), which carries no implementation. Rho snapshots those entries with the selected package version and entry digest, and its served contract is assembled from that snapshot plus the operations Rho itself owns. An absent component stays describable from the snapshot; it is never imported, activated or installed to answer a question about its contract. Public request/response types and the method map are generated from the served contract, so both clients and the service request boundary are checked against one definition.
A headless caller uses the component's supported entry. Rho assembles its views and actions; selected managed execution uses Core's public capability. An Agent component owns its model loop and context. Core remains independent of UI bundles and model interaction. Each repository delivers and verifies its own boundary.
The application is an npm-distributed local service and browser WebUI. The browser reaches scoped application operations through that service; it does not invoke Core or native tools directly. The service uses Core's public CLI for explicitly selected managed operations and Host activity. A missing Core binary does not block workspace startup or native Agent tools. A later desktop client reuses these component and execution boundaries and adds native window and system integration.
Interaction model
Four concepts connect components to the container. The finite 0.2 backend exposes their concrete operation contracts, HTTP/SSE service and client. Plugins supplies independently packaged headless owners. Rho selects a finite allowlisted package list, checks versions/service requirements and injects typed ports. Missing packages report unavailable; they are not installed implicitly. Registered owner views are rendered by the browser application. Headless backend records the actual boundary and persistence rules. Scripts, requirements, typed fields, keys, entity namespaces and two-input joins are explicit declarations. Retained records stay observable through the same contract, which does not register their earlier workflow for new work.
| Concept | Meaning |
|---|---|
| Action | Component/action identity, typed inputs, preconditions, effects, results and cancellation semantics; managed identity where applicable |
| Resource | Owner-provided reference to a file, buffer, table, plot, model or task, with provenance and the content version or digest it needs |
| Selection | Stable entities or ranges in a particular resource version, with explicit project/view context |
| View | Presentation of resources, registered actions and observation subscriptions, with an explicit release lifecycle |
Agent tools, UI controls and CLI adapters reach the same component action. The invocation boundary checks existing authorization, caller/project visibility, resource validity and native preconditions. A resource reference does not grant access to its parent directory. Models and retrieved content cannot expand scope; already authorized actions do not receive an additional container approval.
Tables and charts use provider-declared stable keys and explicit field mappings. Linking different resource versions or entity spaces requires an owner-validated mapping. Sorting and filtering do not turn visible row positions into identifiers. Stale selections are rejected or explained before they affect data or execution. Image coordinates have their own contract; image viewing does not imply data entity selection. R objects require actual runtime-owned descriptors/snapshots; a resident Core Host alone does not establish a live R session.
State and lifecycle ownership
| State or fact | Owner |
|---|---|
| Managed request, native execution identity, partial/unknown outcomes and retained execution facts | Core within its documented contract |
| Functional resources, provenance, domain identities, conditions and checks | Actual functional component |
| Unsaved document, local content version, undo and write-conflict checks | Editing component's document service |
| Selection/filter meaning | Participating component; Rho routes the explicit context |
| Window arrangement, active view and component availability | Rho |
| Cursor, scrolling and rendering resources | Individual view as appropriate |
| Agent session and model context | The Agent runtime owns model context; Rho retains session identity and bounded observations |
| A session's input and conversation record | Whoever started the session: its own window, or Rho |
Multiple views of a document share one logical unsaved-buffer owner. Switching tabs or moving a view between splits preserves content and undo; the later desktop client extends this to native windows. Saving checks external writes; disk files and Git history do not substitute for the current buffer. Versions and provenance belong to individual resources, with no global scientific revision. project.work.read is a linked application observation of those owners: conversation and native stream identities, Agent-reported progress, file observations and the shared Documents buffer. Its cursor is an invalidation cursor, not a transaction or a common resource version. ACP and native transcript identities are not merged merely because their ID strings match.
Each Agent session has one input, held by whoever started it (the user's decision of 2026-10-25). A session started outside Rho keeps its input in its own window; Rho shows its work; feedback uses the separately selected feedback entry. A conversation started in Rho is held by Rho: the Agent panel is its input, and the conversation outlives the panel, a reload and a service restart. A message whose outcome Rho did not observe stays unknown and is not sent again. Agent 0.4.11 owns the Claude and Codex ACP connections, permission requests and session loading; it retains each tool's bounded human title, ACP category and identifying input so the application can present the action without reading native output. Rho owns the durable message identity, transcript and local input. Rho MCP calls retain their project grant; Native tools retain their Agent's own permissions and OS authority. ACP session IDs are kept separately from unobserved native transcript IDs. Core is unchanged. The ACP episode records the actual cancellation and recovery scope. An external client can select the Agent plugin's stdio relay to expose a bounded session projection under its project. Rho reads that projection without acquiring the input, permissions or process lifetime. Existing sessions load in their original client; an uninstrumented running client has no generic passive ACP attachment. External connections have independent sequences and heartbeat observations; the application cursor is not a global clock for their updates.
Execution continuity
A resident Host is held independently of observing windows and renderers. Closing a view releases its subscriptions and drawing resources. Agent-session closure, task cancellation, confirmed native stop and Host shutdown are distinct events. The application makes their effects explicit.
After a missing submission acknowledgement, retain the original caller/request identity and query or retry that identity through the public boundary. Reconnect observes the original task rather than automatically submitting another execution. Partial results and unknown outcomes remain visible. Bounded reads do not start or recover a Host or native session.
Execution completion, artifact integrity, domain checking and model explanation are separate facts. Components interpret their own outputs and expose the scope and freshness of checks. Core output streams serve bounded observation; scientific artifacts use the component's declared files, manifests and checkers.
The application side of the Core boundary, namely request identity, the exit-code state machine, Host lifetime and bounded observation, is owned by the execution bridge.
Interface composition
A functional component owns its UI entry source: the view implementation, its typed properties and its action bindings live with the component in the component owner's repository. Rho builds those views into the application at explicit component versions and supplies theme, commands, layout and interaction routing. Rho does not hold a second implementation of a component's behavior. The selected editor, table and plot entries are implemented; Status records their verification scope.
Trusted React views are built with the application at explicit component versions. An external UI package may contribute a full view over an existing capability using a JSON manifest and an explicit pinned build selection. The same metadata registers its props/bindings with the service and its renderer with the browser. No UI module executes on the server. This adds no backend methods, package discovery or runtime code loading; Plugin authoring documents the path. An Agent describes a composition using a typed catalog of registered components, properties and scoped action/resource/selection references. The container validates that description, then routes actions to their actual owner.
Agent proposals carry intent and exact references; they do not grant execution or layout authority. Use existing conditional composition operations and protection. Current input, protected bindings and historical versions retain their identities; unavailable or stale proposals leave the existing work intact. Already authorized actions receive mechanical checks without a second container approval.
Generated descriptions do not load privileged JavaScript. Schema validity does not establish authorization, resource freshness or scientific correctness. Independent HTML views can use isolated MCP Apps with a controlled message/tool bridge, validated origin/CSP and explicit teardown. UI isolation does not sandbox the OS authority of native tools; Core caller namespaces are not authenticated principals. See Security.
Resource limits
Rho bounds the resources it actually owns and names the exceeded-limit behavior. The headless owners expose the selected defaults and exceeded-limit behavior in backend budgets. Browser drawing and rendering budgets still need their actual UI implementation; the application does not invent a global quota for the user's environment.
| Protected resource | Configuration | Exceeded-limit behavior |
|---|---|---|
| Retained process output rendered per view | Bounded log-view budget | Stop appending, keep the retained prefix visible and mark the stream truncated |
| Table rows/pages requested per view | Page size | Fetch bounded pages on demand; keep the pages already obtained |
| Plot points/series drawn per view | Drawing budget | Reduce drawn marks within the budget and mark the reduction |
| Concurrent component actions | Action-concurrency limit | Queue or reject explicitly; never start work under a new identity |
| Observation subscriptions per view | Subscription limit | Refuse the extra subscription and explain the limit |
| Retained Agent-composed message bytes | Message budget | Reject an oversized description before rendering |
Exhausting a view resource preserves obtained output and uncertainty. It does not stop unrelated execution, stop a user Host or replay a task.
Application composition
An accepted combination records immutable source/artifact identities, dependency versions, third-party origins/licenses, explicit local overrides and the observed results of the integrated flow.
A missing or upgraded component retains enough version and provenance information to inspect existing runs and outputs. Layout restore preserves references and reports unavailable content without claiming that a buffer was saved or a task recovered. View failure does not replay actions.
Source publication, composition acceptance and signed distribution have their own evidence. The release boundary promotes an accepted candidate when an official delivery milestone is selected.