pangea 0.0.57 → 0.1.0

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 (436) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/pangea-cloud-resource-creation/SKILL.md +169 -0
  3. data/.claude/skills/pangea-cloud-resource-creation/references/hetzner-volume-example.md +133 -0
  4. data/.claude/skills/pangea-cloud-resource-creation/references/patterns-antipatterns.md +149 -0
  5. data/.claude/skills/pangea-cloud-resource-creation/references/resource-templates.md +288 -0
  6. data/.claude/skills/pangea-cloud-resource-creation/references/tracker-cli.md +77 -0
  7. data/.claude/skills/pangea-cloud-resource-creation/references/type-system.md +105 -0
  8. data/.claude/skills/pangea-infrastructure/SKILL.md +300 -0
  9. data/.claude/skills/pangea-infrastructure/references/kubernetes-integration.md +149 -0
  10. data/.claude/skills/pangea-infrastructure/references/resource-patterns.md +206 -0
  11. data/.claude/skills/pangea-infrastructure/references/troubleshooting.md +86 -0
  12. data/.claude/skills/pangea-infrastructure/references/workflow-examples.md +98 -0
  13. data/.claude/skills/pangea-refactoring/SKILL.md +478 -0
  14. data/.claude/skills/pangea-resource-testing/SKILL.md +256 -0
  15. data/.claude/skills/pangea-rspec-resource-testing/SKILL.md +258 -0
  16. data/.claude/skills/pangea-rspec-resource-testing/references/cloudflare-zone-example.md +57 -0
  17. data/.claude/skills/pangea-rspec-resource-testing/references/common-patterns.md +109 -0
  18. data/.claude/skills/pangea-rspec-resource-testing/references/debugging.md +63 -0
  19. data/.claude/skills/pangea-rspec-resource-testing/references/integration-tests.md +55 -0
  20. data/.claude/skills/pangea-rspec-resource-testing/references/synthesis-tests.md +169 -0
  21. data/.claude/skills/pangea-rspec-resource-testing/references/troubleshooting.md +129 -0
  22. data/.claude/skills/pangea-rspec-resource-testing/references/type-validation-tests.md +92 -0
  23. data/.github/ISSUE_TEMPLATE/bug_report.yml +114 -0
  24. data/.github/ISSUE_TEMPLATE/feature_request.yml +67 -0
  25. data/.github/ISSUE_TEMPLATE/question.yml +44 -0
  26. data/.github/PULL_REQUEST_TEMPLATE.md +69 -0
  27. data/.github/workflows/ci.yml +80 -0
  28. data/.github/workflows/release.yml +43 -0
  29. data/.gitignore +89 -1
  30. data/.rspec_status +278 -0
  31. data/AGENT_GUIDE.md +349 -0
  32. data/CHANGELOG.md +67 -0
  33. data/CONTRIBUTING.md +143 -0
  34. data/Dockerfile +20 -4
  35. data/EXAMPLES.md +376 -0
  36. data/Gemfile +8 -0
  37. data/Gemfile.lock +252 -70
  38. data/LICENSE +1 -1
  39. data/README.md +217 -40
  40. data/README_backend_configuration.md +181 -0
  41. data/Rakefile +146 -23
  42. data/SECURITY.md +90 -0
  43. data/Steepfile +33 -0
  44. data/bin/generate-hetzner-resource +204 -0
  45. data/bin/hetzner-tracker +280 -0
  46. data/bin/pangea +15 -2
  47. data/bin/pangea-compiler +15 -0
  48. data/bin/pangea-compiler-server +133 -0
  49. data/docker-compose.test.yml +31 -0
  50. data/docs/KUBERNETES_OPERATOR_PLAN.md +2626 -0
  51. data/docs/RESOURCES.md +456 -0
  52. data/exe/pangea +37 -0
  53. data/flake.lock +751 -9
  54. data/flake.nix +346 -6
  55. data/gemset.nix +620 -103
  56. data/guides/README.md +157 -0
  57. data/guides/advanced-patterns.md +1196 -0
  58. data/guides/cicd-integration.md +1047 -0
  59. data/guides/getting-started.md +399 -0
  60. data/guides/migration-from-terraform.md +924 -0
  61. data/guides/multi-environment-management.md +769 -0
  62. data/guides/template-isolation.md +673 -0
  63. data/guides/type-safe-infrastructure.md +695 -0
  64. data/lib/pangea/agent/analysis.rb +128 -0
  65. data/lib/pangea/agent/compilation.rb +62 -0
  66. data/lib/pangea/agent/helpers.rb +29 -0
  67. data/lib/pangea/agent/listing.rb +108 -0
  68. data/lib/pangea/agent.rb +30 -0
  69. data/lib/pangea/architecture_registry.rb +94 -0
  70. data/lib/pangea/architectures.rb +24 -0
  71. data/lib/pangea/backends/base.rb +77 -0
  72. data/lib/pangea/backends/local.rb +159 -0
  73. data/lib/pangea/backends/s3/dynamodb_lock.rb +115 -0
  74. data/lib/pangea/backends/s3.rb +129 -0
  75. data/lib/pangea/backends.rb +51 -0
  76. data/lib/pangea/cli/application/command_router.rb +143 -0
  77. data/lib/pangea/cli/application/options.rb +128 -0
  78. data/lib/pangea/cli/application.rb +130 -0
  79. data/lib/pangea/cli/commands/agent/analysis.rb +107 -0
  80. data/lib/pangea/cli/commands/agent/complexity.rb +67 -0
  81. data/lib/pangea/cli/commands/agent/cost.rb +59 -0
  82. data/lib/pangea/cli/commands/agent/dependencies.rb +63 -0
  83. data/lib/pangea/cli/commands/agent/explanation.rb +81 -0
  84. data/lib/pangea/cli/commands/agent/security.rb +69 -0
  85. data/lib/pangea/cli/commands/agent/suggestions.rb +55 -0
  86. data/lib/pangea/cli/commands/agent/validation.rb +77 -0
  87. data/lib/pangea/cli/commands/agent.rb +85 -0
  88. data/lib/pangea/cli/commands/apply.rb +116 -0
  89. data/lib/pangea/cli/commands/base_command.rb +120 -0
  90. data/lib/pangea/cli/commands/destroy.rb +112 -0
  91. data/lib/pangea/cli/commands/import/import_command_generator.rb +71 -0
  92. data/lib/pangea/cli/commands/import/resource_analyzer.rb +72 -0
  93. data/lib/pangea/cli/commands/import.rb +146 -0
  94. data/lib/pangea/cli/commands/init.rb +92 -0
  95. data/lib/pangea/cli/commands/inspect/config_inspection.rb +130 -0
  96. data/lib/pangea/cli/commands/inspect/resource_inspection.rb +105 -0
  97. data/lib/pangea/cli/commands/inspect/template_analysis.rb +124 -0
  98. data/lib/pangea/cli/commands/inspect.rb +95 -0
  99. data/lib/pangea/cli/commands/new_project.rb +266 -0
  100. data/lib/pangea/cli/commands/plan.rb +93 -0
  101. data/lib/pangea/cli/commands/sync.rb +95 -0
  102. data/lib/pangea/cli/error_handler.rb +169 -0
  103. data/lib/pangea/cli/errors.rb +57 -0
  104. data/lib/pangea/cli/formatters/json_formatter.rb +195 -0
  105. data/lib/pangea/cli/presenters/apply_presenter.rb +264 -0
  106. data/lib/pangea/cli/presenters/base_presenter.rb +142 -0
  107. data/lib/pangea/cli/presenters/destroy_presenter.rb +100 -0
  108. data/lib/pangea/cli/presenters/plan_presenter.rb +456 -0
  109. data/lib/pangea/cli/services/template_service.rb +96 -0
  110. data/lib/pangea/cli/services/workspace_service.rb +94 -0
  111. data/lib/pangea/cli/ui/README.md +255 -0
  112. data/lib/pangea/cli/ui/banner/operation_summary.rb +106 -0
  113. data/lib/pangea/cli/ui/banner.rb +80 -0
  114. data/lib/pangea/cli/ui/diff/formatting.rb +53 -0
  115. data/lib/pangea/cli/ui/diff/plan_parser.rb +84 -0
  116. data/lib/pangea/cli/ui/diff.rb +147 -0
  117. data/lib/pangea/cli/ui/logger/display_helpers.rb +87 -0
  118. data/lib/pangea/cli/ui/logger/info_panels.rb +88 -0
  119. data/lib/pangea/cli/ui/logger/resource_display.rb +54 -0
  120. data/lib/pangea/cli/ui/logger/styles.rb +21 -0
  121. data/lib/pangea/cli/ui/logger.rb +83 -0
  122. data/lib/pangea/cli/ui/output_formatter/constants.rb +22 -0
  123. data/lib/pangea/cli/ui/output_formatter/display.rb +157 -0
  124. data/lib/pangea/cli/ui/output_formatter/formatting.rb +44 -0
  125. data/lib/pangea/cli/ui/output_formatter.rb +23 -0
  126. data/lib/pangea/cli/ui/progress/animations.rb +69 -0
  127. data/lib/pangea/cli/ui/progress/wrappers.rb +100 -0
  128. data/lib/pangea/cli/ui/progress.rb +78 -0
  129. data/lib/pangea/cli/ui/spinner.rb +147 -0
  130. data/lib/pangea/cli/ui/table/formatters.rb +125 -0
  131. data/lib/pangea/cli/ui/table.rb +114 -0
  132. data/lib/pangea/cli/ui/visualizer/cost.rb +37 -0
  133. data/lib/pangea/cli/ui/visualizer/display.rb +92 -0
  134. data/lib/pangea/cli/ui/visualizer/graph.rb +89 -0
  135. data/lib/pangea/cli/ui/visualizer/statistics.rb +58 -0
  136. data/lib/pangea/cli/ui/visualizer.rb +167 -0
  137. data/lib/pangea/compilation/backend_injector.rb +78 -0
  138. data/lib/pangea/compilation/compilation_helpers.rb +128 -0
  139. data/lib/pangea/compilation/template_compiler.rb +123 -0
  140. data/lib/pangea/compilation/template_extractor.rb +81 -0
  141. data/lib/pangea/compilation/template_validator.rb +47 -0
  142. data/lib/pangea/compilation/validator.rb +133 -0
  143. data/lib/pangea/components.rb +27 -0
  144. data/lib/pangea/configuration/config_loader.rb +86 -0
  145. data/lib/pangea/configuration/defaults.rb +58 -0
  146. data/lib/pangea/configuration/namespace_manager.rb +95 -0
  147. data/lib/pangea/configuration/types/backends.rb +95 -0
  148. data/lib/pangea/configuration/types/base.rb +33 -0
  149. data/lib/pangea/configuration/types/configuration_schema.rb +105 -0
  150. data/lib/pangea/configuration/types/settings.rb +56 -0
  151. data/lib/pangea/configuration/types/state.rb +91 -0
  152. data/lib/pangea/configuration/types.rb +21 -0
  153. data/lib/pangea/configuration.rb +108 -0
  154. data/lib/pangea/entities.rb +18 -0
  155. data/lib/pangea/execution/terraform_command_builder.rb +87 -0
  156. data/lib/pangea/execution/terraform_command_executor.rb +152 -0
  157. data/lib/pangea/execution/terraform_executor.rb +140 -0
  158. data/lib/pangea/execution/terraform_operations.rb +91 -0
  159. data/lib/pangea/execution/terraform_output_parser.rb +129 -0
  160. data/lib/pangea/execution/terraform_retry.rb +99 -0
  161. data/lib/pangea/execution/workspace_manager.rb +164 -0
  162. data/lib/pangea/resources/templates/resource_template.rb.erb +56 -0
  163. data/lib/pangea/resources/validators/shared_validators.rb +48 -0
  164. data/lib/pangea/resources.rb +20 -0
  165. data/lib/pangea/types.rb +64 -0
  166. data/lib/pangea/utilities/cli/README.md +11 -0
  167. data/lib/pangea/utilities/cli/command.rb +98 -0
  168. data/lib/pangea/utilities/cli/commands/cost_command.rb +117 -0
  169. data/lib/pangea/utilities/cli/commands/drift_command.rb +127 -0
  170. data/lib/pangea/utilities/cli/commands/state_command.rb +119 -0
  171. data/lib/pangea/utilities/cost/README.md +12 -0
  172. data/lib/pangea/utilities/cost/calculator.rb +174 -0
  173. data/lib/pangea/utilities/cost.rb +29 -0
  174. data/lib/pangea/utilities/drift/README.md +12 -0
  175. data/lib/pangea/utilities/drift/detector.rb +122 -0
  176. data/lib/pangea/utilities/drift/report.rb +100 -0
  177. data/lib/pangea/utilities/drift.rb +29 -0
  178. data/lib/pangea/utilities/ip_discovery.rb +109 -0
  179. data/lib/pangea/utilities/remote_state/README.md +12 -0
  180. data/lib/pangea/utilities/remote_state/dependency_manager.rb +99 -0
  181. data/lib/pangea/utilities/remote_state/dsl_extensions.rb +109 -0
  182. data/lib/pangea/utilities/remote_state/output_registry.rb +119 -0
  183. data/lib/pangea/utilities/remote_state/reference.rb +77 -0
  184. data/lib/pangea/utilities/remote_state.rb +28 -0
  185. data/lib/pangea/utilities/visualization/README.md +12 -0
  186. data/lib/pangea/utilities/visualization/graph.rb +112 -0
  187. data/lib/pangea/utilities/visualization/mermaid_exporter.rb +149 -0
  188. data/lib/pangea/utilities/visualization.rb +28 -0
  189. data/lib/pangea/utilities.rb +34 -0
  190. data/lib/pangea/version.rb +15 -1
  191. data/lib/pangea.rb +38 -16
  192. data/pangea.gemspec +39 -34
  193. data/pangea.rb +14 -0
  194. data/pangea.yaml.example +87 -0
  195. data/pangea.yml.example +76 -0
  196. data/pkgs/products/pangea/deploy/configmap.yaml +67 -0
  197. data/pkgs/products/pangea/deploy/crds/infrastructuretemplates.yaml +395 -0
  198. data/pkgs/products/pangea/deploy/crds/pangeanamespaces.yaml +286 -0
  199. data/pkgs/products/pangea/deploy/kustomization.yaml +54 -0
  200. data/pkgs/products/pangea/deploy/namespace.yaml +6 -0
  201. data/pkgs/products/pangea/deploy/operator-deployment.yaml +138 -0
  202. data/pkgs/products/pangea/deploy/operator-service.yaml +23 -0
  203. data/pkgs/products/pangea/deploy/rbac/role.yaml +106 -0
  204. data/pkgs/products/pangea/deploy/rbac/rolebinding.yaml +15 -0
  205. data/pkgs/products/pangea/deploy/rbac/serviceaccount.yaml +7 -0
  206. data/pkgs/products/pangea/deploy/web-deployment.yaml +64 -0
  207. data/pkgs/products/pangea/deploy/web-service.yaml +19 -0
  208. data/rbs_collection.yaml +37 -0
  209. data/release.sh +32 -0
  210. data/scripts/add_copyright_headers.rb +65 -0
  211. data/scripts/analyze_resource_structure.rb +127 -0
  212. data/scripts/audit_vpc_resources.rb +36 -0
  213. data/scripts/discover_resources.rb +53 -0
  214. data/scripts/find_untested_resources.rb +115 -0
  215. data/scripts/generate_vpc_tests.rb +21 -0
  216. data/scripts/prioritize_resources.rb +72 -0
  217. data/scripts/synthesis_coverage_report.json +3723 -0
  218. data/scripts/synthesis_coverage_report.rb +284 -0
  219. data/scripts/synthesis_coverage_summary.rb +233 -0
  220. data/scripts/synthesis_enhancement_tasks.json +74 -0
  221. data/scripts/verify_implementation.rb +146 -0
  222. data/scripts/verify_utilities.rb +185 -0
  223. data/sig/pangea/architectures.rbs +260 -0
  224. data/sig/pangea/entities/namespace.rbs +37 -0
  225. data/sig/pangea/resources/aws.rbs +254 -0
  226. data/sig/pangea/resources/aws_acm_certificate.rbs +23 -0
  227. data/sig/pangea/resources/aws_acm_certificate_validation.rbs +20 -0
  228. data/sig/pangea/resources/aws_api_gateway_deployment.rbs +49 -0
  229. data/sig/pangea/resources/aws_api_gateway_method.rbs +51 -0
  230. data/sig/pangea/resources/aws_api_gateway_resource.rbs +33 -0
  231. data/sig/pangea/resources/aws_api_gateway_rest_api.rbs +60 -0
  232. data/sig/pangea/resources/aws_api_gateway_stage.rbs +89 -0
  233. data/sig/pangea/resources/aws_appstream_fleet.rbs +58 -0
  234. data/sig/pangea/resources/aws_batch_compute_environment.rbs +54 -0
  235. data/sig/pangea/resources/aws_batch_job_definition.rbs +69 -0
  236. data/sig/pangea/resources/aws_batch_job_queue.rbs +65 -0
  237. data/sig/pangea/resources/aws_braket_device.rbs +114 -0
  238. data/sig/pangea/resources/aws_braket_quantum_task.rbs +32 -0
  239. data/sig/pangea/resources/aws_budgets_budget.rbs +130 -0
  240. data/sig/pangea/resources/aws_budgets_budget_action.rbs +95 -0
  241. data/sig/pangea/resources/aws_cloudfront_cache_policy.rbs +18 -0
  242. data/sig/pangea/resources/aws_cloudfront_distribution.rbs +124 -0
  243. data/sig/pangea/resources/aws_cloudfront_origin_access_control.rbs +27 -0
  244. data/sig/pangea/resources/aws_cloudfront_origin_request_policy.rbs +17 -0
  245. data/sig/pangea/resources/aws_cloudwatch_composite_alarm.rbs +34 -0
  246. data/sig/pangea/resources/aws_cloudwatch_dashboard.rbs +69 -0
  247. data/sig/pangea/resources/aws_cloudwatch_event_rule.rbs +34 -0
  248. data/sig/pangea/resources/aws_cloudwatch_event_target.rbs +80 -0
  249. data/sig/pangea/resources/aws_cloudwatch_log_destination.rbs +26 -0
  250. data/sig/pangea/resources/aws_cloudwatch_log_destination_policy.rbs +27 -0
  251. data/sig/pangea/resources/aws_cloudwatch_log_group.rbs +28 -0
  252. data/sig/pangea/resources/aws_cloudwatch_log_metric_filter.rbs +43 -0
  253. data/sig/pangea/resources/aws_cloudwatch_log_stream.rbs +25 -0
  254. data/sig/pangea/resources/aws_cloudwatch_log_subscription_filter.rbs +28 -0
  255. data/sig/pangea/resources/aws_codeartifact_domain.rbs +29 -0
  256. data/sig/pangea/resources/aws_codeartifact_repository.rbs +46 -0
  257. data/sig/pangea/resources/aws_codestar_connection.rbs +36 -0
  258. data/sig/pangea/resources/aws_cognito_identity_pool.rbs +56 -0
  259. data/sig/pangea/resources/aws_cognito_identity_provider.rbs +46 -0
  260. data/sig/pangea/resources/aws_cognito_user.rbs +36 -0
  261. data/sig/pangea/resources/aws_cognito_user_group.rbs +34 -0
  262. data/sig/pangea/resources/aws_cognito_user_pool.rbs +176 -0
  263. data/sig/pangea/resources/aws_cognito_user_pool_client.rbs +75 -0
  264. data/sig/pangea/resources/aws_cognito_user_pool_domain.rbs +46 -0
  265. data/sig/pangea/resources/aws_datasync_on_snow_location.rbs +12 -0
  266. data/sig/pangea/resources/aws_datasync_on_snow_task.rbs +12 -0
  267. data/sig/pangea/resources/aws_datasync_snow_ball_edge.rbs +12 -0
  268. data/sig/pangea/resources/aws_db_parameter_group.rbs +81 -0
  269. data/sig/pangea/resources/aws_db_subnet_group.rbs +42 -0
  270. data/sig/pangea/resources/aws_ec2_carrier_gateway.rbs +12 -0
  271. data/sig/pangea/resources/aws_ec2_local_gateway.rbs +12 -0
  272. data/sig/pangea/resources/aws_ec2_local_gateway_route.rbs +12 -0
  273. data/sig/pangea/resources/aws_ec2_local_gateway_route_table.rbs +12 -0
  274. data/sig/pangea/resources/aws_ec2_local_gateway_route_table_vpc_association.rbs +12 -0
  275. data/sig/pangea/resources/aws_ec2_local_gateway_virtual_interface_group_association.rbs +12 -0
  276. data/sig/pangea/resources/aws_ecr_lifecycle_policy.rbs +28 -0
  277. data/sig/pangea/resources/aws_ecr_replication_configuration.rbs +42 -0
  278. data/sig/pangea/resources/aws_ecr_repository.rbs +36 -0
  279. data/sig/pangea/resources/aws_ecr_repository_policy.rbs +27 -0
  280. data/sig/pangea/resources/aws_ecs_cluster.rbs +86 -0
  281. data/sig/pangea/resources/aws_ecs_cluster_capacity_providers.rbs +59 -0
  282. data/sig/pangea/resources/aws_ecs_service.rbs +238 -0
  283. data/sig/pangea/resources/aws_ecs_task_definition.rbs +334 -0
  284. data/sig/pangea/resources/aws_efs_access_point.rbs +33 -0
  285. data/sig/pangea/resources/aws_efs_file_system.rbs +34 -0
  286. data/sig/pangea/resources/aws_efs_mount_target.rbs +29 -0
  287. data/sig/pangea/resources/aws_eks_addon.rbs +50 -0
  288. data/sig/pangea/resources/aws_eks_cluster.rbs +79 -0
  289. data/sig/pangea/resources/aws_eks_fargate_profile.rbs +43 -0
  290. data/sig/pangea/resources/aws_eks_node_group.rbs +106 -0
  291. data/sig/pangea/resources/aws_elasticache_cluster.rbs +39 -0
  292. data/sig/pangea/resources/aws_elasticache_parameter_group.rbs +18 -0
  293. data/sig/pangea/resources/aws_elasticache_subnet_group.rbs +17 -0
  294. data/sig/pangea/resources/aws_elemental_data_plane_channel.rbs +18 -0
  295. data/sig/pangea/resources/aws_emrcontainers_virtual_cluster.rbs +39 -0
  296. data/sig/pangea/resources/aws_frauddetector_detector.rbs +76 -0
  297. data/sig/pangea/resources/aws_groundstation_antenna_downlink_config.rbs +12 -0
  298. data/sig/pangea/resources/aws_groundstation_antenna_uplink_config.rbs +12 -0
  299. data/sig/pangea/resources/aws_groundstation_config.rbs +12 -0
  300. data/sig/pangea/resources/aws_groundstation_contact.rbs +12 -0
  301. data/sig/pangea/resources/aws_groundstation_dataflow_endpoint_group.rbs +12 -0
  302. data/sig/pangea/resources/aws_groundstation_mission_profile.rbs +12 -0
  303. data/sig/pangea/resources/aws_groundstation_tracking_config.rbs +12 -0
  304. data/sig/pangea/resources/aws_healthlake_fhir_datastore.rbs +80 -0
  305. data/sig/pangea/resources/aws_iam_group.rbs +71 -0
  306. data/sig/pangea/resources/aws_iam_policy.rbs +62 -0
  307. data/sig/pangea/resources/aws_iam_role_policy_attachment.rbs +88 -0
  308. data/sig/pangea/resources/aws_iam_user.rbs +56 -0
  309. data/sig/pangea/resources/aws_kms_alias.rbs +16 -0
  310. data/sig/pangea/resources/aws_kms_key.rbs +23 -0
  311. data/sig/pangea/resources/aws_lambda_event_source_mapping.rbs +116 -0
  312. data/sig/pangea/resources/aws_lambda_function.rbs +137 -0
  313. data/sig/pangea/resources/aws_lambda_layer_version.rbs +48 -0
  314. data/sig/pangea/resources/aws_lambda_permission.rbs +44 -0
  315. data/sig/pangea/resources/aws_lightsail_bucket.rbs +12 -0
  316. data/sig/pangea/resources/aws_lightsail_certificate.rbs +12 -0
  317. data/sig/pangea/resources/aws_lightsail_database.rbs +12 -0
  318. data/sig/pangea/resources/aws_lightsail_disk.rbs +12 -0
  319. data/sig/pangea/resources/aws_lightsail_disk_attachment.rbs +12 -0
  320. data/sig/pangea/resources/aws_lightsail_domain.rbs +12 -0
  321. data/sig/pangea/resources/aws_lightsail_instance.rbs +12 -0
  322. data/sig/pangea/resources/aws_lightsail_key_pair.rbs +12 -0
  323. data/sig/pangea/resources/aws_lightsail_load_balancer.rbs +12 -0
  324. data/sig/pangea/resources/aws_lightsail_load_balancer_attachment.rbs +12 -0
  325. data/sig/pangea/resources/aws_lightsail_static_ip.rbs +12 -0
  326. data/sig/pangea/resources/aws_lightsail_static_ip_attachment.rbs +12 -0
  327. data/sig/pangea/resources/aws_lookoutequipment_dataset.rbs +73 -0
  328. data/sig/pangea/resources/aws_managedblockchain_member.rbs +73 -0
  329. data/sig/pangea/resources/aws_managedblockchain_network.rbs +102 -0
  330. data/sig/pangea/resources/aws_managedblockchain_node.rbs +71 -0
  331. data/sig/pangea/resources/aws_media_convert_queue.rbs +20 -0
  332. data/sig/pangea/resources/aws_media_live_channel.rbs +67 -0
  333. data/sig/pangea/resources/aws_media_live_input.rbs +68 -0
  334. data/sig/pangea/resources/aws_media_package_channel.rbs +35 -0
  335. data/sig/pangea/resources/aws_media_package_origin_endpoint.rbs +29 -0
  336. data/sig/pangea/resources/aws_media_store_container.rbs +13 -0
  337. data/sig/pangea/resources/aws_outposts_asset.rbs +12 -0
  338. data/sig/pangea/resources/aws_outposts_capacity_task.rbs +12 -0
  339. data/sig/pangea/resources/aws_outposts_connection.rbs +12 -0
  340. data/sig/pangea/resources/aws_outposts_order.rbs +12 -0
  341. data/sig/pangea/resources/aws_outposts_outpost.rbs +12 -0
  342. data/sig/pangea/resources/aws_outposts_outpost_instance_type.rbs +12 -0
  343. data/sig/pangea/resources/aws_outposts_site.rbs +12 -0
  344. data/sig/pangea/resources/aws_outposts_supported_hardware_type.rbs +12 -0
  345. data/sig/pangea/resources/aws_qldb_ledger.rbs +37 -0
  346. data/sig/pangea/resources/aws_qldb_stream.rbs +53 -0
  347. data/sig/pangea/resources/aws_rds_cluster.rbs +193 -0
  348. data/sig/pangea/resources/aws_rds_cluster_instance.rbs +128 -0
  349. data/sig/pangea/resources/aws_route53_health_check.rbs +34 -0
  350. data/sig/pangea/resources/aws_route53_record.rbs +63 -0
  351. data/sig/pangea/resources/aws_route53_zone.rbs +26 -0
  352. data/sig/pangea/resources/aws_s3_bucket_cors_configuration.rbs +42 -0
  353. data/sig/pangea/resources/aws_s3_bucket_inventory.rbs +78 -0
  354. data/sig/pangea/resources/aws_s3_bucket_lifecycle_configuration.rbs +94 -0
  355. data/sig/pangea/resources/aws_s3_bucket_notification.rbs +65 -0
  356. data/sig/pangea/resources/aws_s3_bucket_object_lock_configuration.rbs +51 -0
  357. data/sig/pangea/resources/aws_s3_bucket_replication_configuration.rbs +107 -0
  358. data/sig/pangea/resources/aws_s3_bucket_website_configuration.rbs +74 -0
  359. data/sig/pangea/resources/aws_sagemaker_feature_group.rbs +58 -0
  360. data/sig/pangea/resources/aws_secretsmanager_secret.rbs +29 -0
  361. data/sig/pangea/resources/aws_secretsmanager_secret_version.rbs +21 -0
  362. data/sig/pangea/resources/aws_sfn_activity.rbs +36 -0
  363. data/sig/pangea/resources/aws_sfn_state_machine.rbs +54 -0
  364. data/sig/pangea/resources/aws_snowball_cluster.rbs +12 -0
  365. data/sig/pangea/resources/aws_snowball_job.rbs +12 -0
  366. data/sig/pangea/resources/aws_snowcone_device.rbs +12 -0
  367. data/sig/pangea/resources/aws_snowcone_job.rbs +12 -0
  368. data/sig/pangea/resources/aws_snowmobile_job.rbs +12 -0
  369. data/sig/pangea/resources/aws_sns_subscription.rbs +49 -0
  370. data/sig/pangea/resources/aws_sns_topic.rbs +78 -0
  371. data/sig/pangea/resources/aws_sqs_queue.rbs +67 -0
  372. data/sig/pangea/resources/aws_sqs_queue_policy.rbs +29 -0
  373. data/sig/pangea/resources/aws_wavelength_application_deployment.rbs +12 -0
  374. data/sig/pangea/resources/aws_wavelength_deployment.rbs +12 -0
  375. data/sig/pangea/resources/aws_wavelength_edge_location_mapping.rbs +12 -0
  376. data/sig/pangea/resources/aws_wavelength_network_interface.rbs +12 -0
  377. data/sig/pangea/resources/aws_wavelength_workload.rbs +12 -0
  378. data/sig/pangea/resources/aws_workspaces_bundle.rbs +50 -0
  379. data/sig/pangea/resources/aws_workspaces_directory.rbs +63 -0
  380. data/sig/pangea/resources/aws_workspaces_ip_group.rbs +41 -0
  381. data/sig/pangea/resources/aws_workspaces_workspace.rbs +40 -0
  382. data/sig/pangea/structures/namespace.rbs +28 -0
  383. data/sig/pangea/structures/project.rbs +20 -0
  384. data/sig/pangea/types.rbs +76 -0
  385. data/sig/pangea.rbs +13 -0
  386. data/synthesizer-tests.yaml +72 -0
  387. data/test_infrastructure/infrastructure.rb +510 -0
  388. data/test_infrastructure/main.tf.json +15 -0
  389. data/test_infrastructure/multi_template_infrastructure.rb +125 -0
  390. data/test_infrastructure/pangea.yml +35 -0
  391. data/test_infrastructure/simple_infrastructure.rb +82 -0
  392. data/test_infrastructure/test_multi_workspaces.rb +90 -0
  393. data/test_infrastructure/test_template_workspaces.rb +62 -0
  394. data/test_infrastructure/workspace_compute.tf.json +46 -0
  395. data/test_infrastructure/workspace_local_resources.tf.json +41 -0
  396. data/test_infrastructure/workspace_networking.tf.json +32 -0
  397. data/test_infrastructure/workspace_storage.tf.json +34 -0
  398. metadata +673 -147
  399. data/example/config/README.md +0 -3
  400. data/example/config/sample.rb +0 -20
  401. data/lib/pangea/cli/config.rb +0 -99
  402. data/lib/pangea/cli/constants.rb +0 -33
  403. data/lib/pangea/cli/subcommands/config.rb +0 -212
  404. data/lib/pangea/cli/subcommands/infra.rb +0 -311
  405. data/lib/pangea/cli/subcommands/main.rb +0 -58
  406. data/lib/pangea/cli/subcommands/pangea.rb +0 -18
  407. data/lib/pangea/cli/subcommands/state.rb +0 -30
  408. data/lib/pangea/cli.rb +0 -73
  409. data/lib/pangea/config.rb +0 -35
  410. data/lib/pangea/docker.rb +0 -104
  411. data/lib/pangea/errors/incorrect_subcommand_error.rb +0 -2
  412. data/lib/pangea/errors/namespace_not_found_error.rb +0 -2
  413. data/lib/pangea/errors/no_infra_target_error.rb +0 -2
  414. data/lib/pangea/errors/project_not_found_error.rb +0 -2
  415. data/lib/pangea/errors/site_not_found_error.rb +0 -2
  416. data/lib/pangea/executor.rb +0 -10
  417. data/lib/pangea/log/init.rb +0 -2
  418. data/lib/pangea/modcache.rb +0 -79
  419. data/lib/pangea/module.rb +0 -17
  420. data/lib/pangea/modules.rb +0 -134
  421. data/lib/pangea/processor.rb +0 -104
  422. data/lib/pangea/renderer.rb +0 -85
  423. data/lib/pangea/sandbox.rb +0 -90
  424. data/lib/pangea/say/init.rb +0 -27
  425. data/lib/pangea/shell/README.md +0 -1
  426. data/lib/pangea/shell/terraform.rb +0 -21
  427. data/lib/pangea/shell.rb +0 -27
  428. data/lib/pangea/stack.rb +0 -11
  429. data/lib/pangea/state.rb +0 -96
  430. data/lib/pangea/structures/README.md +0 -3
  431. data/lib/pangea/structures/abstract.rb +0 -2
  432. data/lib/pangea/structures/namespace.rb +0 -4
  433. data/lib/pangea/structures/project.rb +0 -4
  434. data/lib/pangea/structures/site.rb +0 -4
  435. data/lib/pangea/synthesizer/config.rb +0 -38
  436. data/lib/pangea/utils.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b67384b1e67ddd2e0ce27af66f4e84cbb477eb9ca4c7d7441f347379a53664a6
