# Orchestration crate layout

`crates/orchestration/src` is grouped by app concern. Entity folders hold application logic and port traits. Centralized `adapters/` folders hold concrete storage, tool, MCP, git, and LSP implementations.

Rust import paths match the folder layout. For example, `workflow/catalog.rs` is `orchestration::workflow::catalog`, and `run/execution/` is `orchestration::run::execution`.

## Module paths

| File or folder | Rust module |
| --- | --- |
| `backend/mod.rs` | `orchestration::backend` |
| `workflow/catalog.rs` | `orchestration::workflow::catalog` |
| `run/coordinator/mod.rs` | `orchestration::run::coordinator` |
| `run/execution/` | `orchestration::run::execution` |
| `run/handoff.rs` | `orchestration::run::handoff` |
| `tool/registry.rs` | `orchestration::tool::registry` |
| `adapters/tool_impl/` | `orchestration::tools` internal alias |
| `adapters/infrastructure/git` | `orchestration::git` public alias |
| `adapters/infrastructure/lsp` | `orchestration::lsp` public alias |

## Roles

```text
desktop / ui
    │
    ▼
backend/                  AppBackend facade and composition root
    │
    ├── workflow/          workflow catalog and authoring services
    ├── chat.rs            saved direct-chat metadata
    ├── agent.rs           saved agent library
    ├── project/           project registry and file references
    ├── settings/          settings facade, provider readiness, skills
    ├── schedule/          schedule evaluation and status
    ├── run/               run registry, per-run coordinators, checkpoints, state projection
    ├── terminal.rs        embedded terminal sessions
    └── tool/              tool registry, dispatch, retry, output

adapters/
    ├── storage/           JSON and checkpoint persistence
    ├── tool_impl/         concrete read/search/write/bash/edit tools
    ├── mcp/               MCP discovery and run clients
    └── infrastructure/    git and LSP integrations
```

| Role | Folder | Job |
| --- | --- | --- |
| Composition | `backend/` | Construct services, expose the stable facade that desktop calls. |
| Application services | `workflow/`, `agent.rs`, `project/`, `settings/`, `schedule/`, `run/`, `terminal.rs`, `tool/` | Apply app rules, coordinate ports, and return API DTOs. |
| Port traits | `{entity}/ports.rs` or `agent.rs` | Define store/catalog seams consumed by entity services. |
| Run state | `run/state.rs` | Project `RunTelemetry` into `WorkflowRunState` for UI and IPC. |
| Concrete storage | `adapters/storage/` | Read and write JSON files under `{data_local}/openflow/`, project workflow files, and run checkpoints. |
| Runtime I/O | `adapters/tool_impl/`, `adapters/mcp/`, `adapters/infrastructure/` | Perform filesystem, subprocess, MCP, git, and LSP work. |
| Shared DTOs | `api.rs`, `error.rs` | Define transport shapes and `BackendError` used across the crate. |

Engine semantics stay in `crates/engine`. Orchestration wires the engine to providers, stores, tools, projects, and desktop-facing state.

## Directory map

```text
orchestration/src/
├── lib.rs
├── api.rs
├── error.rs
├── backend/
│   ├── mod.rs
│   └── tests.rs
├── adapters/
│   ├── storage/
│   │   ├── agent_store.rs
│   │   ├── app_workflow_store.rs
│   │   ├── project_store.rs
│   │   ├── project_workflow_store.rs
│   │   ├── run_checkpoint_store.rs
│   │   ├── settings_store.rs
│   │   └── skill_store.rs
│   ├── tool_impl/
│   ├── mcp/
│   └── infrastructure/
├── agent.rs
├── chat.rs
├── diagnostics.rs
├── project/
├── run/
│   ├── coordinator/
│   ├── execution/
│   ├── handoff.rs
│   ├── persistence.rs
│   └── state.rs
├── schedule/
├── settings/
├── terminal.rs
├── tool/
└── workflow/
    ├── authoring/
    └── catalog.rs
```

## Entity reference

### Workflow

| File | Module path | Responsibility |
| --- | --- | --- |
| `workflow/catalog.rs` | `workflow::catalog` | Merge app and project workflows; assign, unassign, rename, and split saves. |
| `workflow/authoring/` | `workflow::authoring` | AI-assisted workflow draft and validation turns. |
| `workflow/ports.rs` | `workflow::ports` | Workflow store traits consumed by the catalog. |
| `adapters/storage/app_workflow_store.rs` | `adapters::storage::app_workflow_store` | Persist app-level `workflows.json`. |
| `adapters/storage/project_workflow_store.rs` | `adapters::storage::project_workflow_store` | Discover and save per-project workflow files. |

The catalog owns merge policy; the stores only read and write bytes.

### Agent

