cloudfall 0.6.0rc1__tar.gz → 0.6.0rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/ARCHITECTURE.md +2 -1
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CHANGELOG.md +5 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/MANIFESTO.md +2 -4
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/PKG-INFO +52 -25
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/README.md +51 -24
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/ROADMAP.md +5 -2
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/pyproject.toml +1 -1
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/.ansible-lint +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/.gitignore +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CODE_OF_CONDUCT.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CONTRIBUTING.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/LICENSE +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/SECURITY.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/Taskfile.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/README.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/alert-rules/postgresql-down.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/applications/crm.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/components/crm-backend.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/domains/crm-site.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/logging-stacks/operations.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/operator-policies/production.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/server-types/debian-application.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/servers/h1.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/servers/h2.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/services/postgresql-main.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/services/redis-cache.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/ssh-public-keys/example-admin.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/alert-rule.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/application.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/artifact.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/backup-receipt.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/common.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/component.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/deployment-receipt.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/domain.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/environment-receipt.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/logging-stack.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/observed-domain.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/observed-server.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operation-decision.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operation.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operator-policy.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operator-proposal.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/release-receipt.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/server-type.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/server.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/service.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/ssh-public-key.schema.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/applications/crm.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/components/crm-backend.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/server-types/debian-application.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/servers/h1.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/schema/components/component-unknown-field.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/observed/compliant/h1.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/observed/compliant/h2.json +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/ansible-context.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/assets/logo.svg +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/availability-design.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/brownfield-design.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-ansible-replacement.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-nixos-base.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-rust-rewrite.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/fleet-goals.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/getting-started.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/hybrid-storage-design.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/landscape.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/logging-service-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/neon-migration-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/new-server-storage-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/operator-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-debian-container-m1.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-dns-cutover.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-guided-data-migration.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m1.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m2-m3.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m4-m5.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-render-cutover.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m7.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m8.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m9.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-11-hetzner-m10.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/render-migration-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/secrets-guide.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/README.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/ansible.cfg +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/backup.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/baseline.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/bootstrap.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/data.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/deploy.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/domains.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/health.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/inspect.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/logging.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/restart.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/rollback.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/services.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/time.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/health.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/health_gate.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/restart.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/rollback.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/templates/component.service.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/templates/nftables.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/alertmanager-defaults.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/alertmanager.yaml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/grafana.ini.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki-datasource.yml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki-systemd-override.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki.yaml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/nginx-loki-gateway.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-datasource.yml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-defaults.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-rules.yaml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus.yaml.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/templates/alloy-systemd-override.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/templates/config.alloy.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/templates/domain-site.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.service.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.sh.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.timer.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/cloudfall.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.sh.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.timer.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/handlers/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.service.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.sh.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.timer.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/cloudfall.conf.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.service.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.sh.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.timer.j2 +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/defaults/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/meta/argument_specs.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/meta/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/tasks/main.yml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/__init__.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/__main__.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/ansible_inventory.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/artifact.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/cli.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/playbook.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/py.typed +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_ansible_inventory.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_artifact_builder.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_deploy_templates.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_firewall_templates.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_logging_templates.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_nginx_site_templates.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_playbook.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_postgresql_templates.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_time_role.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/README.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/pyproject.toml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/render.yaml +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/src/demo/__init__.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/src/demo/asgi.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/uv.lock +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/README.md +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/__init__.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/__main__.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/agent_server.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/agent_tools.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/ansible_api.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/ansible_reader.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/app.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/audit.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/authoring.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/catalog.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/cli.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/commands.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/cutover.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/dashboard.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/dashboard_server.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/decision.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/domain.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/importer.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/inventory.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/lifecycle.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/migrate.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/observation.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/observe.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/operations.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/operator.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/project.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/py.typed +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/render_api.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/resources.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/secrets.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/service_evidence.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/validation.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/why.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_agent_server.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_ansible_reader.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_app.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_arguments.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_audit.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_authoring.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_catalog.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_commands.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_cutover.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_dashboard_server.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_data_migration.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_decision.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_importer.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_inventory.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_lifecycle.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_migrate.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_observe.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_operations_dashboard.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_operator.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_project.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_render_api.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_resources.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_secrets.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_service_evidence.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_validation.py +0 -0
- {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_why.py +0 -0
|
@@ -15,7 +15,8 @@ Debian servers without Kubernetes (see the [fleet goals](docs/fleet-goals.md)),
|
|
|
15
15
|
on a config the team already owns. This document describes the durable
|
|
16
16
|
design; [`ROADMAP.md`](ROADMAP.md) is the authoritative source for what is
|
|
17
17
|
implemented today, and the [brownfield design](docs/brownfield-design.md)
|
|
18
|
-
describes the
|
|
18
|
+
describes the next step, whose operations catalog, gate and record are
|
|
19
|
+
built while safe edits and autonomy from the record are not.
|
|
19
20
|
|
|
20
21
|
Every layer keeps the same invariants: no action without declared config, no
|
|
21
22
|
status without evidence, no compliance without audit, no decision without a
|
|
@@ -70,6 +70,11 @@ Notable changes to Cloudfall. The format follows
|
|
|
70
70
|
|
|
71
71
|
### Changed
|
|
72
72
|
|
|
73
|
+
- The README, the site, the roadmap and the architecture say what is built
|
|
74
|
+
on a team's own Ansible repository (the operations catalog, the gate,
|
|
75
|
+
decision records and `cloudfall why`) instead of calling it unbuilt, show
|
|
76
|
+
a real `cloudfall why` answer, and address both teams leaving a PaaS and
|
|
77
|
+
teams already running Ansible
|
|
73
78
|
- The README opens with what Cloudfall is, a diagram of the gate, a short
|
|
74
79
|
quickstart and a guide index; the long walkthroughs moved to
|
|
75
80
|
[docs/getting-started.md](docs/getting-started.md). The repository has issue
|
|
@@ -81,10 +81,8 @@ marketing copy; it is the release policy.
|
|
|
81
81
|
## 8 · Open core, never crippled
|
|
82
82
|
|
|
83
83
|
Cloudfall is AGPL-3.0. The free tool must be genuinely sufficient to leave
|
|
84
|
-
a PaaS and run your own server; sustainability comes from
|
|
85
|
-
|
|
86
|
-
What is free stays free, and the line between the two is stated in the
|
|
87
|
-
README, not discovered at checkout.
|
|
84
|
+
a PaaS and run your own server; sustainability never comes from holding
|
|
85
|
+
back the open core. What is free stays free.
|
|
88
86
|
|
|
89
87
|
---
|
|
90
88
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cloudfall
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.0rc2
|
|
4
4
|
Summary: The operator's record for self-hosted servers run by an AI agent: Ansible executes, Cloudfall gates, verifies and keeps the receipts
|
|
5
5
|
Project-URL: Homepage, https://cloudfall.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/cloudfall-dev/cloudfall
|
|
@@ -72,15 +72,44 @@ flowchart LR
|
|
|
72
72
|
R -.->|earned autonomy| G
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
### What the record looks like
|
|
76
|
+
|
|
77
|
+
Ask why something happened and Cloudfall answers from the record alone. This
|
|
78
|
+
is a real decision from the maintainer's six-host production fleet, a
|
|
79
|
+
`converge` run of the team's own `site.yml` (output abridged to the story):
|
|
80
|
+
|
|
81
|
+
```console
|
|
82
|
+
$ cloudfall why --operation converge
|
|
83
|
+
It was based on 6 host snapshots in tmp/observed, the latest observed at 2026-09-21T10:39:30Z.
|
|
84
|
+
At 2026-09-22T19:38:45Z the mutating operation converge (site.yml) was proposed against the whole fleet with no inputs.
|
|
85
|
+
Check mode would have changed no host and left 3 hosts untouched; the diff is decisions/converge-20260922193845.diff (sha256 4c8458ca26c5…, 48061 bytes).
|
|
86
|
+
It waited for an approval: a mutating operation runs in check mode first and waits for an approval of the recorded diff.
|
|
87
|
+
roman approved it at 2026-09-22T19:39:51Z.
|
|
88
|
+
The run at 2026-09-22T19:39:51Z exited 0 and changed no host; the log is decisions/converge-20260922193845-execution.log.
|
|
89
|
+
The verify step at 2026-09-22T19:40:39Z exited 0 and changed no host; the log is decisions/converge-20260922193845-verify.log.
|
|
90
|
+
It ended verified: the run succeeded and the verify step changed nothing.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Every sentence is drawn from a field of the record. `--format html` renders
|
|
94
|
+
the same answer as one page, and agents get it as the `why` tool.
|
|
95
|
+
|
|
75
96
|
## Who it is for
|
|
76
97
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
(hardened baseline, monitoring, PostgreSQL and Redis with backups that
|
|
98
|
+
**Founders leaving a PaaS.** A small production app with a database costs
|
|
99
|
+
about $83 a month on Render and runs on a Hetzner server for under €10.
|
|
100
|
+
Cloudfall moves your applications and databases onto one or two servers you
|
|
101
|
+
own (hardened baseline, monitoring, PostgreSQL and Redis with backups that
|
|
82
102
|
provably restore, health-gated deploys with rollback, a real DNS cutover),
|
|
83
103
|
and an always-on operator runs them there with a receipt for every action.
|
|
104
|
+
Start with the [Render migration guide](docs/render-migration-guide.md).
|
|
105
|
+
|
|
106
|
+
**Teams and agencies that already run Ansible.** Point Cloudfall at your own
|
|
107
|
+
repository: it reads your inventory, and each playbook you declare in
|
|
108
|
+
`operations/` becomes an operation with a risk level, a verify step and a
|
|
109
|
+
record. Your agent sees exactly those operations as tools, a mutating one
|
|
110
|
+
runs in check mode and waits for a person to approve the diff, and
|
|
111
|
+
`cloudfall why` answers for it afterwards. No import, no second copy of
|
|
112
|
+
your fleet. See the [brownfield design](docs/brownfield-design.md).
|
|
84
113
|
|
|
85
114
|
> **Proven live, not promised.** Everything implemented has run on
|
|
86
115
|
> disposable Hetzner Cloud Debian 13 servers: an application actually hosted
|
|
@@ -148,8 +177,8 @@ and drift audit to the live dashboard, is in
|
|
|
148
177
|
|
|
149
178
|
```console
|
|
150
179
|
uv run cloudfall import render render.yaml --application acme --server h1
|
|
151
|
-
uv run cloudfall migrate --build
|
|
152
|
-
uv run cloudfall migrate --build
|
|
180
|
+
uv run cloudfall migrate --build web=main # show the plan
|
|
181
|
+
uv run cloudfall migrate --build web=main --yes # run it
|
|
153
182
|
```
|
|
154
183
|
|
|
155
184
|
The importer never guesses silently: `IMPORT-REPORT.md` records what was not
|
|
@@ -189,8 +218,8 @@ contracts. See [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
|
189
218
|
|
|
190
219
|
## Status
|
|
191
220
|
|
|
192
|
-
Cloudfall is pre-1.0 and honestly labeled.
|
|
193
|
-
disposable Debian targets:
|
|
221
|
+
Cloudfall is pre-1.0 and honestly labeled. On servers Cloudfall sets up,
|
|
222
|
+
implemented and proven live on disposable Debian targets:
|
|
194
223
|
|
|
195
224
|
- Typed YAML config with JSON Schemas, deterministic Ansible inventory,
|
|
196
225
|
read-only inspection and config-versus-observed drift audit
|
|
@@ -203,18 +232,19 @@ disposable Debian targets:
|
|
|
203
232
|
- `cloudfall mcp serve` and the always-on operator with receipted proposals
|
|
204
233
|
and policy-bounded autonomy
|
|
205
234
|
|
|
206
|
-
|
|
207
|
-
fleet
|
|
208
|
-
recovery). See the [roadmap](ROADMAP.md).
|
|
235
|
+
On your own Ansible repository, implemented and run on the maintainer's
|
|
236
|
+
production fleet:
|
|
209
237
|
|
|
210
|
-
|
|
238
|
+
- Read-only observation through your inventory and `ansible.cfg`, and drift
|
|
239
|
+
audit without a Cloudfall project
|
|
240
|
+
- The operations catalog, the check-then-approve gate, and one decision
|
|
241
|
+
record per operation with its evidence, diff, approver and verify result
|
|
242
|
+
- `cloudfall why` and `cloudfall mcp serve --repository`, where the tool
|
|
243
|
+
list is your catalog
|
|
211
244
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
audit entry. Ansible is the hand, the agent is the brain, Cloudfall is the
|
|
216
|
-
conscience. Designed, not yet built:
|
|
217
|
-
[docs/brownfield-design.md](docs/brownfield-design.md).
|
|
245
|
+
Not yet validated live: bare-metal RAID/storage provisioning. Not built yet:
|
|
246
|
+
safe edits of your inventory and variables, and autonomy computed from the
|
|
247
|
+
record. See the [roadmap](ROADMAP.md).
|
|
218
248
|
|
|
219
249
|
## Community
|
|
220
250
|
|
|
@@ -225,8 +255,5 @@ conscience. Designed, not yet built:
|
|
|
225
255
|
|
|
226
256
|
## License
|
|
227
257
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
always-on operator and commercial licensing are how the project sustains
|
|
231
|
-
itself; neither holds back the open core. Commercial licensing exceptions
|
|
232
|
-
are available from the copyright holder.
|
|
258
|
+
Cloudfall is free under the [GNU AGPL-3.0-or-later](LICENSE). Commercial
|
|
259
|
+
licensing exceptions are available from the copyright holder.
|
|
@@ -44,15 +44,44 @@ flowchart LR
|
|
|
44
44
|
R -.->|earned autonomy| G
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
### What the record looks like
|
|
48
|
+
|
|
49
|
+
Ask why something happened and Cloudfall answers from the record alone. This
|
|
50
|
+
is a real decision from the maintainer's six-host production fleet, a
|
|
51
|
+
`converge` run of the team's own `site.yml` (output abridged to the story):
|
|
52
|
+
|
|
53
|
+
```console
|
|
54
|
+
$ cloudfall why --operation converge
|
|
55
|
+
It was based on 6 host snapshots in tmp/observed, the latest observed at 2026-09-21T10:39:30Z.
|
|
56
|
+
At 2026-09-22T19:38:45Z the mutating operation converge (site.yml) was proposed against the whole fleet with no inputs.
|
|
57
|
+
Check mode would have changed no host and left 3 hosts untouched; the diff is decisions/converge-20260922193845.diff (sha256 4c8458ca26c5…, 48061 bytes).
|
|
58
|
+
It waited for an approval: a mutating operation runs in check mode first and waits for an approval of the recorded diff.
|
|
59
|
+
roman approved it at 2026-09-22T19:39:51Z.
|
|
60
|
+
The run at 2026-09-22T19:39:51Z exited 0 and changed no host; the log is decisions/converge-20260922193845-execution.log.
|
|
61
|
+
The verify step at 2026-09-22T19:40:39Z exited 0 and changed no host; the log is decisions/converge-20260922193845-verify.log.
|
|
62
|
+
It ended verified: the run succeeded and the verify step changed nothing.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Every sentence is drawn from a field of the record. `--format html` renders
|
|
66
|
+
the same answer as one page, and agents get it as the `why` tool.
|
|
67
|
+
|
|
47
68
|
## Who it is for
|
|
48
69
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
(hardened baseline, monitoring, PostgreSQL and Redis with backups that
|
|
70
|
+
**Founders leaving a PaaS.** A small production app with a database costs
|
|
71
|
+
about $83 a month on Render and runs on a Hetzner server for under €10.
|
|
72
|
+
Cloudfall moves your applications and databases onto one or two servers you
|
|
73
|
+
own (hardened baseline, monitoring, PostgreSQL and Redis with backups that
|
|
54
74
|
provably restore, health-gated deploys with rollback, a real DNS cutover),
|
|
55
75
|
and an always-on operator runs them there with a receipt for every action.
|
|
76
|
+
Start with the [Render migration guide](docs/render-migration-guide.md).
|
|
77
|
+
|
|
78
|
+
**Teams and agencies that already run Ansible.** Point Cloudfall at your own
|
|
79
|
+
repository: it reads your inventory, and each playbook you declare in
|
|
80
|
+
`operations/` becomes an operation with a risk level, a verify step and a
|
|
81
|
+
record. Your agent sees exactly those operations as tools, a mutating one
|
|
82
|
+
runs in check mode and waits for a person to approve the diff, and
|
|
83
|
+
`cloudfall why` answers for it afterwards. No import, no second copy of
|
|
84
|
+
your fleet. See the [brownfield design](docs/brownfield-design.md).
|
|
56
85
|
|
|
57
86
|
> **Proven live, not promised.** Everything implemented has run on
|
|
58
87
|
> disposable Hetzner Cloud Debian 13 servers: an application actually hosted
|
|
@@ -120,8 +149,8 @@ and drift audit to the live dashboard, is in
|
|
|
120
149
|
|
|
121
150
|
```console
|
|
122
151
|
uv run cloudfall import render render.yaml --application acme --server h1
|
|
123
|
-
uv run cloudfall migrate --build
|
|
124
|
-
uv run cloudfall migrate --build
|
|
152
|
+
uv run cloudfall migrate --build web=main # show the plan
|
|
153
|
+
uv run cloudfall migrate --build web=main --yes # run it
|
|
125
154
|
```
|
|
126
155
|
|
|
127
156
|
The importer never guesses silently: `IMPORT-REPORT.md` records what was not
|
|
@@ -161,8 +190,8 @@ contracts. See [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
|
161
190
|
|
|
162
191
|
## Status
|
|
163
192
|
|
|
164
|
-
Cloudfall is pre-1.0 and honestly labeled.
|
|
165
|
-
disposable Debian targets:
|
|
193
|
+
Cloudfall is pre-1.0 and honestly labeled. On servers Cloudfall sets up,
|
|
194
|
+
implemented and proven live on disposable Debian targets:
|
|
166
195
|
|
|
167
196
|
- Typed YAML config with JSON Schemas, deterministic Ansible inventory,
|
|
168
197
|
read-only inspection and config-versus-observed drift audit
|
|
@@ -175,18 +204,19 @@ disposable Debian targets:
|
|
|
175
204
|
- `cloudfall mcp serve` and the always-on operator with receipted proposals
|
|
176
205
|
and policy-bounded autonomy
|
|
177
206
|
|
|
178
|
-
|
|
179
|
-
fleet
|
|
180
|
-
recovery). See the [roadmap](ROADMAP.md).
|
|
207
|
+
On your own Ansible repository, implemented and run on the maintainer's
|
|
208
|
+
production fleet:
|
|
181
209
|
|
|
182
|
-
|
|
210
|
+
- Read-only observation through your inventory and `ansible.cfg`, and drift
|
|
211
|
+
audit without a Cloudfall project
|
|
212
|
+
- The operations catalog, the check-then-approve gate, and one decision
|
|
213
|
+
record per operation with its evidence, diff, approver and verify result
|
|
214
|
+
- `cloudfall why` and `cloudfall mcp serve --repository`, where the tool
|
|
215
|
+
list is your catalog
|
|
183
216
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
audit entry. Ansible is the hand, the agent is the brain, Cloudfall is the
|
|
188
|
-
conscience. Designed, not yet built:
|
|
189
|
-
[docs/brownfield-design.md](docs/brownfield-design.md).
|
|
217
|
+
Not yet validated live: bare-metal RAID/storage provisioning. Not built yet:
|
|
218
|
+
safe edits of your inventory and variables, and autonomy computed from the
|
|
219
|
+
record. See the [roadmap](ROADMAP.md).
|
|
190
220
|
|
|
191
221
|
## Community
|
|
192
222
|
|
|
@@ -197,8 +227,5 @@ conscience. Designed, not yet built:
|
|
|
197
227
|
|
|
198
228
|
## License
|
|
199
229
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
always-on operator and commercial licensing are how the project sustains
|
|
203
|
-
itself; neither holds back the open core. Commercial licensing exceptions
|
|
204
|
-
are available from the copyright holder.
|
|
230
|
+
Cloudfall is free under the [GNU AGPL-3.0-or-later](LICENSE). Commercial
|
|
231
|
+
licensing exceptions are available from the copyright holder.
|
|
@@ -13,8 +13,11 @@ The first story, proven live in M0–M10:
|
|
|
13
13
|
> from GitHub with health checks and rollback, and a DNS cutover checklist.
|
|
14
14
|
> An always-on operator then runs it there, with a receipt for every action.
|
|
15
15
|
|
|
16
|
-
The second story,
|
|
17
|
-
[brownfield design](docs/brownfield-design.md)):
|
|
16
|
+
The second story, under way (M15–M17, see the
|
|
17
|
+
[brownfield design](docs/brownfield-design.md)): the operations catalog,
|
|
18
|
+
the gate and the decision record are built and have run on the
|
|
19
|
+
maintainer's own production fleet; safe edits and autonomy from the record
|
|
20
|
+
are not built yet:
|
|
18
21
|
|
|
19
22
|
> A team that already runs Ansible points its agent at its own repository.
|
|
20
23
|
> Cloudfall reads their inventory as the only config, exposes each of their
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cloudfall"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.0rc2"
|
|
4
4
|
description = "The operator's record for self-hosted servers run by an AI agent: Ansible executes, Cloudfall gates, verifies and keeps the receipts"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-or-later"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/server-types/debian-application.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/ssh-public-keys/example-admin.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/applications/crm.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/servers/h1.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-ansible-replacement.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-debian-container-m1.md
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-guided-data-migration.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/defaults/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/handlers/main.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/meta/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/tasks/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/defaults/main.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/meta/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/tasks/main.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/defaults/main.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/meta/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/health.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/restart.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/rollback.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/defaults/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/handlers/main.yml
RENAMED
|
File without changes
|
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/meta/main.yml
RENAMED
|
File without changes
|
{cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/tasks/main.yml
RENAMED
|
File without changes
|