mayhem-cli 0.6.2__tar.gz → 0.8.0__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 (360) hide show
  1. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/.github/workflows/release.yml +4 -4
  2. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/Justfile +20 -19
  3. mayhem_cli-0.8.0/PKG-INFO +404 -0
  4. mayhem_cli-0.8.0/README.md +389 -0
  5. mayhem_cli-0.8.0/docs/README.md +74 -0
  6. mayhem_cli-0.8.0/docs/adr/adr-m7-1-k8s-executor.md +98 -0
  7. mayhem_cli-0.8.0/docs/adr-adr-m7-1-k8s-executor-flip.md +172 -0
  8. mayhem_cli-0.8.0/docs/architecture/fault-taxonomy.md +5 -0
  9. mayhem_cli-0.8.0/docs/architecture/safety.md +12 -0
  10. mayhem_cli-0.8.0/docs/architecture/toolkit.md +5 -0
  11. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/docs/compensation.md +6 -2
  12. mayhem_cli-0.8.0/docs/config.md +212 -0
  13. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/docs/drill-spec.md +105 -23
  14. mayhem_cli-0.8.0/docs/fault-catalog/README.md +21 -0
  15. mayhem_cli-0.8.0/docs/fault-catalog/reliability-matrix.md +64 -0
  16. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/docs/grounding-log.md +5 -0
  17. mayhem_cli-0.8.0/docs/k8s-new.md +5 -0
  18. mayhem_cli-0.8.0/docs/k8s-plan-1.md +437 -0
  19. mayhem_cli-0.8.0/docs/k8s-plan-2.md +387 -0
  20. mayhem_cli-0.8.0/docs/m7-k8s-executor-discovery.md +164 -0
  21. mayhem_cli-0.8.0/docs/new-plan/00-product-and-cli-roadmap.md +84 -0
  22. mayhem_cli-0.8.0/docs/new-plan/01-workflow-command-architecture.md +84 -0
  23. mayhem_cli-0.8.0/docs/new-plan/02-guided-onboarding-and-target-profiles.md +75 -0
  24. mayhem_cli-0.8.0/docs/new-plan/03-plan-first-execution-and-unified-evidence.md +77 -0
  25. mayhem_cli-0.8.0/docs/new-plan/04-output-errors-and-script-compatibility.md +77 -0
  26. mayhem_cli-0.8.0/docs/new-plan/05-configuration-policy-and-environment-safety.md +73 -0
  27. mayhem_cli-0.8.0/docs/new-plan/06-docker-podman-reliability-slice.md +75 -0
  28. mayhem_cli-0.8.0/docs/new-plan/07-first-class-kubernetes-engine.md +78 -0
  29. mayhem_cli-0.8.0/docs/new-plan/08-fault-catalog-reliability-matrix.md +83 -0
  30. mayhem_cli-0.8.0/docs/new-plan/09-campaigns-coverage-and-explore-loop.md +79 -0
  31. mayhem_cli-0.8.0/docs/new-plan/10-diagnostics-recovery-and-reporting.md +76 -0
  32. mayhem_cli-0.8.0/docs/new-plan/11-extension-api-and-packaging.md +88 -0
  33. mayhem_cli-0.8.0/docs/new-plan/README.md +52 -0
  34. mayhem_cli-0.8.0/docs/policy-and-break-glass.md +28 -0
  35. mayhem_cli-0.8.0/docs/product/cli-product-direction.md +64 -0
  36. mayhem_cli-0.8.0/docs/product/command-architecture.md +100 -0
  37. mayhem_cli-0.8.0/docs/provider-sdk.md +217 -0
  38. mayhem_cli-0.8.0/docs/reference/cli.md +110 -0
  39. mayhem_cli-0.8.0/docs/reference/experiment-dsl.md +10 -0
  40. mayhem_cli-0.8.0/docs/reference/fault-catalog.md +82 -0
  41. mayhem_cli-0.8.0/docs/reference/output-schema.md +47 -0
  42. mayhem_cli-0.8.0/docs/reference/sqlite-schema.md +15 -0
  43. mayhem_cli-0.8.0/docs/superpowers/plans/2026-09-24-container-kubernetes-fault-expansion-plan.md +267 -0
  44. mayhem_cli-0.8.0/docs/superpowers/plans/2026-09-24-documentation-to-implementation-plan.md +406 -0
  45. mayhem_cli-0.8.0/docs/superpowers/specs/2026-09-24-container-kubernetes-fault-expansion-design.md +61 -0
  46. mayhem_cli-0.8.0/docs/superpowers/specs/2026-09-24-documentation-to-implementation-design.md +91 -0
  47. mayhem_cli-0.8.0/examples/k8s/README.md +39 -0
  48. mayhem_cli-0.8.0/examples/k8s/mayhem.yaml +207 -0
  49. mayhem_cli-0.8.0/examples/providers/test-catalog.json +40 -0
  50. mayhem_cli-0.8.0/examples/providers/test_provider.py +19 -0
  51. mayhem_cli-0.8.0/examples/testCase/mayhem-safe-docker-podman.yaml +50 -0
  52. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/pyproject.toml +46 -5
  53. mayhem_cli-0.8.0/src/mayhem/agents/executors.py +3931 -0
  54. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/impact.py +37 -1
  55. mayhem_cli-0.8.0/src/mayhem/agents/k8s_control.py +411 -0
  56. mayhem_cli-0.8.0/src/mayhem/agents/k8s_resolve.py +947 -0
  57. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/lease_client.py +7 -0
  58. mayhem_cli-0.8.0/src/mayhem/cli/app.py +226 -0
  59. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/campaign.py +234 -59
  60. mayhem_cli-0.8.0/src/mayhem/cli/command_registry.py +79 -0
  61. mayhem_cli-0.8.0/src/mayhem/cli/commands.py +48 -0
  62. mayhem_cli-0.8.0/src/mayhem/cli/config_cmd.py +71 -0
  63. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/context.py +3 -0
  64. mayhem_cli-0.8.0/src/mayhem/cli/coverage_cmd.py +262 -0
  65. mayhem_cli-0.8.0/src/mayhem/cli/doctor.py +128 -0
  66. mayhem_cli-0.8.0/src/mayhem/cli/errors.py +196 -0
  67. mayhem_cli-0.8.0/src/mayhem/cli/execution.py +129 -0
  68. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/experiment.py +2 -0
  69. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/expert.py +84 -4
  70. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/explore.py +56 -22
  71. mayhem_cli-0.8.0/src/mayhem/cli/extend.py +153 -0
  72. mayhem_cli-0.8.0/src/mayhem/cli/init.py +138 -0
  73. mayhem_cli-0.8.0/src/mayhem/cli/inspect.py +192 -0
  74. mayhem_cli-0.8.0/src/mayhem/cli/lifecycle.py +1745 -0
  75. mayhem_cli-0.8.0/src/mayhem/cli/next_cmd.py +271 -0
  76. mayhem_cli-0.8.0/src/mayhem/cli/output.py +111 -0
  77. mayhem_cli-0.8.0/src/mayhem/cli/render.py +151 -0
  78. mayhem_cli-0.8.0/src/mayhem/cli/renderers.py +193 -0
  79. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/resolver.py +10 -0
  80. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/services.py +167 -19
  81. mayhem_cli-0.8.0/src/mayhem/cli/toolkit.py +139 -0
  82. mayhem_cli-0.8.0/src/mayhem/cli/topology.py +334 -0
  83. mayhem_cli-0.8.0/src/mayhem/cli/workflows.py +110 -0
  84. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/config.py +136 -1
  85. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/cell_runner.py +18 -5
  86. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/compensation.py +180 -7
  87. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/executor.py +748 -9
  88. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/explore_flow.py +40 -17
  89. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/janitor.py +49 -0
  90. mayhem_cli-0.8.0/src/mayhem/controller/k8s_runtime.py +859 -0
  91. mayhem_cli-0.8.0/src/mayhem/controller/plan_diff.py +79 -0
  92. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/planner.py +557 -59
  93. mayhem_cli-0.8.0/src/mayhem/controller/preflight.py +381 -0
  94. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/recovery.py +210 -0
  95. mayhem_cli-0.8.0/src/mayhem/controller/safety.py +576 -0
  96. mayhem_cli-0.8.0/src/mayhem/controller/target_selector.py +3 -0
  97. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/campaigns.py +46 -0
  98. mayhem_cli-0.8.0/src/mayhem/domain/catalog.py +1851 -0
  99. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/common.py +12 -7
  100. mayhem_cli-0.8.0/src/mayhem/domain/coverage.py +314 -0
  101. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/decisions.py +33 -0
  102. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/errors.py +28 -0
  103. mayhem_cli-0.8.0/src/mayhem/domain/evidence.py +57 -0
  104. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/experiments.py +172 -11
  105. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/faults.py +91 -9
  106. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/identity.py +15 -0
  107. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/k8s_adapter.py +62 -6
  108. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/leases.py +50 -1
  109. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/m5_campaign.py +73 -3
  110. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/maniac.py +52 -1
  111. mayhem_cli-0.8.0/src/mayhem/domain/policy.py +140 -0
  112. mayhem_cli-0.8.0/src/mayhem/domain/preflight.py +123 -0
  113. mayhem_cli-0.8.0/src/mayhem/domain/provider.py +323 -0
  114. mayhem_cli-0.8.0/src/mayhem/domain/resolution.py +72 -0
  115. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/runtime_adapter.py +117 -0
  116. mayhem_cli-0.8.0/src/mayhem/domain/target.py +125 -0
  117. mayhem_cli-0.8.0/src/mayhem/domain/target_profiles.py +221 -0
  118. mayhem_cli-0.8.0/src/mayhem/domain/target_selector.py +283 -0
  119. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/topology.py +8 -0
  120. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/campaign_engine.py +77 -0
  121. mayhem_cli-0.8.0/src/mayhem/infra/catalog_report.py +277 -0
  122. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/coverage_repository.py +139 -13
  123. mayhem_cli-0.8.0/src/mayhem/infra/diagnostics.py +963 -0
  124. mayhem_cli-0.8.0/src/mayhem/infra/evidence.py +241 -0
  125. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/lease_repository.py +34 -2
  126. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/migrations.py +13 -0
  127. mayhem_cli-0.8.0/src/mayhem/infra/project_detection.py +115 -0
  128. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/ranking.py +44 -2
  129. mayhem_cli-0.8.0/src/mayhem/infra/report.py +543 -0
  130. mayhem_cli-0.8.0/src/mayhem/providers/__init__.py +19 -0
  131. mayhem_cli-0.8.0/src/mayhem/providers/builtin.py +126 -0
  132. mayhem_cli-0.8.0/src/mayhem/providers/loader.py +316 -0
  133. mayhem_cli-0.8.0/src/mayhem/providers/protocols.py +36 -0
  134. mayhem_cli-0.8.0/src/mayhem/providers/registry.py +80 -0
  135. mayhem_cli-0.8.0/src/mayhem/schemas/output_v1.json +43 -0
  136. mayhem_cli-0.8.0/src/mayhem/topology/providers/adapter_registry.py +86 -0
  137. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/docker_adapter.py +17 -0
  138. mayhem_cli-0.8.0/src/mayhem/topology/providers/k8s_manifest.py +229 -0
  139. mayhem_cli-0.8.0/src/mayhem/topology/providers/kubernetes.py +406 -0
  140. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/e2e/test_cli_e2e.py +77 -67
  141. mayhem_cli-0.8.0/tests/fixtures/cli/commands_show.json +37 -0
  142. mayhem_cli-0.8.0/tests/fixtures/cli/coverage.json +22 -0
  143. mayhem_cli-0.8.0/tests/fixtures/cli/doctor.json +18 -0
  144. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_accept_criteria.py +5 -1
  145. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_additive_schema.py +1 -0
  146. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_campaigns.py +91 -4
  147. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_capability_safety.py +17 -0
  148. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cli.py +191 -7
  149. mayhem_cli-0.8.0/tests/unit/test_cli_active_surface.py +60 -0
  150. mayhem_cli-0.8.0/tests/unit/test_cli_config.py +44 -0
  151. mayhem_cli-0.8.0/tests/unit/test_cli_contract.py +114 -0
  152. mayhem_cli-0.8.0/tests/unit/test_cli_doctor.py +143 -0
  153. mayhem_cli-0.8.0/tests/unit/test_cli_errors.py +132 -0
  154. mayhem_cli-0.8.0/tests/unit/test_cli_execution.py +216 -0
  155. mayhem_cli-0.8.0/tests/unit/test_cli_exhaustive_matrix.py +735 -0
  156. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cli_exit_codes.py +11 -11
  157. mayhem_cli-0.8.0/tests/unit/test_cli_extend.py +149 -0
  158. mayhem_cli-0.8.0/tests/unit/test_cli_init.py +123 -0
  159. mayhem_cli-0.8.0/tests/unit/test_cli_output.py +75 -0
  160. mayhem_cli-0.8.0/tests/unit/test_cli_renderers.py +124 -0
  161. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cli_resolver.py +7 -7
  162. mayhem_cli-0.8.0/tests/unit/test_cli_topology.py +139 -0
  163. mayhem_cli-0.8.0/tests/unit/test_cli_user_regressions.py +59 -0
  164. mayhem_cli-0.8.0/tests/unit/test_command_inventory.py +56 -0
  165. mayhem_cli-0.8.0/tests/unit/test_command_registry.py +33 -0
  166. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_config.py +58 -0
  167. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_container_fault_matrix.py +15 -8
  168. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_coverage.py +82 -7
  169. mayhem_cli-0.8.0/tests/unit/test_diagnostics.py +330 -0
  170. mayhem_cli-0.8.0/tests/unit/test_documentation_consistency.py +58 -0
  171. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_example_specs_yaml.py +5 -3
  172. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_fault_catalog_all.py +56 -8
  173. mayhem_cli-0.8.0/tests/unit/test_fault_catalog_exhaustive.py +946 -0
  174. mayhem_cli-0.8.0/tests/unit/test_fault_catalog_metadata.py +126 -0
  175. mayhem_cli-0.8.0/tests/unit/test_fault_expansion_catalog.py +91 -0
  176. mayhem_cli-0.8.0/tests/unit/test_fault_expansion_container.py +161 -0
  177. mayhem_cli-0.8.0/tests/unit/test_fault_expansion_kubernetes.py +183 -0
  178. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_impact_gate.py +1 -0
  179. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_janitor.py +12 -0
  180. mayhem_cli-0.8.0/tests/unit/test_k8s_cli.py +150 -0
  181. mayhem_cli-0.8.0/tests/unit/test_k8s_discovery.py +360 -0
  182. mayhem_cli-0.8.0/tests/unit/test_k8s_manifest.py +512 -0
  183. mayhem_cli-0.8.0/tests/unit/test_k8s_plan1.py +285 -0
  184. mayhem_cli-0.8.0/tests/unit/test_k8s_plan2.py +210 -0
  185. mayhem_cli-0.8.0/tests/unit/test_k8s_selection.py +155 -0
  186. mayhem_cli-0.8.0/tests/unit/test_kplan1_targets.py +453 -0
  187. mayhem_cli-0.8.0/tests/unit/test_kplan2_topology.py +89 -0
  188. mayhem_cli-0.8.0/tests/unit/test_kplan3_resolver.py +203 -0
  189. mayhem_cli-0.8.0/tests/unit/test_kplan3_runtime.py +644 -0
  190. mayhem_cli-0.8.0/tests/unit/test_kplan5_runtime.py +508 -0
  191. mayhem_cli-0.8.0/tests/unit/test_kplan6_runtime.py +1205 -0
  192. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_lifecycle_run_liveness.py +66 -0
  193. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_m7_k8s.py +50 -6
  194. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_maniac.py +1 -0
  195. mayhem_cli-0.8.0/tests/unit/test_plan_diff.py +55 -0
  196. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_planner.py +24 -0
  197. mayhem_cli-0.8.0/tests/unit/test_policy_explain.py +243 -0
  198. mayhem_cli-0.8.0/tests/unit/test_preflight.py +154 -0
  199. mayhem_cli-0.8.0/tests/unit/test_provider_loader.py +222 -0
  200. mayhem_cli-0.8.0/tests/unit/test_provider_registry.py +136 -0
  201. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_ranking.py +34 -3
  202. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_recovery.py +104 -0
  203. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_report.py +133 -1
  204. mayhem_cli-0.8.0/tests/unit/test_runtime_execution_matrix.py +2311 -0
  205. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_safety.py +18 -4
  206. mayhem_cli-0.8.0/tests/unit/test_selection_modes.py +352 -0
  207. mayhem_cli-0.8.0/tests/unit/test_target_profiles.py +141 -0
  208. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_topology_providers.py +6 -1
  209. mayhem_cli-0.8.0/tests/unit/test_workflow_groups.py +47 -0
  210. mayhem_cli-0.8.0/uv.lock +1619 -0
  211. mayhem_cli-0.6.2/PKG-INFO +0 -555
  212. mayhem_cli-0.6.2/README.md +0 -541
  213. mayhem_cli-0.6.2/docs/config.md +0 -285
  214. mayhem_cli-0.6.2/docs/features.md +0 -408
  215. mayhem_cli-0.6.2/docs/re-design.md +0 -1405
  216. mayhem_cli-0.6.2/examples/k8s/README.md +0 -32
  217. mayhem_cli-0.6.2/examples/k8s/mayhem.yaml +0 -76
  218. mayhem_cli-0.6.2/src/mayhem/agents/executors.py +0 -430
  219. mayhem_cli-0.6.2/src/mayhem/cli/app.py +0 -175
  220. mayhem_cli-0.6.2/src/mayhem/cli/config_cmd.py +0 -47
  221. mayhem_cli-0.6.2/src/mayhem/cli/coverage_cmd.py +0 -325
  222. mayhem_cli-0.6.2/src/mayhem/cli/lifecycle.py +0 -885
  223. mayhem_cli-0.6.2/src/mayhem/cli/next_cmd.py +0 -216
  224. mayhem_cli-0.6.2/src/mayhem/cli/toolkit.py +0 -41
  225. mayhem_cli-0.6.2/src/mayhem/cli/topology.py +0 -127
  226. mayhem_cli-0.6.2/src/mayhem/controller/safety.py +0 -392
  227. mayhem_cli-0.6.2/src/mayhem/domain/catalog.py +0 -727
  228. mayhem_cli-0.6.2/src/mayhem/domain/coverage.py +0 -204
  229. mayhem_cli-0.6.2/src/mayhem/infra/report.py +0 -227
  230. mayhem_cli-0.6.2/src/mayhem/topology/providers/adapter_registry.py +0 -60
  231. mayhem_cli-0.6.2/tests/unit/test_cli_contract.py +0 -113
  232. mayhem_cli-0.6.2/tests/unit/test_command_inventory.py +0 -117
  233. mayhem_cli-0.6.2/uv.lock +0 -819
  234. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/.gitignore +0 -0
  235. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/CHANGELOG.md +0 -0
  236. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/cliff.toml +0 -0
  237. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/docs/grounding-rules.md +0 -0
  238. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/k8s/kubernetes.yaml +0 -0
  239. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/data/hello.txt +0 -0
  240. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/data/index.html +0 -0
  241. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/docker-compose.mayhem.yml +0 -0
  242. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/docker-compose.yml +0 -0
  243. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/mayhem.yaml +0 -0
  244. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/examples/testCase/nginx.conf +0 -0
  245. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agent/__init__.py +0 -0
  246. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agent/cli.py +0 -0
  247. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/__init__.py +0 -0
  248. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/capabilities.py +0 -0
  249. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/probes.py +0 -0
  250. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/protocol.py +0 -0
  251. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/server.py +0 -0
  252. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/sinks.py +0 -0
  253. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/transports.py +0 -0
  254. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/agents/watchdog.py +0 -0
  255. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/__init__.py +0 -0
  256. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/dependency.py +0 -0
  257. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/exit_codes.py +0 -0
  258. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/cli/style.py +0 -0
  259. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/__init__.py +0 -0
  260. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/observability_collector.py +0 -0
  261. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/observations.py +0 -0
  262. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/resilience_report.py +0 -0
  263. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/controller/resource_manager.py +0 -0
  264. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/__init__.py +0 -0
  265. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/cancellation.py +0 -0
  266. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/candidates.py +0 -0
  267. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/capabilities.py +0 -0
  268. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/cell_rules.py +0 -0
  269. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/checks.py +0 -0
  270. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/events.py +0 -0
  271. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/execution_context.py +0 -0
  272. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/execution_loci.py +0 -0
  273. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/load_strategy.py +0 -0
  274. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/observability.py +0 -0
  275. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/outcomes.py +0 -0
  276. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/remote_agent_interface.py +0 -0
  277. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/resources.py +0 -0
  278. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/risks.py +0 -0
  279. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/run_outcome.py +0 -0
  280. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/domain/success.py +0 -0
  281. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/__init__.py +0 -0
  282. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/candidate_gates.py +0 -0
  283. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/candidate_generator.py +0 -0
  284. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/kpi.py +0 -0
  285. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/maniac.py +0 -0
  286. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/migrator.py +0 -0
  287. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/infra/store.py +0 -0
  288. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/py.typed +0 -0
  289. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/spec.py +0 -0
  290. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/__init__.py +0 -0
  291. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/fingerprint.py +0 -0
  292. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/hashing.py +0 -0
  293. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/manifests/docker.yaml +0 -0
  294. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/manifests/podman.yaml +0 -0
  295. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/manifests/stress-ng.yaml +0 -0
  296. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/manifests/tc-netem.yaml +0 -0
  297. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/manifests/toxiproxy.yaml +0 -0
  298. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/registry.py +0 -0
  299. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/toolkit/tool_runner.py +0 -0
  300. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/__init__.py +0 -0
  301. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/__init__.py +0 -0
  302. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/base.py +0 -0
  303. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/compose.py +0 -0
  304. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/docker_runtime.py +0 -0
  305. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/providers/podman_adapter.py +0 -0
  306. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/resolve.py +0 -0
  307. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/src/mayhem/topology/service.py +0 -0
  308. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/conftest.py +0 -0
  309. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/e2e/__init__.py +0 -0
  310. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/integration/test_agent_serve.py +0 -0
  311. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/integration/test_agent_watchdog_e2e.py +0 -0
  312. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/integration/test_m5_e2e.py +0 -0
  313. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/integration/test_store.py +0 -0
  314. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_agent_capabilities.py +0 -0
  315. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_agent_protocol.py +0 -0
  316. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_agents.py +0 -0
  317. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_campaign_run.py +0 -0
  318. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cancellation.py +0 -0
  319. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_candidates.py +0 -0
  320. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_capability_matrix.py +0 -0
  321. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_capability_registry.py +0 -0
  322. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cell_rules.py +0 -0
  323. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cell_runner.py +0 -0
  324. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_check_spec.py +0 -0
  325. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_cli_campaign.py +0 -0
  326. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_compensation.py +0 -0
  327. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_coverage_repository.py +0 -0
  328. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_domain_properties.py +0 -0
  329. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_drill_spec.py +0 -0
  330. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_execution_context.py +0 -0
  331. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_executor.py +0 -0
  332. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_executor_drill.py +0 -0
  333. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_faults.py +0 -0
  334. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_fingerprint.py +0 -0
  335. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_fork_atomicity.py +0 -0
  336. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_kpi.py +0 -0
  337. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_lease_repository.py +0 -0
  338. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_leases.py +0 -0
  339. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_load_strategy.py +0 -0
  340. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_m12_step1_catalog.py +0 -0
  341. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_m8_operations.py +0 -0
  342. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_m9_catalog.py +0 -0
  343. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_migrations.py +0 -0
  344. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_network_path_model.py +0 -0
  345. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_observability.py +0 -0
  346. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_observations.py +0 -0
  347. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_resilience_report.py +0 -0
  348. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_resolve.py +0 -0
  349. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_resource_conflict_exec.py +0 -0
  350. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_resource_manager.py +0 -0
  351. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_resources.py +0 -0
  352. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_risks.py +0 -0
  353. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_run_outcome.py +0 -0
  354. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_runtime_adapter.py +0 -0
  355. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_success.py +0 -0
  356. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_three_locus.py +0 -0
  357. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_tool_runner.py +0 -0
  358. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_topology.py +0 -0
  359. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_topology_ctr.py +0 -0
  360. {mayhem_cli-0.6.2 → mayhem_cli-0.8.0}/tests/unit/test_watchdog.py +0 -0