| File | Module path | Responsibility |
| --- | --- | --- |
| `agent.rs` | `agent` | Callable agent CRUD, `create_agent_node`, and agent store trait. |
| `adapters/storage/agent_store.rs` | `adapters::storage::agent_store` | Persist `openflow/agents.json`. |

### Chat

| File | Module path | Responsibility |
| --- | --- | --- |
| `chat.rs` | `chat` | Persisted Chat identity, project/runtime config, title, timestamps, and durable run reference. |
| `backend/chat.rs` | `backend::chat` | Direct-chat commands and private workflow execution adapter. |
| `adapters/storage/chat_store.rs` | `adapters::storage::chat_store` | Persist `openflow/chats.json` separately from the workflow catalog. |

### Project

| File | Module path | Responsibility |
| --- | --- | --- |
| `project/registry.rs` | `project::registry` | Register and load project folders. |
| `project/file_refs.rs` | `project::file_refs` | Read project file-reference content. |
| `project/ports.rs` | `project::ports` | Project store trait and project DTO. |
| `adapters/storage/project_store.rs` | `adapters::storage::project_store` | Persist `openflow/projects.json`. |

### Run

| File | Module path | Responsibility |
| --- | --- | --- |
| `run/registry.rs` | `run::registry` | Addressable top-level sessions keyed by `run_id`; shared execution resources. |
| `run/coordinator/mod.rs` | `run::coordinator` | One session mutex; `start_run`, `submit_*`, `stop_run`, resume, replay, interrupts. |
| `run/execution/` | `run::execution` | Host loop, AI adapter, `ToolPortImpl`, headless execution, telemetry event projection. |
| `run/handoff.rs` | `run::handoff` | Validate, atomically persist, hash, and resolve canonical Markdown/JSON node handoffs. |
| `run/persistence.rs` | `run::persistence` | Durable run roots, records, and checkpoint metadata. |
| `run/ports.rs` | `run::ports` | Run checkpoint store trait. |
| `run/skill_invocation.rs` | `run::skill_invocation` | Resolve installed task-prompt skill tokens into frozen runtime prompt guidance. |
| `run/state.rs` | `run::state` | `WorkflowRunState` projected for UI and IPC. |
| `adapters/storage/run_checkpoint_store.rs` | `adapters::storage::run_checkpoint_store` | Persist run records and engine checkpoints. |

