> ## Documentation Index
> Fetch the complete documentation index at: https://athanor.alexisbouchez.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How Athanor is structured internally

## Package Layout

```
cmd/athanor/          CLI entrypoint (local TUI + server mode)
internal/
  workflow/            YAML parsing and type definitions
  runner/              Execution engine (job scheduling, step dispatch)
  expr/                GitHub Actions expression evaluator
  action/              Action resolution, caching, composite execution
  server/              Webhook server, GitHub API, web dashboard, run store
  tui/                 Terminal UI (bubbletea)
  vmm/                 CloudHypervisor VM lifecycle, networking, SSH executor
```

## Server Mode Data Flow

```
GitHub webhook POST
       |
       v
  server/server.go      HTTP handler, signature validation
       |
       v
  server/worker.go      Job queue, clone/fetch, workflow discovery
       |
       v
  vmm/lifecycle.go      Spin up microVM (CH + virtiofs + TAP)
       |
       v
  runner/runner.go       Execute workflow (topo sort, step loop)
       |
       v
  vmm/ssh.go            Run steps inside VM via SSH
       |
       v
  server/store.go        Collect logs, update run state
       |
       v
  server/github.go       Report to GitHub (Checks API + commit statuses)
  server/ui.go           Serve web dashboard (SSE live updates)
```

## Local Mode Data Flow

```
  workflow/ParseFile     Parse YAML
       |
       v
  runner/Runner          Execute workflow locally
       |
       v
  tui/Model              Render split-panel TUI
```

## MicroVM Lifecycle

Each CI job runs inside an ephemeral CloudHypervisor microVM. Independent jobs (no `needs:` dependency between them) run in parallel, each in its own VM. The number of concurrent VMs is auto-detected from host RAM or set via `VM_MAX_PARALLEL`.

```
1. Copy rootfs image       (ext4, ~4GB)
2. Allocate TAP device     (attached to br0 bridge)
3. Start virtiofsd         (shares workspace dir)
4. Start cloud-hypervisor  (API socket, kernel, rootfs, net, virtiofs)
5. PUT /api/v1/vm.create   (send config)
6. PUT /api/v1/vm.boot     (boot the VM)
7. Wait for SSH            (~4 seconds total boot time)
8. Execute steps via SSH   (each step = new SSH session)
9. PUT /api/v1/vm.shutdown (graceful shutdown)
10. Kill processes         (CH, virtiofsd)
11. Free TAP device
12. Delete rootfs copy
```

The workspace is shared bidirectionally via **virtiofs**. The host clones the repo, and the VM sees it at `/workspace`.

Networking uses a **TAP device** attached to a Linux bridge (`br0`) with NAT, giving VMs full internet access for downloading dependencies.

## Expression Engine

The `internal/expr/` package implements a full GitHub Actions expression evaluator:

* **Lexer** tokenizes expression contents inside `${{ }}`
* **Parser** performs recursive descent producing an AST
* **Evaluator** does tree-walking with GitHub Actions truthiness rules
* **Interpolation** finds `${{ }}` delimiters, evaluates, and splices results

Supports: context access (`github.sha`), operators (`==`, `!=`, `&&`, `||`, `!`), functions (`contains`, `startsWith`, `format`, `join`, `toJSON`, `fromJSON`, `success`, `failure`, `always`, `cancelled`), index access (`matrix['os']`).

## Runner Events

The runner communicates via a buffered Go channel of typed events:

| Event              | When                                      |
| ------------------ | ----------------------------------------- |
| `WorkflowStarted`  | Run begins                                |
| `JobStarted`       | A job begins execution                    |
| `StepStarted`      | A step begins execution                   |
| `StepOutput`       | A line of stdout/stderr from a step       |
| `StepFinished`     | A step completes (with exit code)         |
| `JobFinished`      | A job completes (success/failure/skipped) |
| `WorkflowFinished` | All jobs done                             |

In server mode, the worker drains these events into the `RunStore`, which notifies SSE subscribers for the web dashboard and builds the log output for the GitHub Checks API.

## GitHub Integration

Athanor uses two GitHub APIs:

**Checks API** (requires GitHub App) creates a check run per workflow with full Markdown-formatted log output. Each job and step appears with its status and output in a code block. GitHub displays this in the check run details view.

**Commit Statuses** (works with PAT) sets a single `athanor` status on the commit. Always set as a fallback.

Authentication for the Checks API uses standard GitHub App JWT flow:

1. Sign a JWT with the app's RSA private key
2. Exchange it for a short-lived installation token
3. Use the token for API calls
4. Cache and refresh automatically

## Job Scheduling

Jobs are sorted using **Kahn's algorithm** for topological ordering, producing levels of parallelizable jobs. Matrix jobs are expanded into virtual jobs before sorting.

```
Level 0: [lint]              <- no dependencies
Level 1: [test, build]       <- both depend on lint
Level 2: [deploy]            <- depends on test and build
```

## Action Support

The `internal/action/` package handles `uses:` steps:

1. **Resolve** parses `owner/repo@version`, `./local/path`, or `docker://image`
2. **Builtins** provide a built-in shim for `actions/checkout` (git checkout)
3. **Cache** clones action repos to `~/.cache/athanor/actions/`
4. **Metadata** parses `action.yml` for inputs, outputs, runs
5. **Composite** executes composite action steps inline
6. **Node** executes Node.js actions via `node` (if available)