@@ -25,14 +25,14 @@ jobs:
25
25
  run: python -m pip install --quiet uv
26
26
  - name: Sync dev dependencies
27
27
  run: uv sync --group dev
28
- - name: Run tests
29
- run: uv run pytest tests/unit tests/integration
28
+ - name: Run unit tests
29
+ run: uv run pytest tests/unit
30
+ - name: Run integration tests
31
+ run: uv run pytest tests/integration
30
32
  # NOTE: `ruff check src/` is NOT gated here — the repository's committed
31
33
  # ruff config currently reports 30-49 pre-existing violations under every
32
34
  # ruff generation (0.8-0.16); the project has no lint-green baseline in
33
35
  # its history. Land a lint-cleanup first, then re-add `ruff check src/`.
34
- - name: Architectural contracts
35
- run: uv run lint-imports
36
36
 
37
37
  build-and-publish:
38
38
  name: Build and publish to PyPI
@@ -9,9 +9,10 @@ set shell := ["bash", "-euo", "pipefail", "-c"]
9
9
 
10
10
  _testcase := "examples/testCase"
11
11
  _compose := _testcase / "docker-compose.yml"
12
- _config := _testcase / "mayhem.yml"
12
+ _config := _testcase / "mayhem.yaml"
13
13
  _spec := _testcase / "mayhem.yaml"
