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.
Files changed (273) hide show
  1. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/ARCHITECTURE.md +2 -1
  2. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CHANGELOG.md +5 -0
  3. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/MANIFESTO.md +2 -4
  4. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/PKG-INFO +52 -25
  5. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/README.md +51 -24
  6. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/ROADMAP.md +5 -2
  7. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/pyproject.toml +1 -1
  8. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/.ansible-lint +0 -0
  9. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/.gitignore +0 -0
  10. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CODE_OF_CONDUCT.md +0 -0
  11. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/CONTRIBUTING.md +0 -0
  12. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/LICENSE +0 -0
  13. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/SECURITY.md +0 -0
  14. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/Taskfile.yml +0 -0
  15. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/README.md +0 -0
  16. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/alert-rules/postgresql-down.yaml +0 -0
  17. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/applications/crm.yaml +0 -0
  18. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/components/crm-backend.yaml +0 -0
  19. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/domains/crm-site.yaml +0 -0
  20. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/logging-stacks/operations.yaml +0 -0
  21. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/operator-policies/production.yaml +0 -0
  22. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/server-types/debian-application.yaml +0 -0
  23. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/servers/h1.yaml +0 -0
  24. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/servers/h2.yaml +0 -0
  25. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/services/postgresql-main.yaml +0 -0
  26. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/services/redis-cache.yaml +0 -0
  27. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/examples/ssh-public-keys/example-admin.yaml +0 -0
  28. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/alert-rule.schema.json +0 -0
  29. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/application.schema.json +0 -0
  30. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/artifact.schema.json +0 -0
  31. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/backup-receipt.schema.json +0 -0
  32. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/common.schema.json +0 -0
  33. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/component.schema.json +0 -0
  34. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/deployment-receipt.schema.json +0 -0
  35. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/domain.schema.json +0 -0
  36. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/environment-receipt.schema.json +0 -0
  37. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/logging-stack.schema.json +0 -0
  38. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/observed-domain.schema.json +0 -0
  39. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/observed-server.schema.json +0 -0
  40. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operation-decision.schema.json +0 -0
  41. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operation.schema.json +0 -0
  42. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operator-policy.schema.json +0 -0
  43. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/operator-proposal.schema.json +0 -0
  44. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/release-receipt.schema.json +0 -0
  45. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/server-type.schema.json +0 -0
  46. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/server.schema.json +0 -0
  47. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/service.schema.json +0 -0
  48. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/schemas/v1/ssh-public-key.schema.json +0 -0
  49. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/applications/crm.yaml +0 -0
  50. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/components/crm-backend.yaml +0 -0
  51. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/server-types/debian-application.yaml +0 -0
  52. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/missing-server/servers/h1.yaml +0 -0
  53. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/invalid/schema/components/component-unknown-field.yaml +0 -0
  54. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/observed/compliant/h1.json +0 -0
  55. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/config/tests/observed/compliant/h2.json +0 -0
  56. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/ansible-context.md +0 -0
  57. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/assets/logo.svg +0 -0
  58. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/availability-design.md +0 -0
  59. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/brownfield-design.md +0 -0
  60. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-ansible-replacement.md +0 -0
  61. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-nixos-base.md +0 -0
  62. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/decisions/2026-09-14-no-rust-rewrite.md +0 -0
  63. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/fleet-goals.md +0 -0
  64. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/getting-started.md +0 -0
  65. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/hybrid-storage-design.md +0 -0
  66. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/landscape.md +0 -0
  67. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/logging-service-guide.md +0 -0
  68. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/neon-migration-guide.md +0 -0
  69. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/new-server-storage-guide.md +0 -0
  70. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/operator-guide.md +0 -0
  71. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-debian-container-m1.md +0 -0
  72. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-dns-cutover.md +0 -0
  73. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-guided-data-migration.md +0 -0
  74. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m1.md +0 -0
  75. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m2-m3.md +0 -0
  76. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-hetzner-m4-m5.md +0 -0
  77. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-08-render-cutover.md +0 -0
  78. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m7.md +0 -0
  79. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m8.md +0 -0
  80. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-10-hetzner-m9.md +0 -0
  81. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/proving-runs/2026-09-11-hetzner-m10.md +0 -0
  82. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/render-migration-guide.md +0 -0
  83. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/docs/secrets-guide.md +0 -0
  84. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/README.md +0 -0
  85. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/ansible.cfg +0 -0
  86. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/backup.yml +0 -0
  87. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/baseline.yml +0 -0
  88. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/bootstrap.yml +0 -0
  89. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/data.yml +0 -0
  90. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/deploy.yml +0 -0
  91. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/domains.yml +0 -0
  92. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/health.yml +0 -0
  93. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/inspect.yml +0 -0
  94. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/logging.yml +0 -0
  95. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/restart.yml +0 -0
  96. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/rollback.yml +0 -0
  97. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/services.yml +0 -0
  98. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/playbooks/time.yml +0 -0
  99. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/defaults/main.yml +0 -0
  100. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/handlers/main.yml +0 -0
  101. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/meta/argument_specs.yml +0 -0
  102. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/meta/main.yml +0 -0
  103. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_access/tasks/main.yml +0 -0
  104. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/defaults/main.yml +0 -0
  105. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/meta/argument_specs.yml +0 -0
  106. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/meta/main.yml +0 -0
  107. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_bootstrap/tasks/main.yml +0 -0
  108. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/defaults/main.yml +0 -0
  109. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/meta/argument_specs.yml +0 -0
  110. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/meta/main.yml +0 -0
  111. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_data_migration/tasks/main.yml +0 -0
  112. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/defaults/main.yml +0 -0
  113. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/meta/argument_specs.yml +0 -0
  114. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/meta/main.yml +0 -0
  115. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/health.yml +0 -0
  116. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/health_gate.yml +0 -0
  117. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/main.yml +0 -0
  118. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/restart.yml +0 -0
  119. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/tasks/rollback.yml +0 -0
  120. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_deploy/templates/component.service.j2 +0 -0
  121. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/defaults/main.yml +0 -0
  122. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/handlers/main.yml +0 -0
  123. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/meta/argument_specs.yml +0 -0
  124. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/meta/main.yml +0 -0
  125. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/tasks/main.yml +0 -0
  126. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_firewall/templates/nftables.conf.j2 +0 -0
  127. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/defaults/main.yml +0 -0
  128. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/meta/argument_specs.yml +0 -0
  129. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/meta/main.yml +0 -0
  130. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_inspect/tasks/main.yml +0 -0
  131. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/defaults/main.yml +0 -0
  132. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/handlers/main.yml +0 -0
  133. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/meta/argument_specs.yml +0 -0
  134. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/meta/main.yml +0 -0
  135. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/tasks/main.yml +0 -0
  136. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/alertmanager-defaults.j2 +0 -0
  137. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/alertmanager.yaml.j2 +0 -0
  138. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/grafana.ini.j2 +0 -0
  139. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki-datasource.yml.j2 +0 -0
  140. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki-systemd-override.conf.j2 +0 -0
  141. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/loki.yaml.j2 +0 -0
  142. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/nginx-loki-gateway.conf.j2 +0 -0
  143. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-datasource.yml.j2 +0 -0
  144. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-defaults.j2 +0 -0
  145. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus-rules.yaml.j2 +0 -0
  146. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_backend/templates/prometheus.yaml.j2 +0 -0
  147. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/defaults/main.yml +0 -0
  148. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/handlers/main.yml +0 -0
  149. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/meta/argument_specs.yml +0 -0
  150. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/meta/main.yml +0 -0
  151. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/tasks/main.yml +0 -0
  152. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/templates/alloy-systemd-override.conf.j2 +0 -0
  153. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_logging_collector/templates/config.alloy.j2 +0 -0
  154. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/defaults/main.yml +0 -0
  155. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/handlers/main.yml +0 -0
  156. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/meta/argument_specs.yml +0 -0
  157. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/meta/main.yml +0 -0
  158. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/tasks/main.yml +0 -0
  159. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_nginx_site/templates/domain-site.conf.j2 +0 -0
  160. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/defaults/main.yml +0 -0
  161. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/handlers/main.yml +0 -0
  162. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/meta/argument_specs.yml +0 -0
  163. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/meta/main.yml +0 -0
  164. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/tasks/main.yml +0 -0
  165. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.service.j2 +0 -0
  166. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.sh.j2 +0 -0
  167. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/backup.timer.j2 +0 -0
  168. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/cloudfall.conf.j2 +0 -0
  169. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.service.j2 +0 -0
  170. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.sh.j2 +0 -0
  171. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_postgresql/templates/restore-check.timer.j2 +0 -0
  172. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/defaults/main.yml +0 -0
  173. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/handlers/main.yml +0 -0
  174. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/meta/argument_specs.yml +0 -0
  175. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/meta/main.yml +0 -0
  176. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/tasks/main.yml +0 -0
  177. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.service.j2 +0 -0
  178. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.sh.j2 +0 -0
  179. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/backup.timer.j2 +0 -0
  180. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/cloudfall.conf.j2 +0 -0
  181. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.service.j2 +0 -0
  182. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.sh.j2 +0 -0
  183. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_redis/templates/restore-check.timer.j2 +0 -0
  184. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/defaults/main.yml +0 -0
  185. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/meta/argument_specs.yml +0 -0
  186. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/meta/main.yml +0 -0
  187. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_time/tasks/main.yml +0 -0
  188. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/defaults/main.yml +0 -0
  189. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/meta/argument_specs.yml +0 -0
  190. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/meta/main.yml +0 -0
  191. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/ansible/roles/cloudfall_unattended_upgrades/tasks/main.yml +0 -0
  192. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/__init__.py +0 -0
  193. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/__main__.py +0 -0
  194. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/ansible_inventory.py +0 -0
  195. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/artifact.py +0 -0
  196. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/cli.py +0 -0
  197. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/playbook.py +0 -0
  198. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/src/cloudfall_engine/py.typed +0 -0
  199. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_ansible_inventory.py +0 -0
  200. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_artifact_builder.py +0 -0
  201. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_deploy_templates.py +0 -0
  202. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_firewall_templates.py +0 -0
  203. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_logging_templates.py +0 -0
  204. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_nginx_site_templates.py +0 -0
  205. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_playbook.py +0 -0
  206. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_postgresql_templates.py +0 -0
  207. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/engine/tests/test_time_role.py +0 -0
  208. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/README.md +0 -0
  209. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/pyproject.toml +0 -0
  210. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/render.yaml +0 -0
  211. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/src/demo/__init__.py +0 -0
  212. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/src/demo/asgi.py +0 -0
  213. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/examples/render-demo/uv.lock +0 -0
  214. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/README.md +0 -0
  215. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/__init__.py +0 -0
  216. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/__main__.py +0 -0
  217. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/agent_server.py +0 -0
  218. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/agent_tools.py +0 -0
  219. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/ansible_api.py +0 -0
  220. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/ansible_reader.py +0 -0
  221. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/app.py +0 -0
  222. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/audit.py +0 -0
  223. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/authoring.py +0 -0
  224. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/catalog.py +0 -0
  225. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/cli.py +0 -0
  226. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/commands.py +0 -0
  227. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/cutover.py +0 -0
  228. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/dashboard.py +0 -0
  229. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/dashboard_server.py +0 -0
  230. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/decision.py +0 -0
  231. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/domain.py +0 -0
  232. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/importer.py +0 -0
  233. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/inventory.py +0 -0
  234. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/lifecycle.py +0 -0
  235. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/migrate.py +0 -0
  236. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/observation.py +0 -0
  237. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/observe.py +0 -0
  238. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/operations.py +0 -0
  239. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/operator.py +0 -0
  240. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/project.py +0 -0
  241. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/py.typed +0 -0
  242. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/render_api.py +0 -0
  243. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/resources.py +0 -0
  244. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/secrets.py +0 -0
  245. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/service_evidence.py +0 -0
  246. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/validation.py +0 -0
  247. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/src/cloudfall/why.py +0 -0
  248. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_agent_server.py +0 -0
  249. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_ansible_reader.py +0 -0
  250. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_app.py +0 -0
  251. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_arguments.py +0 -0
  252. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_audit.py +0 -0
  253. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_authoring.py +0 -0
  254. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_catalog.py +0 -0
  255. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_commands.py +0 -0
  256. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_cutover.py +0 -0
  257. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_dashboard_server.py +0 -0
  258. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_data_migration.py +0 -0
  259. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_decision.py +0 -0
  260. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_importer.py +0 -0
  261. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_inventory.py +0 -0
  262. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_lifecycle.py +0 -0
  263. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_migrate.py +0 -0
  264. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_observe.py +0 -0
  265. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_operations_dashboard.py +0 -0
  266. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_operator.py +0 -0
  267. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_project.py +0 -0
  268. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_render_api.py +0 -0
  269. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_resources.py +0 -0
  270. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_secrets.py +0 -0
  271. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_service_evidence.py +0 -0
  272. {cloudfall-0.6.0rc1 → cloudfall-0.6.0rc2}/sdk/tests/test_validation.py +0 -0
  273. {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 proposed next step, none of which is built.
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 the hosted
85
- operator and commercial licensing, never from holding back the open core.
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.0rc1
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
- Teams with one to twenty servers and no platform hire: founders leaving a
78
- PaaS whose bill crossed $1,000 a month, and anyone whose servers are already
79
- run by Claude Code, Codex or another agent. Today Cloudfall moves your
80
- applications and databases onto one or two Hetzner-class servers you own
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 acme-api=main # show the plan
152
- uv run cloudfall migrate --build acme-api=main --yes # run it
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. Implemented and proven live on
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
- Not yet validated live: bare-metal RAID/storage provisioning. Next up: the
207
- fleet-density track (resource sharing, node drain, PostgreSQL point-in-time
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
- ### Direction: your Ansible, not ours
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
- Most teams that would use Cloudfall already run Ansible. The next step reads
213
- their inventory as the only config and exposes each of their playbooks to
214
- the agent as a declared operation with a risk level, a verify step and an
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
- Everything in this repository is free under the
229
- [GNU AGPL-3.0-or-later](LICENSE) and sufficient on its own. The hosted
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
- Teams with one to twenty servers and no platform hire: founders leaving a
50
- PaaS whose bill crossed $1,000 a month, and anyone whose servers are already
51
- run by Claude Code, Codex or another agent. Today Cloudfall moves your
52
- applications and databases onto one or two Hetzner-class servers you own
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 acme-api=main # show the plan
124
- uv run cloudfall migrate --build acme-api=main --yes # run it
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. Implemented and proven live on
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
- Not yet validated live: bare-metal RAID/storage provisioning. Next up: the
179
- fleet-density track (resource sharing, node drain, PostgreSQL point-in-time
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
- ### Direction: your Ansible, not ours
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
- Most teams that would use Cloudfall already run Ansible. The next step reads
185
- their inventory as the only config and exposes each of their playbooks to
186
- the agent as a declared operation with a risk level, a verify step and an
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
- Everything in this repository is free under the
201
- [GNU AGPL-3.0-or-later](LICENSE) and sufficient on its own. The hosted
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, designed and not yet built (M15–M17, see the
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.0rc1"
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