# Playbook And Action YAML Reference

This page describes the YAML shapes used for playbooks, actions, and tasks. The schemas live in [`schema/`](https://github.com/bluecadet/preflight/tree/main/schema), and the runtime loaders live in [`internal/action/`](https://github.com/bluecadet/preflight/tree/main/internal/action).

## `playbook.yml`

Playbooks are the top-level execution documents.

### Fields

| Field         | Type      | Meaning                                             |
| ------------- | --------- | --------------------------------------------------- |
| `name`        | string    | Human-readable playbook name                        |
| `description` | string    | Optional description                                |
| `defaults`    | object    | Task execution defaults inherited by playbook tasks |
| `vars`        | object    | Playbook-level variable overrides                   |
| `import`      | string\[] | Other playbook files to merge before local tasks    |
| `tasks`       | task\[]   | Ordered task list                                   |

### Import Behavior

Imports are loaded depth-first.

- Imported vars are merged first.
- The importing playbook’s vars override imported vars.
- Imported tasks are prepended in listed order.
- Import cycles are rejected.
- Relative import paths are resolved from the playbook that declares them.

### Example

```yaml
name: lobby-baseline

import:
  - ./base.yml

vars:
  content_root: "C:\\Exhibits\\Lobby"

tasks:
  - name: Prepare content directory
    directory:
      path: "{{ vars.content_root }}"
      ensure: present
```

## `action.yml`

Actions package reusable tasks behind a typed input surface.

### Fields

| Field         | Type    | Meaning                                                        |
| ------------- | ------- | -------------------------------------------------------------- |
| `name`        | string  | Required namespaced action name such as `myorg/display-config` |
| `version`     | string  | Semantic version string                                        |
| `description` | string  | Optional description                                           |
| `author`      | string  | Optional author                                                |
| `defaults`    | object  | Task execution defaults inherited by action tasks              |
| `inputs`      | object  | Named input definitions                                        |
| `tasks`       | task\[] | Ordered task list                                              |

### Input Definition Fields

| Field         | Type   | Meaning                                              |
| ------------- | ------ | ---------------------------------------------------- |
| `type`        | enum   | `string`, `bool`, `int`, or `path`                   |
| `required`    | bool   | Whether the caller must supply the input             |
| `default`     | any    | Default value injected before caller-provided values |
| `description` | string | Human-readable explanation                           |

### Example

```yaml
name: preflight/autologin
version: "1.0.0"
description: Configure Windows automatic login

inputs:
  username:
    type: string
    required: true
  password:
    type: string
    required: false

tasks:
  - name: Enable auto-login
    registry:
      path: 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
      values:
        AutoAdminLogon: "1"
        DefaultUserName: "{{ vars.username }}"
        DefaultPassword: "{{ vars.password }}"
```

## Task Shape

Every task requires `name`. A task may use exactly one execution form:

- `uses` plus `with`
- `module` plus `params`
- one inline module block such as `directory`, `service`, or `powershell`

Mixing these forms in the same task is an error.

### Shared Task Fields

| Field           | Type      | Meaning                                                                                                 |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------- |
| `name`          | string    | Task label used in output and as a fallback dependency reference                                        |
| `id`            | string    | Optional stable task reference for `depends_on`                                                         |
| `uses`          | string    | Action reference                                                                                        |
| `with`          | object    | Inputs passed to the referenced action                                                                  |
| `become`        | object    | Execute the task as another user                                                                        |
| `module`        | string    | Explicit module name, including plugin-backed modules                                                   |
| `params`        | object    | Parameters for `module`                                                                                 |
| `when`          | string    | Template condition expression                                                                           |
| `depends_on`    | string\[] | Task dependencies; Preflight resolves `id` first, then falls back to `name` when no explicit ref is set |
| `ignore_errors` | bool      | Continue after a task failure                                                                           |
| `tags`          | string\[] | Tags used by `--tags` and `--skip-tags`                                                                 |

Use `id` when tasks need a stable dependency key that should not change with display-name edits.

Example:

```yaml
tasks:
  - name: Prepare content volume
    id: prepare-volume
    directory:
      path: "C:\\Content"
      ensure: present

  - name: Sync content
    module: signage_sync
    depends_on: ["prepare-volume"]
    params:
      source: "\\\\nas01\\content"
      destination: "C:\\Content"
```

### Task Defaults

Playbooks and actions may define:

```yaml
defaults:
  become:
    enabled: true
    user: exhibit
    method: sudo
```

Task defaults are inherited into child tasks. `become` precedence is:

```
playbook defaults -> action defaults -> task become
```

If a `become` object is present and omits `enabled`, Preflight treats it as enabled. Setting `enabled: false` on a task disables inherited `become` for that task.

### `become`

`become` is task execution metadata, not a module parameter. It changes which user the task runs as while leaving `params` unchanged.

| Field          | Type   | Meaning                                                         |
| -------------- | ------ | --------------------------------------------------------------- |
| `enabled`      | bool   | Enable alternate-user execution                                 |
| `user`         | string | Target user to execute as                                       |
| `password`     | string | Optional password or secret reference                           |
| `method`       | string | Runtime method (`runas` on Windows, `sudo` on POSIX by default) |
| `load_profile` | bool   | Windows-focused profile loading hint                            |

Example:

```yaml
tasks:
  - name: Configure kiosk shell
    become:
      user: exhibit
      password: secret:exhibit-password
    powershell:
      script: |
        Write-Output $env:USERNAME
```

### Explicit Module Tasks

Use `module` and `params` for plugin-backed modules or when you want an explicit module name:

```yaml
tasks:
  - name: Sync signage
    module: signage_sync
    params:
      source: "\\\\nas01\\signage"
      destination: "C:\\Signage"
```

### Inline Module Tasks

Use one inline module key when you want a built-in task form:

```yaml
tasks:
  - name: Ensure content directory exists
    directory:
      path: "C:\\Exhibits\\Content"
      ensure: present
```

For the exact built-in module fields, see [Built-in module reference](/reference/modules/).

## Template Context

Task names, `when:` expressions, and string parameter values may read from:

| Namespace  | Meaning                               |
| ---------- | ------------------------------------- |
| `vars.*`   | Merged variables                      |
| `facts.*`  | Gathered host facts                   |
| `target.*` | Safe target metadata                  |
| `env.*`    | Gathered target environment variables |

The template engine supports simple dot-path lookups such as `{{ vars.content_root }}`. It renders string values recursively through nested maps and lists, which lets actions template shapes such as registry value lists and power-plan setting arrays. It does not implement the full Jinja filter and expression language.

## Action Resolution Order

When Preflight resolves a `uses:` reference, it checks these sources in order:

1. Embedded stdlib
2. Local project actions under `actions/`
3. User cache under `~/.preflight/actions`
4. Git-backed remote refs

## Remote Action Refs

Supported remote refs use this shape:

```
host/org/repo[/path/to/action]@revision
```

Examples:

```
github.com/acme/actions/signage@v1.2.3
github.com/acme/actions/collections/autologin@0123456789abcdef
```

Remote refs are pinned to exact commit SHAs in `preflight.lock` for reproducible resolution.

## Editor Schema Wiring

The JSON schemas in `schema/` enable live validation and autocompletion in editors that support the YAML Language Server protocol (e.g. VS Code with the [YAML extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)).

**Inline file comment** (works in any editor with yaml-language-server support):

```yaml
# yaml-language-server: $schema=https://preflight.dev/schema/action.schema.json
name: myorg/my-action
...
```

**VS Code `settings.json`** (applies to all matching files in the workspace):

```json
{
  "yaml.schemas": {
    "https://preflight.dev/schema/action.schema.json": "**/actions/**/action.yml",
    "https://preflight.dev/schema/playbook.schema.json": "**/playbooks/*.yml",
    "https://preflight.dev/schema/config.schema.json": "**/preflight.yml"
  }
}
```

## Related Docs

- [Project config reference](/reference/config/)
- [Inventory reference](/reference/inventory/)
- [Execution model](/explanation/execution-model/) — action resolution order and lockfile behavior