14
14
  _db := ".mayhem/e2e.db"
15
+ _workers := "5"
15
16
 
16
17
  # ── setup ────────────────────────────────────────────────────────────────────
17
18
 
@@ -72,13 +73,6 @@ validate: setup
72
73
  mayhem --db {{ _db }} validate {{ _spec }} --compose {{ _compose }}
73
74
  @echo "✓ validate"
74
75
 
75
- # Validate with explicit process topology (no compose auto-detect)
76
- validate-process:
77
- @echo "=== validate --process ==="
78
- mayhem validate {{ _spec }} \
79
- --process "download-1=10001" --process "download-2=10002"
80
- @echo "✓ validate --process"
81
-
82
76
  # Plan the experiment
83
77
  plan:
84
78
  @echo "=== plan ==="
@@ -108,16 +102,21 @@ history:
108
102
  echo "✓ history"; \
109
103
  fi
110
104
 
111
- # Recovery sweep (orphaned fault leases)
112
- recover: setup
105
+ # Recovery sweep (orphaned fault leases for the most recent run)
106
+ recover:
113
107
  @echo "=== recover ==="
114
- mayhem --db {{ _db }} recover
108
+ @run_id=$$(sqlite3 {{ _db }} "SELECT id FROM runs ORDER BY rowid DESC LIMIT 1" 2>/dev/null || echo ""); \
109
+ if [ -z "$$run_id" ]; then \
110
+ echo "⚠ no runs in DB — skipping recover"; \
111
+ else \
112
+ mayhem --db {{ _db }} recover "$$run_id"; \
113
+ fi
115
114
  @echo "✓ recover"