Only `run/execution/` constructs or drives `InteractiveEngine`, as required by the [architecture contract](https://philbotar.github.io/OpenFlow/architecture/contract.html).

### Settings

| File | Module path | Responsibility |
| --- | --- | --- |
| `settings/facade.rs` | `settings::facade` | Settings UX backend: redaction, skill list, provider readiness, validation summary. |
| `settings/provider.rs` | `settings::provider` | Key precedence: transient input, stored key, then environment. |
| `settings/model.rs` | `settings::model` | Persisted settings DTOs. |
| `settings/ports.rs` | `settings::ports` | Settings and skill catalog traits. |
| `adapters/storage/settings_store.rs` | `adapters::storage::settings_store` | Persist `settings.json`. |
| `adapters/storage/skill_store.rs` | `adapters::storage::skill_store` | Scan configured roots for `SKILL.md` files. |

### Tool and infrastructure

| File or folder | Module path | Responsibility |
| --- | --- | --- |
| `tool/registry.rs` | `tool::registry` | Register builtin tools and their `ToolTier` and `ToolConcurrency`. |
| `tool/runner.rs` | `tool::runner` | Execute registered tools and persist large artifacts. |
| `tool/dispatch.rs` | `tool::dispatch` | Route calls to concrete tool implementations. |
| `tool/retry.rs` | `tool::retry` | Retry transient tool failures according to workflow policy. |
| `adapters/tool_impl/` | `tools` internal alias | Concrete read, ls, search, find, write, edit, bash, grep, and patch implementations. |
| `adapters/mcp/` | `adapters::mcp` | MCP server discovery and per-run clients. |
| `adapters/infrastructure/git` | `git` public alias | Execution-cwd-scoped diff and revert operations. |
| `adapters/infrastructure/lsp` | `lsp` public alias | LSP settings and format/diagnostic integration. |

### Diagnostics, schedule, and terminal

| File or folder | Module path | Responsibility |
| --- | --- | --- |
| `diagnostics.rs` | `diagnostics` | Append optional local debug output to a process-specific JSONL file in the system temporary directory. |
| `schedule/` | `schedule` | Evaluate workflow schedules and status. |
| `terminal.rs` | `terminal` | Manage embedded terminal sessions. |

## Request flow: start a run

```mermaid
sequenceDiagram
    participant UI
    participant Desktop
    participant Backend as backend/mod.rs
    participant Registry as run/registry
    participant Coordinator as run/coordinator
    participant Execution as run/execution
    participant Engine as engine::InteractiveEngine
    participant ToolPort as ToolPortImpl

    UI->>Desktop: invoke start_run
    Desktop->>Backend: AppBackend::start_run
    Backend->>Registry: RunRegistry::start_run
    Registry->>Coordinator: create one RunCoordinator
    Coordinator->>Execution: spawn_interactive_workflow_run
    Execution->>Engine: engine.run(ai, tool_port, cancel_token)
    Engine->>ToolPort: ToolPort::run_tools
    ToolPort-->>Engine: ToolResult batch
    Execution-->>Coordinator: RunTelemetry stream
    Coordinator-->>Backend: WorkflowRunState
    Backend-->>Desktop: IPC payload
```

`AppBackend` delegates run lifecycle operations to `RunRegistry`, which owns
one `RunCoordinator` per live or retained in-process run. Different workflows may run concurrently,
but the registry rejects a second active run for the same workflow. It targets 64 retained sessions by
evicting inactive sessions first and never evicts an active session.

Registry operations accept an optional run ID internally: an explicit ID selects that session;
omitting it selects the latest session for legacy backend calls. Missing explicit IDs return an
error. `AppBackend` retains separate addressed and legacy methods for existing consumers.

The coordinator completes fallible launch setup, including durable resume status writes, before
spawning execution. It then installs handles without an intervening await. The headless runner
cancels and joins execution on return; dropping its future cancels and aborts the owned task.

Hashline editing uses one concrete snapshot store, with a single mutex over versions and path
recency so concurrent writes cannot bypass eviction. Bash and MCP package installation share
the process-group cleanup helper in `adapters/infrastructure/process.rs`.

## Where to add code

| Change | Put it here |
| --- | --- |
| New workflow merge rule | `workflow/catalog.rs`. |
| New workflow file layout | `adapters/storage/app_workflow_store.rs` or `adapters/storage/project_workflow_store.rs`. |
| New project registry behavior | `project/registry.rs` plus `project/ports.rs` if the store seam changes. |
| New run lifecycle step | `run/coordinator/mod.rs` or `run/execution/`. |
| New UI run field | `run/state.rs` plus `engine::RunTelemetry` if the engine emits new state. |
| New builtin tool | `adapters/tool_impl/`, `tool/registry.rs`, `tool/dispatch.rs`, and `crates/engine/src/tools/config.rs`; also update `NODE_RUNTIME_PREAMBLE` in `crates/engine/src/execution/node_invocation.rs`. |
| New settings field | `settings/model.rs`, `adapters/storage/settings_store.rs`, and `settings/facade.rs` if UI-facing. |
| New desktop command | Delegate in `backend/mod.rs`; implement in the owning service module. |

## Import rules

| Folder | May import |
| --- | --- |
| `backend/` | Entity services, storage adapters, `api`, and `error`. |
| `workflow/`, `agent/`, `project/`, `settings/`, `tool/` | Engine types, local ports, sibling modules, and shared DTOs. They must not import `crate::adapters::`. |
| `run/` | Engine types, providers through `AiPort`, tool infrastructure, run ports, and run state. |
| `adapters/storage/` | Engine types, entity port traits, filesystem/JSON support. |
| `adapters/tool_impl/`, `adapters/mcp/`, `adapters/infrastructure/` | Engine tool types and concrete I/O crates. |

Cross-entity work goes through services or `backend/`. Entity services should depend on port traits when a concrete store would otherwise leak persistence details.

## Persistence locations

| Data | Location | Owning module |
| --- | --- | --- |
| App workflows | `{data_local}/openflow/workflows.json` | `orchestration/src/adapters/storage/app_workflow_store.rs` |
| Projects | `{data_local}/openflow/projects.json` (migrates from legacy slug) | `orchestration/src/adapters/storage/project_store.rs` |
| Saved agents | `{data_local}/openflow/agents.json` (migrates from legacy slug) | `orchestration/src/adapters/storage/agent_store.rs` |
| Settings | `{data_local}/openflow/settings.json` | `orchestration/src/adapters/storage/settings_store.rs` |
| Project workflows | `{project}/.flow/workflows/{workflowId}.workflow.json` | `orchestration/src/adapters/storage/project_workflow_store.rs` |
| Provider API keys | Plaintext in `settings.json` (`ProviderProfile.api_key`) | `orchestration/src/adapters/storage/settings_store.rs` |
| Skills | Discovered at runtime from Cursor/Claude/Agents skill dirs (not persisted) | `orchestration/src/adapters/storage/skill_store.rs` |

`AppBackend::load_all_workflows` merges app-store workflows with project-discovered workflows (project files win on ID collision).

`run_checkpoint_store` writes to `{data_local}/openflow/runs/` or the project-scoped run root selected by orchestration. [Data locations](https://philbotar.github.io/OpenFlow/reference/) lists run attachments, handoffs, and credential storage.
