# Hematite Architecture
This is the short contributor map of Hematite's current runtime boundaries.
The goal is simple:
- `conversation.rs` should orchestrate turns
- specialized modules should own their own policy or explanation logic
- the TUI should render runtime truth, not invent it
- LM Studio should remain the local model runtime, not the product brain
- recurring workflow structure should live in the harness when local models are not dependable enough to infer it every turn
## Core Boundaries
### `src/runtime.rs`
Owns runtime assembly.
- builds the runtime bundle
- wires agent channels, watcher channels, voice, swarm, and LM Studio profile sync
- spawns the agent loop
If you are changing startup ownership, channel plumbing, or steady-state runtime boot, start here.
### `src/agent/conversation.rs`
Owns turn orchestration.
- handles user turns and slash-command flow
- assembles prompts
- applies workflow mode policy during the turn
- coordinates tool execution, verification, compaction, recovery, and final output
This file should not drift back into being a tool registry, product-truth catalog, or giant policy dump.
### `src/agent/routing.rs`
Owns query intent classification.
- classifies stable product-truth questions
- identifies routing classes such as architecture, runtime diagnosis, capability questions, and toolchain questions
- keeps prompt-shaped routing logic out of the main turn loop
### `src/agent/direct_answers.rs`
Owns stable product-truth responses.
- identity
- workflow modes
- Gemma-native settings
- session memory policy
- recovery-recipe explanations
- MCP lifecycle explanations
- tool-class and tool-registry explanations
If a behavior is stable product truth and should answer with `Tokens: 0`, it likely belongs here.
### `src/agent/policy.rs`
Owns tool-policy helper logic.
- destructive-tool classification
- path normalization
- MCP mutation/read helper checks
- target-path extraction
This keeps low-level policy helpers out of `conversation.rs`.
### `src/agent/permission_enforcer.rs`
Owns typed authorization decisions.
- `Allow`
- `Ask`
- `Deny`
Inputs include workflow mode, workspace trust, shell rules, trust sensitivity, and tool metadata.
### `src/agent/trust_resolver.rs`
Owns workspace trust state.
- trusted
- require-approval
- denied
Trust is meant to affect destructive or external actions, not normal repo reads.
### `src/agent/recovery_recipes.rs`
Owns typed runtime recovery planning.
- provider degraded
- context window
- prompt-budget pressure
- history pressure
- MCP workspace read blocked
- proof-before-edit blockers
Recovery plans should be explicit runtime policy, not buried in ad hoc branches.
### `src/agent/compaction.rs`
Owns compaction and session carry-forward.
- recursive summary compression
- compaction thresholds
- typed session ledger
- checkpoint, blocker, recovery, verification, and compaction carry-forward
### `src/agent/tool_registry.rs`
Owns the built-in tool surface.
- built-in tool catalog
- builtin dispatch path
`conversation.rs` should consume the registry, not act like a second registry.
### `src/agent/architecture_summary.rs`
Owns architecture-overview shaping.
- project-map summary shaping
- runtime-trace summary shaping
- architecture-overview assembly
- read-only architecture batch pruning
### `src/agent/inference.rs`
Owns model/tool protocol surfaces.
- chat message types
- inference events
- tool definitions
- tool metadata
- provider/runtime event flow
- prompt preflight and LM Studio interaction
Tool metadata should continue to live here or in adjacent registry-owned code, not leak back into ad hoc name lists.
## Operator Surface
### `src/ui/tui.rs`
Owns the operator interface.
- main transcript rendering
- SPECULAR panel
- bottom status bar
- runtime badges
- approval prompts
- voice toggle state
The TUI should render typed runtime truth from the agent/runtime layer. It should not be the source of truth for provider health, recovery, or policy state.
## Practical Rules For Contributors
- If you are adding a stable explanation, prefer `direct_answers.rs`.
- If you are adding a new routing class, prefer `routing.rs`.
- If you are adding a low-level approval/path/MCP helper, prefer `policy.rs`.
- If you are changing the built-in tool list or builtin dispatch, prefer `tool_registry.rs`.
- If you are changing typed authorization behavior, prefer `permission_enforcer.rs` and `trust_resolver.rs`.
- If you are changing architecture-overview shaping, prefer `architecture_summary.rs`.
- If you are changing the live turn loop itself, use `conversation.rs`.
## What Not To Reintroduce
Avoid letting `conversation.rs` grow back into:
- a second tool registry
- a second policy registry
- a pile of direct-answer strings
- a second architecture summary formatter
- a home for dead compatibility wrappers
The product is strongest when each boundary owns one thing clearly.