116
115
 
117
116
  # Janitor sweep (stale runs / resources)
118
117
  janitor: setup
119
118
  @echo "=== janitor ==="
120
- mayhem --db {{ _db }} janitor sweep
119
+ mayhem --db {{ _db }} janitor
121
120
  @echo "✓ janitor"
122
121
 
123
122
  # ── campaign CRUD ────────────────────────────────────────────────────────────
@@ -125,14 +124,16 @@ janitor: setup
125
124
  # Create, list, show, start, abort, delete a campaign
126
125
  campaign: setup
127
126
  @echo "=== campaign ==="
128
- mayhem --db {{ _db }} campaign create --name "e2e-campaign" --hypothesis "stack survives chaos"
127
+ mayhem --db {{ _db }} campaign create "e2e-campaign" --hypothesis "stack survives chaos"
129
128
  mayhem --db {{ _db }} campaign list
130
- @cid=$$(sqlite3 {{ _db }} "SELECT id FROM campaigns ORDER BY rowid DESC LIMIT 1"); \
129
+ @cid=$$(sqlite3 {{ _db }} "SELECT id FROM campaigns WHERE name = 'e2e-campaign' ORDER BY rowid DESC LIMIT 1"); \
131
130
  mayhem --db {{ _db }} campaign show "$$cid"; \
