Appearance
Smithers vs the agent platform
It is easy to confuse Smithers with "the agent platform." They overlap. They are not the same thing. This page makes the boundary explicit and explains how each side depends on the other.
Substrate framing: the agent platform (system.agents, system.inference, the provider drivers, system.factotum) is substrate-side infrastructure — the cognitive runtime any vertical can use. Smithers is vertical-side — one specific developer-facing app built on top of that infrastructure. The substrate is general-purpose; the vertical is opinionated.
What "the agent platform" is
The Matrix agent platform (informal name) consists of these actors and packages, none of which Smithers owns:
| Actor / package | Role |
|---|---|
system.inference | Routes inference requests through @open-matrix/inference-catalog. Resolves provider credentials (Codex, Claude, Anthropic API key) without callers ever seeing a key. |
system.agents | Generic session-based agent runtime. Owns session lifecycle, transcript, runtime status. Smithers can dispatch to it; Smithers does not own it. |
@open-matrix/codex-agent / @open-matrix/claude-agent | SDK worker packages that register themselves as runtimes capable of serving agent sessions. Smithers calls them via system.agents. |
@open-matrix/chat | The default, generic chat workbench. A user can talk to any actor through it. Not a Smithers competitor. |
system.factotum | Credential gatekeeper. The ONE actor that reads/writes credential files (per project Rule 4). Smithers' inference resolution goes through it. |
These exist whether or not Smithers is installed. They are general-purpose.
What Smithers adds
Smithers is specifically about constraint-convergence orchestration. It does not:
- Implement an inference adapter. It uses
@open-matrix/inference-catalogandomega-lisp/piai. - Own session storage. When dispatching to an SDK worker (
SmithersSupervisor._stopSdkWorkerSession,_readAgentSessionState,_appendAgentOutputFromSessionTrace), it readssystem.agentssession state. - Manage credentials.
_resolvePiAiConfiginCodingAgent.ts:213-264resolves credentials by calling intoinferenceCatalog.createInferenceConfigwhich in turn flows throughsystem.inferenceand Factotum.
Status note: cross-package import boundary.
CodingAgent.ts:219does an in-processawait import('@open-matrix/inference-catalog')instead of routing through the bus tosystem.inference. This is a known intentional design — tracked as P1.6 — and is not yet resolved. It means Smithers' inference path is currently substrate-aware (it knows aboutinference-catalogas a workspace package) rather than purely substrate-routed (every call throughsystem.inference). Don't pretend this is fully fixed when reading the rest of this page; the bus contract is the target, the in-process import is the present.
Smithers does add:
| Responsibility | Where in source |
|---|---|
| Constraint gathering and projection | ConstraintGraph (src/actors/ConstraintGraph.ts) |
| GitHub issue ingestion + parsing | GitHubAdapter (src/actors/GitHubAdapter.ts) |
| Convergence-loop orchestration | SmithersSupervisor.onSmithersStart |
| Sign-off forcing function | SmithersSupervisor.onSmithersSignOff |
| Parallel review barrier | ReviewerAgent (src/actors/ReviewerAgent.ts) |
| Ratchet of satisfied constraints | RatchetStore (src/actors/RatchetStore.ts) |
| Issue-actor lifecycle | IssueActor (src/actors/IssueActor.ts) |
| Local CodingAgent fallback | CodingAgent (src/coding-agent/CodingAgent.ts) — used when no SDK worker is registered |
| Container management for isolated agents | ContainerManager (src/actors/ContainerManager.ts) |
| Workspace UI state | WorkspaceActor (src/actors/WorkspaceActor.ts) |
| Workstream-request inbox | SmithersSupervisor._workstreamRequests |
Two execution paths for the coding agent
Smithers' supervisor runs the agent through one of two paths, decided at dispatch time (see SmithersSupervisor.ts around the SDK worker selection logic):
Path A — Local CodingAgent
Smithers spawns its own CodingAgent actor inside the same Node process. It:
- Resolves
PiAiConfigthroughinferenceCatalog.createInferenceConfig. - Builds a
streamingOracleshell tool (one tool — Unix-native shell) and runs the LLM tool loop in-process. - Streams
code.eventactivity frames; the supervisor subscribes and forwards them to the browser via the activity bus.
This path requires Docker only if container.runtime: 'docker' is configured AND the user explicitly asks for a containerised run; otherwise everything runs on the local filesystem.
Path B — SDK worker (@open-matrix/codex-agent / claude-agent)
When a registered SDK worker is available, Smithers prefers it. It:
- Looks up an
SdkWorkerRefinsystem.runtimes. - Creates a session in
system.agentsand dispatches the constraint-convergence prompt to that session. - Reads transcript and runtime status back through
system.agentsops; on completion, extracts evidence withevidence-extraction.ts.
Path B is what the productization story rests on (P2.6-smithers-productize.md):
Spawn container button → real container starts. Send prompt → worker session starts, ActivityFrame events stream to UI. Steer / interrupt / continue all work. Session persistence verified across page reload.
Container manager scope
ContainerManager (src/actors/ContainerManager.ts:81-120) is a Docker control surface used by the SDK worker path. It:
- Subscribes to a heartbeat subject (
mx.discovery.heartbeat) and prunes offline containers every 15s. - Tracks
WorkerRecord[]per container — each container can host multiple worker actors of kindcodexorclaude-code. - Provides
container.spawn,container.stop,container.list,container.remove,container.imagesops.
This is not generic Docker tooling. It is specifically the actor that ContainerManager exposes for Smithers to manage worker containers. The wider Matrix platform does not depend on it.
Why the worker-isolation audit gates Smithers
P2.5-worker-isolation-audit.md says:
SDK worker integration merged.
prove-sdk-worker-container.tsconfirms a container can spawn and workers register. But the security model — what filesystem, what network, what host calls a worker can make — is unaudited.
The required audit areas are filesystem scope (cwd/repo roots), shell permissions, NATS credential isolation, network egress policy, approval policy, and heartbeat anti-spoofing. Until those gates close, Smithers is allowed only as a local-Vite proof; no public Smithers/Codex/Claude demo is possible without the audit.
Quick decision table
| If you want to | Use | Notes |
|---|---|---|
| Run an agent on a single one-off task | system.agents directly (or chat) | No constraint orchestration, no review barrier |
| Run a one-off task with structured constraints | Smithers (smithers.start) | Even single-issue runs benefit from the sign-off and ratchet |
| Plug in a new LLM provider | @open-matrix/inference-catalog | Smithers reads from there; do not add a Smithers-specific provider path |
| Add a new agent runtime (e.g., a third SDK) | Add a sibling to codex-agent / claude-agent | Smithers will discover it via system.runtimes and use it through system.agents |
| Audit and harden agent isolation | P2.5 audit + ContainerManager + system.factotum | The audit feeds into ContainerManager constraints, not Smithers' app code |
See also
Source:
WORKSTREAMS/loose-ends/items/P2.6-smithers-productize.md,WORKSTREAMS/loose-ends/items/P2.5-worker-isolation-audit.md,projects/matrix-3/packages/smithers/src/coding-agent/CodingAgent.ts:179-264,projects/matrix-3/packages/smithers/src/actors/ContainerManager.ts:81-120.