# How it works

Klyro behaves like a compiler. A single source document goes through fixed
stages, and every stage is deterministic: the same input always produces the
same output bytes on the same Klyro version.

## The pipeline

```text
read source
  → decode and normalize        (Effect Schema)
  → resolve capabilities and bindings
  → build DeploymentPlan
  → render the complete ArtifactSet in memory
  → inspect overwrite/path policy
  → write through FileSystem and ArtifactWriter
```

1. **Decode**: raw YAML is decoded against a versioned schema
   (`klyro.dev/v1alpha1`, kind `AgentStack`). Unknown fields and unknown
   provider references fail here with stable diagnostics.
2. **Resolve**: selected providers are matched against the curated catalog.
   Capabilities and runtime-specific [bindings](/core-concepts/stacks-and-providers/)
   determine whether the combination is compatible and what it requires.
3. **Plan**: the resolved stack becomes a deployment-neutral plan of logical
   services, configuration, environment references, ports, volumes, and
   artifact intents.
4. **Render**: a renderer (v0.1 ships Docker Compose) converts the plan into a
   complete artifact set in memory. Rendering completes before any write.
5. **Write**: only after destinations are validated and overwrite policy is
   checked does anything touch the filesystem.

## Failure precedes writes

Validation, resolution, planning, and rendering all happen before mutation.
A failed command leaves no partial project behind, including interactive
cancellation, which exits with code `130`. Diagnostics carry stable codes at
each seam; see [Commands](/cli/commands/) for the exit-code table.

## Determinism is a product feature

Generated artifacts contain no timestamps, random identifiers, or
environment-dependent ordering. `plan` output for identical input is
byte-stable, and repeated generation produces byte-identical normalized
artifacts. The repository enforces this with golden-output tests that fail on
any byte drift.

## Where the code lives

| Package                   | Role                                                        |
| ------------------------- | ----------------------------------------------------------- |
| `@klyro/core`             | Schemas, resolver algorithms, planning contracts            |
| `@klyro/catalog`          | Curated provider descriptors, bindings, deployment facts    |
| `@klyro/renderer-compose` | Pure plan-to-Compose rendering                              |
| `@klyro/platform-node`    | Node filesystem, environment, process services; safe writes |
| `@klyro/cli`              | Command routing, prompts, presentation, exit-code mapping   |

The boundaries between these packages are deliberate; contributors can read
the details in the [architecture overview](/contributing/architecture-overview/).