132
131
  mayhem --db {{ _db }} campaign status "$$cid"; \
133
132
  mayhem --db {{ _db }} campaign start "$$cid" || true; \
134
- mayhem --db {{ _db }} campaign abort "$$cid" || true; \
135
- mayhem --db {{ _db }} campaign delete "$$cid"
133
+ mayhem --db {{ _db }} campaign abort "$$cid" || true
134
+ mayhem --db {{ _db }} campaign create "e2e-delete-campaign"
135
+ @delete_cid=$$(sqlite3 {{ _db }} "SELECT id FROM campaigns WHERE name = 'e2e-delete-campaign' ORDER BY rowid DESC LIMIT 1"); \
136
+ mayhem --db {{ _db }} campaign delete --yes "$$delete_cid"
136
137
  @echo "✓ campaign"
137
138
 
138
139
  # ── full round-trip ─────────────────────────────────────────────────────────
@@ -145,8 +146,8 @@ full: setup
145
146
  mayhem --db {{ _db }} run {{ _spec }} --compose {{ _compose }}
146
147
  mayhem --db {{ _db }} status
147
148
  @run_id=$$(sqlite3 {{ _db }} "SELECT id FROM runs ORDER BY rowid DESC LIMIT 1"); \
148
- mayhem --db {{ _db }} history "$$run_id"
149
- mayhem --db {{ _db }} recover
149
+ mayhem --db {{ _db }} history "$$run_id"; \
150
+ mayhem --db {{ _db }} recover "$$run_id"
150
151
  @echo "✓ full round-trip"
151
152
 
152
153
  # ── stack management ─────────────────────────────────────────────────────────
@@ -169,7 +170,7 @@ stack-down:
169
170
  # Run unit tests
170
171
  test-unit:
171
172
  @echo "=== unit tests ==="
172
- python3 -m pytest tests/unit/ -v --tb=short
173
+ python3 -m pytest tests/unit/ -n {{ _workers }} --dist loadfile -v --tb=short
173
174
  @echo "✓ unit tests"
174
175
 
175
176
  # Run e2e tests (in-process, no containers needed)