4
- data.tar.gz: 660bad90a7ad11eeea0efcba6cebb195d4b033ad5f1687f244e9b7323a6d5442
3
+ metadata.gz: 4ea21a75b0c516b27bb6a7bd07273509323c5343809d5b0379e17842e2952e05
4
+ data.tar.gz: 0e5f2f1bcd36111e0bb22a62e5689e60063aeef306fb7ee1f27a1da8e03e4c65
5
5
  SHA512:
6
- metadata.gz: 859e4081b558250b3c130c4d23cf45a4d9f631cb0545e75facb6ef83129f8841c9a9afdaf115b8a3cc7f58ede4e6ff124ca2cf9b3da12e6305475a65b61583ea
7
- data.tar.gz: dbc9e49f912a86066c05a9e6f6ddc78605cdb745614b57addd9e538222a066dc21bc6cb356cd428b6ce70d670db50db0108b28ae085bbbf69492b007368e4140
6
+ metadata.gz: c8a3df832621cbf6f8703b2f0285e0df4bec5b923ce6e88084d1b4658434437379d7f849adc3c1ad75f2c164562e5507686d6c01dcc8434b8a87b37afe2f7ee5
7
+ data.tar.gz: 99eea2be7e31503322c467f69483e6d70ccd578fbcc0cf6924a9e83bfc6da75f233961d7806afd60ec23a980293c2817d54853149d2caed360846d2fa55abdd5
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: pangea-cloud-resource-creation
3
+ description: Creates cloud provider resources for Pangea using Dry::Struct types, terraform-synthesizer integration, and RSpec tests. Use when adding support for new cloud providers (AWS, Hetzner, Cloudflare, GCP, Azure, DigitalOcean, etc.) to Pangea. Covers type definitions, resource functions, synthesis specs, tracker creation, and batch implementation patterns. Apply when implementing resources from provider documentation, adding new cloud integrations, or standardizing resource creation workflows.
4
+ metadata:
5
+ version: "1.0.0"
6
+ last_verified: "2025-12-27"
7
+ research_version: "2025-12-27"
8
+ domain_keywords:
9
+ - "terraform"
10
+ - "cloud-providers"
11
+ - "infrastructure-as-code"
12
+ - "resource-synthesis"
13
+ - "ruby-infrastructure"
14
+ - "dry-struct"
15
+ ---
16
+
17
+ # Pangea Cloud Provider Resource Creation
18
+
19
+ ## Overview
20
+
21
+ Standardized pattern for adding cloud provider resources to Pangea. Production-tested with Cloudflare (29 resources) and Hetzner Cloud (25 resources).
22
+
23
+ **Location**: `pkgs/tools/ruby/pangea/`
24
+
25
+ ## Core Pattern
26
+
27
+ Each cloud provider resource requires **exactly three files**:
28
+
29
+ | File | Location | Purpose |
30
+ |------|----------|---------|
31
+ | `types.rb` | `lib/pangea/resources/{resource}/types.rb` | Dry::Struct attribute validation |
32
+ | `resource.rb` | `lib/pangea/resources/{resource}/resource.rb` | terraform-synthesizer + ResourceReference |
33
+ | `synthesis_spec.rb` | `spec/resources/{resource}/synthesis_spec.rb` | RSpec tests for Terraform JSON |
34
+
35
+ **Critical**: All three files must follow exact patterns. Deviations break synthesis or testing.
36
+
37
+ ## File Structure
38
+
39
+ ```
40
+ pkgs/tools/ruby/pangea/
41
+ ├── lib/pangea/resources/
42
+ │ ├── types.rb # Central type definitions for ALL providers
43
+ │ ├── {resource_name}/
44
+ │ │ ├── types.rb # Resource-specific Dry::Struct
45
+ │ │ └── resource.rb # Resource function
46
+ ├── spec/resources/
47
+ │ └── {resource_name}/
48
+ │ └── synthesis_spec.rb # Synthesis tests
49
+ ```
50
+
51
+ ## Implementation Workflow
52
+
53
+ ### Phase 1: Planning
54
+
55
+ 1. **Research** - Review Terraform provider documentation
56
+ 2. **Create Tracker** - `PROVIDER_IMPLEMENTATION.json` with batches
57
+ 3. **Design Types** - Add provider types to central `types.rb`
58
+
59
+ ### Phase 2: Resource Implementation
60
+
61
+ For each resource, create the three required files:
62
+
63
+ 1. **types.rb** - Dry::Struct with `transform_keys(&:to_sym)`
64
+ 2. **resource.rb** - Resource function with conditionals for optional fields
65
+ 3. **synthesis_spec.rb** - Tests with `TerraformSynthesizer.new`
66
+
67
+ ### Phase 3: Batch Execution
68
+
69
+ 1. Implement all types first
70
+ 2. Complete each batch (all 3 files per resource)
71
+ 3. Update tracker: `bin/tracker update resource_name all`
72
+ 4. Commit with batch completion message
73
+
74
+ ## Quick Reference
75
+
76
+ ### Attribute Patterns (types.rb)
77
+
78
+ | Pattern | Syntax |
79
+ |---------|--------|
80
+ | Required | `attribute :name, Type` |
81
+ | Optional with default | `attribute :name, Type.default(value)` |
82
+ | Optional no default | `attribute :name, Type.optional.default(nil)` |
83
+ | Arrays | `attribute :items, Array.of(Type).default([].freeze)` |
84
+ | Hashes | `attribute :labels, Hash.default({}.freeze)` |
85
+
86
+ ### Resource Patterns (resource.rb)
87
+
88
+ | Pattern | Syntax |
89
+ |---------|--------|
90
+ | Required field | `field_name attrs.field` |
91
+ | Optional field | `field_name attrs.field if attrs.field` |
92
+ | Default field | `field_name attrs.field` (always include) |
93
+ | Nested block | `block_name do ... end` inside conditional |
94
+ | Array blocks | `attrs.items.each do \|item\| ... end` |
95
+
96
+ ### Test Requirements (synthesis_spec.rb)
97
+
98
+ - Basic resource with defaults
99
+ - Resource with all options
100
+ - Nested blocks/arrays
101
+ - Resource references (interpolation)
102
+ - Resource composition (parent-child)
103
+
104
+ ## Decision Table
105
+
106
+ | Scenario | Action |
107
+ |----------|--------|
108
+ | Add new cloud provider | Create tracker, implement all batches |
109
+ | Add single resource | Create 3 files, update tracker |
110
+ | Review implementation | Check against anti-patterns |
111
+ | Debug synthesis | Run individual spec, check conditionals |
112
+ | Type validation error | Check `transform_keys`, attribute syntax |
113
+
114
+ ## Anti-Patterns (Quick Check)
115
+
116
+ | Issue | Fix |
117
+ |-------|-----|
118
+ | Missing `transform_keys(&:to_sym)` | Add to Dry::Struct class |
119
+ | Hardcoded values in resource | Use `attrs.field` |
120
+ | Optional without conditional | Add `if attrs.field` |
121
+ | Missing auto-registration | Add `ResourceRegistry.register_module(...)` |
122
+ | Tests without synthesizer | Use `TerraformSynthesizer.new` |
123
+
124
+ ## Testing
125
+
126
+ ```bash
127
+ cd pkgs/tools/ruby/pangea
128
+
129
+ # Single resource
130
+ rspec spec/resources/hcloud_volume/synthesis_spec.rb
131
+
132
+ # All provider resources
133
+ rspec spec/resources/hcloud_*
134
+ ```
135
+
136
+ ## When to Use This Skill
137
+
138
+ - Adding new cloud provider to Pangea
139
+ - Implementing resources from Terraform provider docs
140
+ - Creating resource tracker for new provider
141
+ - Reviewing resource implementation quality
142
+ - User asks: "add support for {cloud provider}"
143
+ - User asks: "implement {terraform resource}"
144
+
145
+ ## Success Criteria
146
+
147
+ - 100% resource coverage for target provider
148
+ - All resources follow three-file pattern
149
+ - All tests use terraform-synthesizer
150
+ - ResourceReference enables composition
151
+ - Tracker shows 100% completion
152
+
153
+ ## Detailed References
154
+
155
+ | Reference | Content |
156
+ |-----------|---------|
157
+ | [{baseDir}/references/resource-templates.md](references/resource-templates.md) | Full templates for types.rb, resource.rb, synthesis_spec.rb |
158
+ | [{baseDir}/references/type-system.md](references/type-system.md) | Type definitions, categories, tracker JSON template |
159
+ | [{baseDir}/references/hetzner-volume-example.md](references/hetzner-volume-example.md) | Complete end-to-end implementation example |
160
+ | [{baseDir}/references/tracker-cli.md](references/tracker-cli.md) | Tracker CLI script implementation |
161
+ | [{baseDir}/references/patterns-antipatterns.md](references/patterns-antipatterns.md) | Common patterns, anti-patterns, testing, git workflow |
162
+
163
+ ## Related Resources
164
+
165
+ - **Hetzner Implementation**: 25 resources (100% complete)
166
+ - **Cloudflare Implementation**: 29 resources (100% complete)
167
+ - **Type System**: `lib/pangea/resources/types.rb`
168
+ - **Synthesizer**: `lib/terraform-synthesizer.rb`
169
+ - **Testing Skill**: `.claude/skills/pangea-rspec-resource-testing.md`
@@ -0,0 +1,133 @@
1
+ # Complete Example: Hetzner Volume
2
+
3
+ End-to-end implementation of `hcloud_volume` resource.
4
+
5
+ ## 1. Type Definition in types.rb
6
+
7
+ ```ruby
8
+ # lib/pangea/resources/types.rb (ADD at end before closing 'end')
9
+
10
+ # Hetzner volume filesystem formats
11
+ HetznerVolumeFormat = String.enum('xfs', 'ext4')
12
+
13
+ # Hetzner volume size validation (10-10000 GB)
14
+ HetznerVolumeSize = Integer.constrained(gteq: 10, lteq: 10000)
15
+ ```
16
+
17
+ ## 2. Resource Types
18
+
19
+ ```ruby
20
+ # lib/pangea/resources/hcloud_volume/types.rb
21
+ # frozen_string_literal: true
22
+ # Copyright 2025 The Pangea Authors
23
+
24
+ require 'dry-struct'
25
+ require 'pangea/resources/types'
26
+
27
+ module Pangea
28
+ module Resources
29
+ module Hetzner
30
+ module Types
31
+ class VolumeAttributes < Dry::Struct
32
+ transform_keys(&:to_sym)
33
+
34
+ # Required
35
+ attribute :name, Resources::Types::String
36
+ attribute :size, HetznerVolumeSize
37
+
38
+ # Optional
39
+ attribute :location, HetznerLocation.optional.default(nil)
40
+ attribute :format, HetznerVolumeFormat.optional.default(nil)
41
+ attribute :labels, HetznerLabels.default({}.freeze)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ ```
48
+
49
+ ## 3. Resource Function
50
+
51
+ ```ruby
52
+ # lib/pangea/resources/hcloud_volume/resource.rb
53
+ # frozen_string_literal: true
54
+ # Copyright 2025 The Pangea Authors
55
+
56
+ require 'pangea/resources/base'
57
+ require 'pangea/resources/reference'
58
+ require 'pangea/resources/hcloud_volume/types'
59
+ require 'pangea/resource_registry'
60
+
61
+ module Pangea
62
+ module Resources
63
+ module HcloudVolume
64
+ def hcloud_volume(name, attributes = {})
65
+ volume_attrs = Hetzner::Types::VolumeAttributes.new(attributes)
66
+
67
+ resource(:hcloud_volume, name) do
68
+ name volume_attrs.name
69
+ size volume_attrs.size
70
+ location volume_attrs.location if volume_attrs.location
71
+ format volume_attrs.format if volume_attrs.format
72
+ labels volume_attrs.labels
73
+ end
74
+
75
+ ResourceReference.new(
76
+ type: 'hcloud_volume',
77
+ name: name,
78
+ resource_attributes: volume_attrs.to_h,
79
+ outputs: {
80
+ id: "${hcloud_volume.#{name}.id}",
81
+ size: "${hcloud_volume.#{name}.size}",
82
+ linux_device: "${hcloud_volume.#{name}.linux_device}"
83
+ }
84
+ )
85
+ end
86
+ end
87
+
88
+ module Hetzner
89
+ include HcloudVolume
90
+ end
91
+ end
92
+ end
93
+
94
+ Pangea::ResourceRegistry.register_module(Pangea::Resources::Hetzner)
95
+ ```
96
+
97
+ ## 4. Synthesis Spec
98
+
99
+ ```ruby
100
+ # spec/resources/hcloud_volume/synthesis_spec.rb
101
+ # frozen_string_literal: true
102
+ # Copyright 2025 The Pangea Authors
103
+
104
+ require 'spec_helper'
105
+ require 'terraform-synthesizer'
106
+ require 'pangea/resources/hcloud_volume/resource'
107
+
108
+ RSpec.describe 'hcloud_volume synthesis' do
109
+ include Pangea::Resources::Hetzner
110
+
111
+ let(:synthesizer) { TerraformSynthesizer.new }
112
+
113
+ it 'synthesizes volume' do
114
+ synthesizer.instance_eval do
115
+ extend Pangea::Resources::Hetzner
116
+ hcloud_volume(:data, {
117
+ name: "web-data",
118
+ size: 100,
119
+ location: "fsn1",
120
+ format: "ext4"
121
+ })
122
+ end
123
+
124
+ result = synthesizer.synthesis
125
+ volume = result[:resource][:hcloud_volume][:data]
126
+
127
+ expect(volume[:name]).to eq("web-data")
128
+ expect(volume[:size]).to eq(100)
129
+ expect(volume[:location]).to eq("fsn1")
130
+ expect(volume[:format]).to eq("ext4")
131
+ end
132
+ end
133
+ ```
@@ -0,0 +1,149 @@
1
+ # Patterns, Anti-Patterns, and Testing
2
+
3
+ ## Common Patterns
4
+
5
+ ### Nested Blocks
6
+
7
+ ```ruby
8
+ # In resource.rb
9
+ if attrs.health_check
10
+ health_check do
11
+ protocol attrs.health_check[:protocol]
12
+ port attrs.health_check[:port]
13
+ interval attrs.health_check[:interval] if attrs.health_check[:interval]
14
+ end
15
+ end
16
+ ```
17
+
18
+ ### Array of Nested Blocks
19
+
20
+ ```ruby
21
+ # In resource.rb
22
+ attrs.rules.each do |rule|
23
+ rule_block do
24
+ direction rule[:direction]
25
+ protocol rule[:protocol]
26
+ port rule[:port] if rule[:port]
27
+ end
28
+ end
29
+ ```
30
+
31
+ ### Conditional Optional Fields
32
+
33
+ ```ruby
34
+ # In resource.rb
35
+ description attrs.description if attrs.description
36
+ location attrs.location if attrs.location
37
+
38
+ # DON'T: if attrs.optional_field.nil? ... (wrong)
39
+ # DO: if attrs.optional_field ... (correct)
40
+ ```
41
+
42
+ ### Computed Properties
43
+
44
+ ```ruby
45
+ # In types.rb
46
+ class ServerAttributes < Dry::Struct
47
+ attribute :server_type, HetznerServerType
48
+
49
+ def is_arm?
50
+ server_type.start_with?('cax')
51
+ end
52
+
53
+ def cpu_type
54
+ is_arm? ? 'arm64' : 'x86_64'
55
+ end
56
+ end
57
+
58
+ # In resource.rb
59
+ resource(:hcloud_server, name) do
60
+ server_type attrs.server_type
61
+ cpu_architecture attrs.cpu_type # Use computed property
62
+ end
63
+ ```
64
+
65
+ ## Anti-Patterns
66
+
67
+ | Anti-Pattern | Problem | Fix |
68
+ |--------------|---------|-----|
69
+ | Missing `transform_keys` | Symbol/string key errors | Add `transform_keys(&:to_sym)` |
70
+ | Hardcoded values in resource | Values should come from attrs | Use `attrs.field` |
71
+ | No conditionals for optional | Includes nil in Terraform | `field attrs.val if attrs.val` |
72
+ | Missing auto-registration | Resource unavailable | Add `ResourceRegistry.register_module(...)` |
73
+ | Tests without synthesizer | Doesn't test Terraform generation | Use `TerraformSynthesizer.new` |
74
+
75
+ ## Testing Strategy
76
+
77
+ ### Run Commands
78
+
79
+ ```bash
80
+ cd pkgs/tools/ruby/pangea
81
+
82
+ # Individual resource
83
+ rspec spec/resources/hcloud_volume/synthesis_spec.rb
84
+
85
+ # All provider resources
86
+ rspec spec/resources/hcloud_*
87
+ ```
88
+
89
+ ### Validate Types in IRB
90
+
91
+ ```ruby
92
+ require 'pangea/resources/hcloud_volume/types'
93
+
94
+ # Valid input
95
+ attrs = Pangea::Resources::Hetzner::Types::VolumeAttributes.new(
96
+ name: "test",
97
+ size: 100,
98
+ format: "ext4"
99
+ )
100
+
101
+ # Invalid input (should raise error)
102
+ attrs = Pangea::Resources::Hetzner::Types::VolumeAttributes.new(
103
+ name: "test",
104
+ size: 5 # Too small, should fail
105
+ )
106
+ ```
107
+
108
+ ## Git Commit Messages
109
+
110
+ ```bash
111
+ # Type definitions
112
+ git commit -m "feat(pangea): add Hetzner Cloud type definitions (12 types)"
113
+
114
+ # Batch implementation
115
+ git commit -m "feat(pangea): complete Batch 1 - Core Infrastructure (5/5 resources)
116
+
117
+ Resources implemented:
118
+ - hcloud_ssh_key: SSH key management
119
+ - hcloud_network: Private VPC networks
120
+ - hcloud_firewall: Stateful firewalls
121
+ - hcloud_server: Virtual servers
122
+ - hcloud_network_subnet: Network subnets
123
+
124
+ All resources include:
125
+ - Dry::Struct type validation
126
+ - terraform-synthesizer integration
127
+ - RSpec synthesis tests
128
+ "
129
+
130
+ # Completion
131
+ git commit -m "docs(pangea): add Provider implementation completion report
132
+
133
+ 100% coverage (XX/XX resources)
134
+ All batches complete
135
+ "
136
+ ```
137
+
138
+ ## Completion Checklist
139
+
140
+ Before marking a resource complete:
141
+
142
+ - [ ] Type definitions added to types.rb
143
+ - [ ] types.rb created with Dry::Struct
144
+ - [ ] resource.rb created with resource() function
145
+ - [ ] synthesis_spec.rb created with TerraformSynthesizer tests
146
+ - [ ] All tests pass
147
+ - [ ] Resource auto-registers via ResourceRegistry
148
+ - [ ] Tracker updated
149
+ - [ ] Committed with descriptive message