Compare commits

...

1 Commits

Author SHA1 Message Date
bebcf8a29d feat: implement thin config ephemerality and upstream pull fallback
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
- 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
2 changed files with 19 additions and 1 deletions

View File

@@ -19,6 +19,24 @@
version: "{{ upstream_branch }}"
force: true
tags: [pull]
register: git_pull
ignore_errors: true
- name: "Fallback: restore config from deadman snapshot if upstream pull failed"
shell: |
if [ ! -f "{{ wizard_home }}/config.yaml" ] || [ ! -f "{{ deadman_snapshot_dir }}/config.yaml.known_good" ]; then
echo "SKIP: config or snapshot missing"
exit 0
fi
if [ {{ git_pull.failed | default('false') }} = true ] || [ {{ git_pull.rc | default(0) }} -ne 0 ]; then
echo "Upstream pull failed — restoring config from deadman snapshot..."
cp "{{ deadman_snapshot_dir }}/config.yaml.known_good" "{{ wizard_home }}/config.yaml"
echo "Config restored from snapshot."
else
echo "Upstream pull succeeded — no action needed."
fi
tags: [pull, fallback]
when: deadman_enabled | default(true)
- name: "Deploy golden state config"
include_role:

View File

@@ -15,7 +15,7 @@
template:
src: "../../wizard_base/templates/wizard_config.yaml.j2"
dest: "{{ wizard_home }}/config.yaml"
mode: "0644"
mode: "0444" # Read-only — ephemeral thin config
backup: true
notify:
- "Restart hermes agent (systemd)"