Skip to content

Architecture

Orchard is a code-mode workflow generation and execution engine. Agents and users produce TypeScript workflow artifacts; Orchard validates, previews, saves, registers, and runs those artifacts on a small in-process task runtime.

This build has no durability. Workflows execute as promises inside the orchard run process, with step results memoized in memory via ctx.step. There is no database, no persistence, no crash recovery, no cross-process execution, and no post-run inspection.

Core loop

text
prompt or workflow spec

generated TypeScript workflow artifact

contract validation, type-check, preview, manifest save

register tasks and run the root workflow in process

read the final state and result snapshot orchard run prints

Layering

text
Prompt / workflow spec
    ↓ orchard generate starts built-in generate-workflow
    ↓ (one generate task calling generateWorkflowArtifact)
TypeScript workflow artifact
    ↓ validate / type-check / preview / manifest
@snevins/orchard-core primitives
    ↓ task / workflow / WorkflowRef.start()
createLocalRuntime() in-process task runtime
    ↓ harnessCall
Harness (cursor | codex | claude | devin)
    ↓ runUnstructuredTurn / runStructuredTurn
CLI agent (cursor-agent | Codex SDK | Claude Code CLI | Devin CLI)

Core deliberately avoids a hidden scheduler, graph DSL, retry engine, monitor, or production control plane. Each top-level workflow starts as an explicit task so Orchard can print a stable workflowID (taskID). Structured harness calls are explicit ctx.step checkpoints so failures and session IDs stay visible in the run's status output while the process is alive.

In-process execution, ephemeral queues

createLocalRuntime() is the entire execution backend: there is no ABSURD_DATABASE_URL, no schema, and no external process to reach. Running orchard init in a directory writes a stable queue namespace (queues.workflow, queues.tasks) to .orchard/config.json. Generated artifacts still pass that namespace to workflow({ queues }) because it is part of the generated-artifact contract, but the in-process runtime tracks queue names only as metadata — there is no worker pool, so nothing schedules against them and a workflow can await a child on any queue without deadlocking on a worker slot.

Package split

@snevins/orchard-core holds reusable primitives:

  • Session-oriented Harness adapters (cursor, codex, claude, devin).
  • Step-memoized wrappers that run workflows and record turns via ctx.step.
  • Zod-validated structured output with same-session repair.
  • createLocalRuntime(), Orchard's in-process task runtime, and its Absurd-shaped runtime contract types, including OrchardWorkflowQueues.

@snevins/orchard-cli exposes the code-mode engine to agents:

  • Incur-backed repo-local orchard commands: init, doctor, generate, preview, run, and feedback.
  • Built-in Incur integrations for --llms, skills, MCP, and shell completions.
  • orchard init writes repo config. orchard doctor is read-only and reports tooling and config readiness as structured data — there is no database, schema, or queue readiness to check.
  • Workflow artifact generation, validation, preview, and manifest helpers used by those commands.
  • An interactive approval host that polls the in-process runtime for pending approval gates for the lifetime of a single orchard run invocation.

Orchard's local runner starts and hosts project-scoped workflows for the lifetime of one process; it does not provision, persist, or replace anything once that process exits.

Validation strategy

  • CLI wrappers are tested with fake executables, not mocked internal functions.
  • Generated workflow artifacts must pass local contract checks and TypeScript validation before Orchard returns their UUID or writes a manifest entry, and generation prompts require scenario-specific values to remain caller-supplied workflow input or per-run options.
  • Static queue validation checks the generated queue contract (queues.workflow for the root workflow and queues.tasks for child tasks), rejects literal queue names, and rejects workflow task references it cannot verify as direct task refs or simple const aliases in an inline task array.
  • End-to-end runtime operations are verified by running the same in-process runtime (createLocalRuntime()) users run, not a mocked scheduler.

Licensed under MIT