# Ansible IaC — The Timmy Foundation Fleet

> One canonical Ansible playbook defines: deadman switch, cron schedule,
> golden state rollback, agent startup sequence.
> — KT Final Session 2026-04-08, Priority TWO

## Purpose

This directory contains the **single source of truth** for fleet infrastructure.
No more ad-hoc recovery implementations. No more overlapping deadman switches.
No more agents mutating their own configs into oblivion.

**Everything** goes through Ansible. If it's not in a playbook, it doesn't exist.

## Architecture

```
┌─────────────────────────────────────────────────┐
│                  Gitea (Source of Truth)          │
│  timmy-config/ansible/                           │
│    ├── inventory/hosts.yml    (fleet machines)    │
│    ├── playbooks/site.yml     (master playbook)   │
│    ├── roles/                 (reusable roles)    │
│    └── group_vars/wizards.yml (golden state)      │
└──────────────────┬──────────────────────────────┘
                   │  PR merge triggers webhook
                   ▼
┌─────────────────────────────────────────────────┐
│              Gitea Webhook Handler                │
│  scripts/deploy_on_webhook.sh                     │
│  → ansible-pull on each target machine            │
└──────────────────┬──────────────────────────────┘
                   │  ansible-pull
                   ▼
┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
│  Timmy   │  │ Allegro  │  │ Bezalel  │  │  Ezra    │
│  (Mac)   │  │  (VPS)   │  │  (VPS)   │  │  (VPS)   │
│          │  │          │  │          │  │          │
│ deadman  │  │ deadman  │  │ deadman  │  │ deadman  │
│ cron     │  │ cron     │  │ cron     │  │ cron     │
│ golden   │  │ golden   │  │ golden   │  │ golden   │
│ req_log  │  │ req_log  │  │ req_log  │  │ req_log  │
└──────────┘  └──────────┘  └──────────┘  └──────────┘
```

## Quick Start

```bash
# Deploy everything to all machines
ansible-playbook -i inventory/hosts.yml playbooks/site.yml

# Deploy only golden state config
ansible-playbook -i inventory/hosts.yml playbooks/golden_state.yml

# Deploy only to a specific wizard
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --limit bezalel

# Dry run (check mode)
ansible-playbook -i inventory/hosts.yml playbooks/site.yml --check --diff
```

## Golden State Provider Chain

All wizard configs converge on this provider chain. **Anthropic is BANNED.**

| Priority | Provider             | Model            | Endpoint                          |
| -------- | -------------------- | ---------------- | --------------------------------- |
| 1        | Kimi                 | kimi-k2.5        | https://api.kimi.com/coding/v1    |
| 2        | Gemini (OpenRouter)  | gemini-2.5-pro   | https://openrouter.ai/api/v1      |
| 3        | Ollama (local)       | gemma4:latest    | http://localhost:11434/v1         |

## Roles

| Role             | Purpose                                                      |
| ---------------- | ------------------------------------------------------------ |
| `wizard_base`    | Common wizard setup: directories, thin config, git pull      |
| `deadman_switch` | Health check → snapshot good config → rollback on death      |
| `golden_state`   | Deploy and enforce golden state provider chain               |
| `request_log`    | SQLite telemetry table for every inference call               |
| `cron_manager`   | Source-controlled cron jobs — no manual crontab edits         |

## Rules

1. **No manual changes.** If it's not in a playbook, it will be overwritten.
2. **No Anthropic.** Banned. Enforcement is automated. See `BANNED_PROVIDERS.yml`.
3. **Idempotent.** Every playbook can run 100 times with the same result.
4. **PR required.** Config changes go through Gitea PR review, then deploy.
5. **One identity per machine.** No duplicate agents. Fleet audit enforces this.

## Related Issues

- timmy-config #442: [P2] Ansible IaC Canonical Playbook
- timmy-config #444: Wire Deadman Switch ACTION
- timmy-config #443: Thin Config Pattern
- timmy-config #446: request_log Telemetry Table
