Files
timmy-config/ansible
Rockachopa bebcf8a29d
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 21s
Smoke Test / smoke (pull_request) Failing after 20s
Validate Config / YAML Lint (pull_request) Failing after 14s
Validate Config / JSON Validate (pull_request) Successful in 18s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 53s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 58s
Validate Config / Cron Syntax Check (pull_request) Successful in 11s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 12s
Validate Config / Playbook Schema Validation (pull_request) Successful in 25s
Architecture Lint / Lint Repository (pull_request) Failing after 23s
PR Checklist / pr-checklist (pull_request) Successful in 3m47s
feat: implement thin config ephemerality and upstream pull fallback
- Make config.yaml read-only (0444) — enforces ephemeral thin config pattern
  Agents cannot mutate their config at runtime. Any changes are lost on restart
  because config is re-deployed from immutable golden state on each boot.

- Add upstream pull fallback in agent_startup.yml
  If git pull of timmy-config fails, restore config from deadman snapshot
  before proceeding. Ensures startup succeeds even when upstream is unreachable.

Design rationale:
- config.yaml is now ephemeral (read-only file)
- Only thin_config.yml is mutable (local_overrides section), but even that is
  restricted by filesystem permissions (0444) — runtime overrides are in-memory only
- Failure recovery: deadman snapshots act as last-known-good config source
- No wizard can permanently modify config without a Gitea PR + Ansible deploy

Related to #443 — Thin Config Pattern: Immutable Local Config with Upstream Pull.
This addresses acceptance criteria:
- Runtime config mutations are ephemeral (file is read-only)
- Fallback to last-known-good if upstream pull fails

Closes #443
2026-04-26 10:54:09 -04:00
..

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

# 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.
  • 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