Declarative Configuration

How lettactl uses YAML to define and manage agent fleets with a single source of truth.

Declarative vs Imperative

lettactl follows the declarative model: you describe what your fleet should look like, not the steps to get there. When you run `lettactl apply`, the diff engine compares your YAML against the live server state and figures out the minimum set of operations needed. Create, update, or leave alone — it decides automatically.

The Fleet Config File

Everything lives in a single YAML file (or split across multiple). The top-level keys are `shared_blocks`, `shared_folders`, `mcp_servers`, and `agents`. Agents is the only required section — everything else is optional.

fleet.yaml
shared_blocks:
  - name: brand_guidelines
    description: "Company voice and style"
    limit: 5000
    from_file: "memory/guidelines.md"

agents:
  - name: support-agent
    description: "Customer support AI"
    llm_config:
      model: "google_ai/gemini-2.5-pro"
      context_window: 32000
    system_prompt:
      from_file: "prompts/support.md"
    shared_blocks:
      - brand_guidelines

How Apply Works

The apply command follows a strict pipeline: parse YAML → validate config → load existing server state → diff each agent → execute operations. With `--dry-run`, it stops after the diff and shows you what would change without touching anything. The diff engine compares system prompts, descriptions, models, tools, memory blocks, folders, and tags.

Apply workflow
# Preview changes
lettactl apply -f fleet.yaml --dry-run

# Deploy for real
lettactl apply -f fleet.yaml

# Only deploy specific agents
lettactl apply -f fleet.yaml --agent support-*

# Filter by tags
lettactl apply -f fleet.yaml --match tags:team=support

Idempotency

Running apply twice with the same config produces zero changes the second time. The diff engine recognizes that the server state already matches and reports all agents as unchanged. This is critical for CI/CD pipelines where apply runs on every push.