@@ -0,0 +1,404 @@
1
+ Metadata-Version: 2.5
2
+ Name: mayhem-cli
3
+ Version: 0.8.0
4
+ Summary: General-purpose chaos engineering and resilience-testing framework: a chaos experiment orchestration engine.
5
+ Author: Mayhem Engineering
6
+ License: Proprietary
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: click>=8.1
9
+ Requires-Dist: kubernetes>=31
10
+ Requires-Dist: pydantic>=2.9
11
+ Requires-Dist: pyyaml>=6.0
12
+ Requires-Dist: structlog>=24.1
13
+ Requires-Dist: typer>=0.12
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Mayhem
17
+
18
+ **Chaos engineering for Docker and Podman, with separately scoped Kubernetes
19
+ planning and execution seams.** The documented quickstart uses a compose
20
+ blueprint. Mayhem compiles a declarative `kind: drill` document into a frozen,
21
+ safety-gated plan, injects supported faults through a capability-aware toolkit,
22
+ and derives the run verdict from recorded observations.
23
+
24
+ Everything lands in SQLite — steps, probes, criteria evaluations, decisions —
25
+ so nothing is ever "trust me, it worked."
26
+
27
+ Kubernetes source support is layered and must not be collapsed into one
28
+ "supported" claim: manifest planning, planner support, executor support, and
29
+ live resolution are separate states. The legacy `KubernetesAdapter` remains
30
+ unavailable, and catalog-only faults are not executable merely because they are
31
+ defined. See the [Kubernetes status](#kubernetes-status) section and the
32
+ [documentation authority index](docs/README.md).
33
+
34
+ ```
35
+ compose blueprint ─▶ topology graph ─▶ compile drill spec ─▶ frozen plan
36
+ │
37
+ verdict ◀── machine criteria ◀── inject → observe → recover
38
+ │
39
+ SQLite evidence + decision trace
40
+ ```
41
+
42
+ - [Quickstart](#quickstart)
43
+ - [A Run in One Screen](#a-run-in-one-screen)
44
+ - [Authoring a Drill](#authoring-a-drill)
45
+ - [Configuration](#configuration)
46
+ - [CLI Reference](#cli-reference)
47
+ - [Campaigns](#campaigns)
48
+ - [Safety Model](#safety-model)
49
+ - [Exit Codes](#exit-codes)
50
+ - [Architecture](#architecture)
51
+ - [Status](#status)
52
+ - [Development](#development)
53
+
54
+ ---
55
+
56
+ ## Quickstart
57
+
58
+ **Prerequisites**
59
+
60
+ - Python 3.12+
61
+ - Docker with Compose v2, or Podman selected with `--podman`
62
+
63
+ The Kubernetes paths have additional SDK, client, cluster, and capability
64
+ requirements. The checked-in documentation does not certify any live cluster.
65
+
66
+ **Install**
67
+
68
+ ```bash
69
+ pip install mayhem-cli # one bundle; console command is `mayhem`
70
+ ```
71
+
72
+ **Run the bundled example**
73
+
74
+ A complete, self-contained six-service stack lives in
75
+ [`examples/testCase/`](examples/testCase/).
76
+
77
+ ```bash
78
+ cd examples/testCase
79
+ docker compose up -d # 0. bring the stack up
80
+ mayhem discover topology --compose docker-compose.yml # 1. blueprint → live graph
81
+ mayhem prepare validate mayhem.yaml --compose docker-compose.yml # 2. compile + safety gates (injects nothing)
82
+ mayhem run mayhem.yaml --compose docker-compose.yml # 3. inject → observe → recover → verdict
83
+ ```
84
+
85
+ Omit `--compose` and Mayhem auto-detects `docker-compose.yml` (or
86
+ `compose.yml`) in the current directory.
87
+
88
+ `validate` and `plan` compile from the compose blueprint and do not inject a
89
+ fault. Topology construction may still inspect an available container runtime
90
+ for current-state data. `run` applies its impact gate and records the actual
91
+ execution outcome.
92
+
93
+ The bundled spec exercises the compose-supported fault families used by the
94
+ example stack. The [`examples/k8s`](examples/k8s) directory is a separate
95
+ manifest-backed planning example. Its presence does not prove live-cluster
96
+ execution, and the current catalog is larger than the original nine-fault
97
+ example. See [Targets (cross-runtime)](docs/drill-spec.md#targets-cross-runtime)
98
+ for the authored target syntax.
99
+
100
+ ---
101
+
102
+ ## A Run in One Screen
103
+
104
+ A clean run needs no interpretation — the verdict is one line away.
105
+
106
+ ```
107
+ $ mayhem run mayhem.yaml --compose docker-compose.yml
108
+
109
+ # Run r-process-drill-8f2a1c
110
+ **status**: completed
111
+ **verdict**: pass
112
+ **success criteria**: ALL PASS
113
+ - [PASS] status:api-up.status PASS (expected 200, got 200)
114
+ - [PASS] latency:api-up.latency_ms PASS (31.2 <= 500.0)
115
+ **observations**: 2/2 sources collected
116
+ **decisions**: 5 governing decision revisions (snapshot in the run row)
117
+ **wall**: 32.4s
118
+
119
+ run r-process-drill-8f2a1c — inspect with `mayhem inspect history r-process-drill-8f2a1c`
120
+ ```
121
+
122
+ Reading the transcript, top to bottom:
123
+
124
+ 1. **Status** — the run's machine state: `completed` (or `failed`/`aborted`
125
+ with a non-zero exit and dirty-lease warnings).
126
+ 2. **Verdict** — `pass`/`fail` derived from the success criteria you declared
127
+ in the spec; `undecided` when a run aborts or the spec has no success block.
128
+ 3. **Success criteria** — every criterion evaluated against real observations,
129
+ one line each, so a failure tells you exactly what drifted.
130
+ 4. **Observations** — how many configured evidence sources actually delivered
131
+ data (probes, logs, metrics …).
132
+ 5. **Decisions** — the governing decision revisions that shaped this run; the
133
+ decision trace is queryable afterward via `mayhem inspect history`.
134
+ 6. **Copy-paste handle** — the run id for the follow-up commands below.
135
+
136
+ From there: `mayhem inspect runs` lists recent runs, `mayhem inspect runs --run <run-id>`
137
+ shows full recorded metadata, and `mayhem inspect history <run-id>` replays the
138
+ complete event journal (every step, probe sample, and lease for that run).
139
+ Add `--debug` to `mayhem run` to stream each step live as it happens
140
+ (`[ok] injected proc.pause 10s into testcase-api`,
141
+ `[ok] recovered ... (compensation ok)`).
142
+
143
+ ---
144
+
145
+ ## Authoring a Drill
146
+
147
+ A drill is one `kind: drill` YAML file — the complete DSL reference lives in
148
+ [`docs/drill-spec.md`](docs/drill-spec.md). The shape:
149
+
150
+ ```yaml
151
+ apiVersion: "mayhem/v1"
152
+ kind: drill
153
+ name: checkout-recovery
154
+ hypothesis: "checkout stays available while cart writes are throttled"
155
+
156
+ config:
157
+ risk_ceiling: high
158
+ max_faults: 1
159
+ timeout: 30m
160
+ recovery: true
161
+
162
+ containers:
163
+ cart-api:
164
+ faults:
165
+ - fault: net.latency
166
+ duration: 10s
167
+ params:
168
+ delay_ms: 300
169
+ jitter_ms: 25
170
+
171
+ execution:
172
+ - sequential: [cart-api]
173
+ - check:
174
+ - http: http://cart-api:8080/_health
175
+ expect:
176
+ status: 200
177
+ ```
178
+
179
+ Validate with `mayhem prepare validate mayhem.yaml`; unknown parameters, out-of-range
180
+ durations, untargetable node kinds, and capability gaps are all compile-time
181
+ errors — before anything is injected.
182
+
183
+ Faults are drawn from the catalog (net.latency, proc.kill, net.packet_loss,
184
+ TLS failure, container pause, HTTP error injection, dependency and database
185
+ faults, k8s.pod_kill, k8s.node_drain, …). The full per-fault reference —
186
+ every id, its capabilities, risk level, and compensation contract — is in
187
+ [`docs/drill-spec.md`](docs/drill-spec.md#fault-catalog).
188
+
189
+ The `containers:` block above is the docker-family authoring shape. To fault a
190
+ Kubernetes workload or node — or mix runtimes in one spec — use the
191
+ cross-runtime `targets:` block instead (exactly one of `containers:` /
192
+ `targets:` defines a spec); see
193
+ [Targets (cross-runtime)](docs/drill-spec.md#targets-cross-runtime).
194
+
195
+ ---
196
+
197
+ ## Configuration
198
+
199
+ Runtime policies live in `mayhem.yaml` — the *configuration* file, distinct
200
+ from a `kind: drill` spec — auto-detected in the cwd or given with `--config`.
201
+ The effective view is one command away: `mayhem prepare config show` prints the
202
+ resolved configuration and provenance; `mayhem prepare config validate` refuses
203
+ unknown keys, a missing or wrong `apiVersion`, and out-of-range sections before
204
+ anything runs.
205
+
206
+ ```yaml
207
+ apiVersion: mayhem/v1 # required; anything else is rejected
208
+ policy:
209
+ allow_faults: null # null = whole catalog; set to restrict
210
+ deny_faults: [] # fault ids never injectable
211
+ risk_ceiling: null # tightened by the drill ceiling at plan time
212
+ allow_critical: false # config-side half of the critical opt-in
213
+ critical_fault_acks: [] # per-fault acks; critical faults need allow_critical + ack + --allow-critical
214
+ blast_radius:
215
+ max_services_pct: 50.0
216
+ max_hosts: 2
217
+ max_concurrent_faults: 3
218
+ max_duration_per_fault_s: 300.0
219
+ forbidden_fault_pairs: [] # pairs such as [net.packet_loss, net.bandwidth]
220
+ storage:
221
+ path: mayhem.db
222
+ artifacts_dir: .mayhem/artifacts
223
+ toolkit:
224
+ binaries: {} # pin a named tool's binary
225
+ runtime: docker # docker | podman | kubernetes
226
+ target:
227
+ containers: [] # explicit discovery targets without compose
228
+ kubernetes:
229
+ context: null # kubeconfig context
230
+ namespace: null # null = no namespace filter
231
+ recovery_grace: 300.0
232
+ log_level: INFO # DEBUG | INFO | WARNING | ERROR
233
+ maniac:
234
+ level: 2
235
+ run_level: 10
236
+ seed: null
237
+ ```
238
+
239
+ Layering, in increasing precedence: **built-in defaults → selected YAML →
240
+ `mayhem.{profile}.yaml` → allowlisted environment variables → programmatic
241
+ CLI overrides**. Profile overlays are separate files selected with `--profile
242
+ NAME`; there is no `profiles:` key inside the base file. The environment layer
243
+ only honours `MAYHEM_STORAGE_PATH`, `MAYHEM_ARTIFACTS_DIR`, and
244
+ `MAYHEM_LOG_LEVEL`. The current CLI uses `--config` and `--profile` to select
245
+ layers; it does not expose a generic flag that maps arbitrary fields into
246
+ configuration.
247
+
248
+ Drill-level `config.risk_ceiling` composes with the policy ceiling and can
249
+ only tighten it.
250
+
251
+ The full configuration reference is in
252
+ [`docs/config.md`](docs/config.md).
253
+
254
+ ---
255
+
256
+ ## CLI surface
257
+
258
+ The active CLI is workflow-oriented: `discover`, `prepare`, `experiment`, `run`, `inspect`, `recover`, and `extend`. Guided `init` and `doctor` are active, and all legacy root commands and aliases have been removed. Exit codes, machine-readable fields, and database migrations remain stable.
259
+
260
+ See [`docs/product/cli-product-direction.md`](docs/product/cli-product-direction.md), [`docs/product/command-architecture.md`](docs/product/command-architecture.md), and [`docs/new-plan/README.md`](docs/new-plan/README.md).
261
+
262
+ Root options precede the command. Unique prefixes work at the root and in the workflow groups.
263
+
264
+ | Command group | Purpose |
265
+ |---------------|---------|
266
+ | `mayhem discover` | Discover topology, engines, faults, and capabilities. |
267
+ | `mayhem prepare` | Validate configuration, prepare dependencies, and compile plans. |
268
+ | `mayhem experiment` | Show, validate, and explore authored experiments. |
269
+ | `mayhem run`, `mayhem maniac` | Execute authored or randomized drills. |
270
+ | `mayhem inspect` | Inspect runs, history, coverage, next actions, leases, and diagnostics. |
271
+ | `mayhem recover`, `mayhem janitor` | Recover runs and clean leases. |
272
+ | `mayhem extend` | Inspect and extend faults, capabilities, dependencies, and providers. |
273
+ | `mayhem campaign`, `mayhem commands`, `mayhem init`, `mayhem doctor`, `mayhem verify` | Manage campaigns, inspect the command map, onboard, diagnose, and verify evidence. |
274
+
275
+ Use each command's current `--help` output for accepted arguments. See the complete [`docs/reference/cli.md`](docs/reference/cli.md) for options and workflow examples.
276
+
277
+ ---
278
+
279
+ ## Campaigns
280
+
281
+ A campaign groups authored drill-spec paths and runs them sequentially.
282
+
283
+ ```bash
284
+ mayhem campaign create black-friday \
285
+ --description "BFCM chaos" --hypothesis "checkout survives every single-fault failure"
286
+ mayhem campaign add-experiment black-friday mayhem.yaml
287
+ mayhem campaign add-experiment black-friday checkout-recovery.yaml
288
+ mayhem campaign start black-friday
289
+ mayhem campaign run black-friday --compose docker-compose.yml
290
+ ```
291
+
292
+ The current CLI creates campaigns in `draft`, `start` moves a draft to
293
+ `running`, `run` executes the stored spec paths, and `archive` or `abort` sets
294
+ the corresponding terminal status. The current command surface does not expose
295
+ campaign scheduling, pause, resume, priority-order, or policy/window editing
296
+ options. See the [campaign reference](docs/reference/cli.md#campaign-commands).
297
+
298
+ ---
299
+
300
+ ## Safety Model
301
+
302
+ - **Risk ceilings.** Every catalog fault carries a risk level; injection is
303
+ refused when either the policy or the drill ceiling is exceeded.
304
+ `critical`-risk faults (e.g. `k8s.node_drain`) need a **triple opt-in**:
305
+ `policy.allow_critical: true`, a per-fault ack in `policy.critical_fault_acks`,
306
+ and the `--allow-critical` CLI flag.
307
+ - **Concurrency budget.** `max_faults` caps simultaneously-injected faults;
308
+ a wider `parallel:` step queues into rounds.
309
+ - **Duration caps.** Per-fault `duration` beyond the catalog maximum is a
310
+ compile error.
311
+ - **Capability gating.** Faults declare the capabilities they need
312
+ (docker engine, kubernetes_engine, net_admin, process control, …); the plan
313
+ is proven against the live graph by the impact gate before run — never
314
+ assumed.
315
+ - **Compensation contracts.** Reversible faults run their declared inverse;
316
+ irreversible ones are followed by workload reconciliation. A failed round
317
+ aborts-and-recovers its own faults first, then propagates.
318
+ - **Lease hygiene.** Fault rounds hold leases with a TTL; `mayhem janitor`
319
+ sweeps orphaned leases and expires pending runs, `mayhem recover` repairs a
320
+ run's orphans on demand.
321
+
322
+ ---
323
+
324
+ ## Exit Codes
325
+
326
+ The stable identifiers and numeric values are defined in
327
+ [`src/mayhem/cli/exit_codes.py`](src/mayhem/cli/exit_codes.py) and documented in
328
+ [`docs/reference/cli.md`](docs/reference/cli.md#exit-codes). The deterministic
329
+ documentation test rejects identifiers that are not declared in source.
330
+
331
+ ---
332
+
333
+ ## Architecture
334
+
335
+ The pipeline is staged so everything expensive is done up front and execution
336
+ is as small as possible:
337
+
338
+ 1. **Discover** — compose discovery builds a Docker/Podman graph. Kubernetes
339
+ has separate live-discovery and offline-manifest providers; the manifest
340
+ provider creates logical placeholders, not live pod selections.
341
+ 2. **Prepare** — `mayhem prepare config` layering (defaults → selected YAML → separate
342
+ profile overlay → allowlisted environment values → programmatic overrides),
343
+ plus topology, drift detection, and target revalidation.
344
+ 3. **Compile & plan** — the drill spec becomes a frozen `ExecutionPlan` with
345
+ step sequences, per-fault compensations, success criteria, and observability
346
+ sources; fault, target, capability, and duration inputs are validated
347
+ against the current models.
348
+ 4. **Execute** — supported runtimes execute inject → hold → compensate rounds
349
+ and record evidence. Kubernetes planner/executor presence does not by itself
350
+ establish a reachable cluster or an available capability.
351
+ 5. **Recover & report** — the janitor sweeps orphaned leases; `status`,
352
+ `history`, and run summaries replay recorded evidence.
353
+
354
+ **Documentation**
355
+
356
+ | Document | Contents |
357
+ |----------|----------|
358
+ | [`docs/README.md`](docs/README.md) | Documentation authority, classifications, source-of-truth map, and Kubernetes status vocabulary. |
359
+ | [`docs/drill-spec.md`](docs/drill-spec.md) | Drill DSL reference. |
360
+ | [`docs/config.md`](docs/config.md) | Current layered configuration contract. |
361
+ | [`docs/reference/cli.md`](docs/reference/cli.md) | Current commands, options, and stable exit codes. |
362
+ | [`docs/compensation.md`](docs/compensation.md) | Compensation lifecycle and verification contracts. |
363
+
364
+ ---
365
+
366
+ ## Status
367
+
368
+ | Area | Status |
369
+ |------|--------|
370
+ | Compose-oriented Docker/Podman workflow | Documented user path |
371
+ | Layered configuration, drill planning, SQLite evidence, CLI exit codes | Current checked-in references |
372
+ | Kubernetes manifest topology | Supported as an offline planning input; blueprint pods are placeholders |
373
+ | Kubernetes planner | Supports normalized `targets:` scopes and frozen-plan metadata |
374
+ | Kubernetes executor/resolver seams | Present in source and unit-tested with fakes; availability is runtime/capability dependent |
375
+ | Legacy `KubernetesAdapter` | Compatibility seam only; reports unavailable |
376
+ | Live Kubernetes cluster acceptance | Not claimed by repository documentation |
377
+ | Catalog-only Kubernetes faults | `k8s.image_pull_slow`; excluded from the available-fault register and refused before mutation |
378
+ | Web UI / REST API | Planned |
379
+
380
+ ### Kubernetes status
381
+
382
+ The [examples/k8s README](examples/k8s/README.md) and
383
+ [documentation authority index](docs/README.md#kubernetes-status-vocabulary)
384
+ explain the separate Kubernetes states. Historical discovery reports and the
385
+ dated [grounding log](docs/grounding-log.md) are retained for traceability and
386
+ must not be treated as live-cluster evidence.
387
+
388
+ ---
389
+
390
+ ## Development
391
+
392
+ ```bash
393
+ # Clone, then sync the dev dependency group (requires https://docs.astral.sh/uv/):
394
+ uv sync --group dev
395
+
396
+ # Run all tests
397
+ uv run pytest
398
+
399
+ # Lint
400
+ uv run ruff check src/
401
+
402
+ # Type check (strict is configured per module)
403
+ uv run mypy
404
+ ```