rcf-lite 0.23.0 → 0.25.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 (666) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/blueprints/application-account-settings/docs/topics.md +10 -1
  3. package/blueprints/application-admin-console/CHANGELOG.md +12 -0
  4. package/blueprints/application-admin-console/blueprint.json +34 -1
  5. package/blueprints/application-admin-console/contributions/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +25 -0
  6. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-014.json +17 -0
  7. package/blueprints/application-admin-console/contributions/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +32 -0
  8. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21815.json +27 -0
  9. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21816.json +27 -0
  10. package/blueprints/application-admin-console/docs/topics.md +10 -1
  11. package/blueprints/application-admin-console/guide/application-admin-console.md +24 -0
  12. package/blueprints/application-admin-console/probe-packs/application-admin-console.pack.mjs +26 -1
  13. package/blueprints/application-api-rest/docs/topics.md +10 -1
  14. package/blueprints/application-charts/docs/topics.md +10 -1
  15. package/blueprints/application-dashboard/docs/topics.md +10 -1
  16. package/blueprints/application-datatable/docs/topics.md +10 -1
  17. package/blueprints/application-empty-error-states/docs/topics.md +10 -1
  18. package/blueprints/application-error-handling/docs/topics.md +10 -1
  19. package/blueprints/application-file-upload/docs/topics.md +10 -1
  20. package/blueprints/application-forms-wizard/docs/topics.md +10 -1
  21. package/blueprints/application-notifications-in-app/docs/topics.md +10 -1
  22. package/blueprints/application-onboarding-tour/docs/topics.md +10 -1
  23. package/blueprints/application-spa/docs/topics.md +10 -1
  24. package/blueprints/delivery-ci-workflows/docs/topics.md +10 -1
  25. package/blueprints/deploy-cloudflare-workers/docs/topics.md +10 -1
  26. package/blueprints/deploy-hetzner-server/CHANGELOG.md +34 -0
  27. package/blueprints/deploy-hetzner-server/README.md +202 -0
  28. package/blueprints/deploy-hetzner-server/blueprint.json +233 -0
  29. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +14 -0
  30. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +14 -0
  31. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +20 -0
  32. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +14 -0
  33. package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +64 -0
  34. package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +116 -0
  35. package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +180 -0
  36. package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +106 -0
  37. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +63 -0
  38. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +60 -0
  39. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +58 -0
  40. package/blueprints/deploy-hetzner-server/contributions/probes/run-cloud-init-render-lint.mjs +9 -0
  41. package/blueprints/deploy-hetzner-server/contributions/probes/run-hcloud-dry-run-mock.mjs +9 -0
  42. package/blueprints/deploy-hetzner-server/contributions/probes/run-manifest-schema-validate.mjs +9 -0
  43. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-cloud-init-hardened.mjs +9 -0
  44. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-snapshot-on-demand.mjs +9 -0
  45. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-throwaway-server-provision.mjs +9 -0
  46. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-001.json +18 -0
  47. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-002.json +18 -0
  48. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-003.json +18 -0
  49. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-004.json +18 -0
  50. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-005.json +18 -0
  51. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-006.json +18 -0
  52. package/blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json +108 -0
  53. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json +27 -0
  54. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +26 -0
  55. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +26 -0
  56. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +25 -0
  57. package/blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl +93 -0
  58. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37101.json +24 -0
  59. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37102.json +24 -0
  60. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37103.json +25 -0
  61. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37104.json +24 -0
  62. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37105.json +24 -0
  63. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37106.json +25 -0
  64. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37107.json +24 -0
  65. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37108.json +24 -0
  66. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37109.json +24 -0
  67. package/blueprints/deploy-hetzner-server/docs/topics.md +48 -0
  68. package/blueprints/deploy-hetzner-server/guide/deploy-hetzner-server.md +180 -0
  69. package/blueprints/edge-cloudflare-access/CHANGELOG.md +23 -0
  70. package/blueprints/edge-cloudflare-access/README.md +141 -0
  71. package/blueprints/edge-cloudflare-access/blueprint.json +197 -0
  72. package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +14 -0
  73. package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +25 -0
  74. package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +12 -0
  75. package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +12 -0
  76. package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +100 -0
  77. package/blueprints/edge-cloudflare-access/contributions/probes/audit-event-secrecy.mjs +70 -0
  78. package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-fixture.mjs +63 -0
  79. package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-reject.mjs +95 -0
  80. package/blueprints/edge-cloudflare-access/contributions/probes/probe-utils.mjs +90 -0
  81. package/blueprints/edge-cloudflare-access/contributions/probes/real-account-gated-url.mjs +65 -0
  82. package/blueprints/edge-cloudflare-access/contributions/probes/run-admin-console-gate-surface.mjs +5 -0
  83. package/blueprints/edge-cloudflare-access/contributions/probes/run-audit-event-secrecy.mjs +5 -0
  84. package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-fixture.mjs +5 -0
  85. package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-reject.mjs +5 -0
  86. package/blueprints/edge-cloudflare-access/contributions/probes/run-real-account-gated-url.mjs +5 -0
  87. package/blueprints/edge-cloudflare-access/contributions/probes/run-wrangler-seam.mjs +5 -0
  88. package/blueprints/edge-cloudflare-access/contributions/probes/wrangler-seam.mjs +203 -0
  89. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-001.json +17 -0
  90. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-002.json +17 -0
  91. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-003.json +17 -0
  92. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-004.json +17 -0
  93. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-005.json +17 -0
  94. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-006.json +18 -0
  95. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +31 -0
  96. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +33 -0
  97. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +25 -0
  98. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +25 -0
  99. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34101.json +27 -0
  100. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34102.json +28 -0
  101. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34103.json +27 -0
  102. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34104.json +27 -0
  103. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34105.json +27 -0
  104. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34106.json +27 -0
  105. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34107.json +27 -0
  106. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34108.json +27 -0
  107. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34109.json +27 -0
  108. package/blueprints/edge-cloudflare-access/docs/topics.md +71 -0
  109. package/blueprints/edge-cloudflare-access/guide/edge-cloudflare-access.md +180 -0
  110. package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +10 -0
  111. package/blueprints/edge-cloudflare-rate-limiting/README.md +73 -0
  112. package/blueprints/edge-cloudflare-rate-limiting/blueprint.json +174 -0
  113. package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +14 -0
  114. package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +14 -0
  115. package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +14 -0
  116. package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +14 -0
  117. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/event-secrecy.mjs +104 -0
  118. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-presence.mjs +95 -0
  119. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-schema-validate.mjs +130 -0
  120. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/probe-utils.mjs +111 -0
  121. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/real-account-burst-and-429.mjs +104 -0
  122. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-event-secrecy.mjs +5 -0
  123. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-presence.mjs +5 -0
  124. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-schema-validate.mjs +5 -0
  125. package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-real-account-burst-and-429.mjs +5 -0
  126. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-001.json +17 -0
  127. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-002.json +17 -0
  128. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-003.json +17 -0
  129. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-004.json +17 -0
  130. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-005.json +17 -0
  131. package/blueprints/edge-cloudflare-rate-limiting/contributions/schemas/rate-limit-rule.schema.json +67 -0
  132. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +31 -0
  133. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +25 -0
  134. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +26 -0
  135. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36101.json +27 -0
  136. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36102.json +27 -0
  137. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36103.json +27 -0
  138. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36104.json +27 -0
  139. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36105.json +27 -0
  140. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36106.json +27 -0
  141. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36107.json +27 -0
  142. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36108.json +27 -0
  143. package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +71 -0
  144. package/blueprints/edge-cloudflare-rate-limiting/guide/edge-cloudflare-rate-limiting.md +88 -0
  145. package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +13 -0
  146. package/blueprints/edge-cloudflare-tunnel/README.md +257 -0
  147. package/blueprints/edge-cloudflare-tunnel/blueprint.json +168 -0
  148. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +23 -0
  149. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +19 -0
  150. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +19 -0
  151. package/blueprints/edge-cloudflare-tunnel/contributions/probes/aud-presence-check.mjs +114 -0
  152. package/blueprints/edge-cloudflare-tunnel/contributions/probes/cloudflared-config-lint.mjs +80 -0
  153. package/blueprints/edge-cloudflare-tunnel/contributions/probes/manifest-schema-validate.mjs +234 -0
  154. package/blueprints/edge-cloudflare-tunnel/contributions/probes/probe-utils.mjs +231 -0
  155. package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-connector-healthy.mjs +54 -0
  156. package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-tunnel-hostname-routes.mjs +73 -0
  157. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-aud-presence-check.mjs +4 -0
  158. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-cloudflared-config-lint.mjs +4 -0
  159. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-manifest-schema-validate.mjs +4 -0
  160. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-connector-healthy.mjs +4 -0
  161. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-tunnel-hostname-routes.mjs +4 -0
  162. package/blueprints/edge-cloudflare-tunnel/contributions/probes/tunnel-manifest.schema.json +55 -0
  163. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-001.json +18 -0
  164. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-002.json +18 -0
  165. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-003.json +18 -0
  166. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-004.json +18 -0
  167. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-005.json +18 -0
  168. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +26 -0
  169. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +26 -0
  170. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +25 -0
  171. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39101.json +24 -0
  172. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39102.json +24 -0
  173. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39103.json +24 -0
  174. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39104.json +24 -0
  175. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39105.json +24 -0
  176. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39106.json +24 -0
  177. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39107.json +24 -0
  178. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39108.json +24 -0
  179. package/blueprints/edge-cloudflare-tunnel/docs/topics.md +72 -0
  180. package/blueprints/edge-cloudflare-tunnel/guide/edge-cloudflare-tunnel.md +204 -0
  181. package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +20 -0
  182. package/blueprints/edge-cloudflare-turnstile/README.md +95 -0
  183. package/blueprints/edge-cloudflare-turnstile/blueprint.json +161 -0
  184. package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +14 -0
  185. package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +14 -0
  186. package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +14 -0
  187. package/blueprints/edge-cloudflare-turnstile/contributions/probes/event-secrecy.mjs +51 -0
  188. package/blueprints/edge-cloudflare-turnstile/contributions/probes/guard-shape-scan.mjs +48 -0
  189. package/blueprints/edge-cloudflare-turnstile/contributions/probes/probe-utils.mjs +139 -0
  190. package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-event-secrecy.mjs +5 -0
  191. package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-guard-shape-scan.mjs +5 -0
  192. package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-secret-shape-scan.mjs +5 -0
  193. package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-siteverify-fixture.mjs +5 -0
  194. package/blueprints/edge-cloudflare-turnstile/contributions/probes/secret-shape-scan.mjs +77 -0
  195. package/blueprints/edge-cloudflare-turnstile/contributions/probes/siteverify-fixture.mjs +53 -0
  196. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-001.json +17 -0
  197. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-002.json +17 -0
  198. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-003.json +17 -0
  199. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-004.json +17 -0
  200. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-005.json +17 -0
  201. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +26 -0
  202. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +36 -0
  203. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +25 -0
  204. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35101.json +27 -0
  205. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35102.json +27 -0
  206. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35103.json +27 -0
  207. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35104.json +27 -0
  208. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35105.json +36 -0
  209. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35106.json +27 -0
  210. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35107.json +27 -0
  211. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35108.json +27 -0
  212. package/blueprints/edge-cloudflare-turnstile/docs/topics.md +71 -0
  213. package/blueprints/edge-cloudflare-turnstile/guide/edge-cloudflare-turnstile.md +104 -0
  214. package/blueprints/edge-cloudflare-turnstile/probe-packs/edge-cloudflare-turnstile.pack.mjs +146 -0
  215. package/blueprints/email-smtp-resend/docs/topics.md +10 -1
  216. package/blueprints/jobs-background/docs/topics.md +10 -1
  217. package/blueprints/messaging-queue-cloudflare/docs/topics.md +10 -1
  218. package/blueprints/object-storage-s3/docs/topics.md +10 -1
  219. package/blueprints/observability-essentials/docs/topics.md +10 -1
  220. package/blueprints/observability-logging/docs/topics.md +10 -1
  221. package/blueprints/observability-probe-endpoints/docs/topics.md +10 -1
  222. package/blueprints/persistence-data-d1/docs/topics.md +10 -1
  223. package/blueprints/persistence-data-postgres/docs/topics.md +10 -1
  224. package/blueprints/persistence-data-sqlite/docs/topics.md +10 -1
  225. package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +22 -0
  226. package/blueprints/platform-cloudflare-cron-triggers/README.md +117 -0
  227. package/blueprints/platform-cloudflare-cron-triggers/blueprint.json +85 -0
  228. package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract.json +14 -0
  229. package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3302-platform-cloudflare-cron-triggers-dispatcher-mode.json +14 -0
  230. package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3303-platform-cloudflare-cron-triggers-skew-tolerance-default.json +14 -0
  231. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/dispatcher-routing.mjs +64 -0
  232. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/event-secrecy.mjs +100 -0
  233. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/probe-utils.mjs +70 -0
  234. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/real-account-scheduled-smoke.mjs +100 -0
  235. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-dispatcher-routing.mjs +5 -0
  236. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-event-secrecy.mjs +5 -0
  237. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-real-account-scheduled-smoke.mjs +5 -0
  238. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-skew-tolerance.mjs +5 -0
  239. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-wrangler-test-scheduled.mjs +5 -0
  240. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/skew-tolerance.mjs +130 -0
  241. package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/wrangler-test-scheduled.mjs +129 -0
  242. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-001.json +17 -0
  243. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-002.json +17 -0
  244. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-003.json +17 -0
  245. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-004.json +17 -0
  246. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json +22 -0
  247. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json +22 -0
  248. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json +21 -0
  249. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32101.json +25 -0
  250. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32102.json +34 -0
  251. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32103.json +34 -0
  252. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32104.json +34 -0
  253. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32105.json +25 -0
  254. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32106.json +25 -0
  255. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32107.json +25 -0
  256. package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +74 -0
  257. package/blueprints/platform-cloudflare-cron-triggers/guide/platform-cloudflare-cron-triggers.md +119 -0
  258. package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +23 -0
  259. package/blueprints/platform-cloudflare-durable-objects/README.md +200 -0
  260. package/blueprints/platform-cloudflare-durable-objects/blueprint.json +243 -0
  261. package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3401-platform-cloudflare-durable-objects-single-cell-contract.json +14 -0
  262. package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3402-platform-cloudflare-durable-objects-websocket-hub-contract.json +14 -0
  263. package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3403-platform-cloudflare-durable-objects-storage-backend.json +14 -0
  264. package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3404-platform-cloudflare-durable-objects-migrations-shape.json +14 -0
  265. package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3405-platform-cloudflare-durable-objects-hibernation-posture.json +14 -0
  266. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/alarm-fires-once.mjs +63 -0
  267. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/namespace-facade-ready.mjs +60 -0
  268. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/probe-utils.mjs +105 -0
  269. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/real-account-storage-smoke.mjs +58 -0
  270. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-alarm-fires-once.mjs +5 -0
  271. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-namespace-facade-ready.mjs +5 -0
  272. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-real-account-storage-smoke.mjs +5 -0
  273. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-single-cell-concurrent-increment.mjs +5 -0
  274. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-sole-reader-scan.mjs +5 -0
  275. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-storage-round-trip.mjs +5 -0
  276. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-websocket-hub-broadcast.mjs +5 -0
  277. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-wrangler-seam.mjs +5 -0
  278. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/single-cell-concurrent-increment.mjs +56 -0
  279. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/sole-reader-scan.mjs +117 -0
  280. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/storage-round-trip.mjs +87 -0
  281. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/websocket-hub-broadcast.mjs +112 -0
  282. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/wrangler-seam.mjs +257 -0
  283. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-001.json +17 -0
  284. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-002.json +17 -0
  285. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-003.json +17 -0
  286. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-004.json +17 -0
  287. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-005.json +17 -0
  288. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-006.json +17 -0
  289. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-007.json +17 -0
  290. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-008.json +17 -0
  291. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3401-platform-cloudflare-durable-objects-namespace-facade.json +31 -0
  292. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3402-platform-cloudflare-durable-objects-single-cell-shape.json +30 -0
  293. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3403-platform-cloudflare-durable-objects-alarm-handler.json +29 -0
  294. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3404-platform-cloudflare-durable-objects-websocket-hub.json +31 -0
  295. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3405-platform-cloudflare-durable-objects-event-sink.json +24 -0
  296. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33101.json +27 -0
  297. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33102.json +27 -0
  298. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33103.json +27 -0
  299. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33104.json +27 -0
  300. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33105.json +27 -0
  301. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33106.json +27 -0
  302. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33107.json +27 -0
  303. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33108.json +27 -0
  304. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33109.json +27 -0
  305. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33110.json +27 -0
  306. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33111.json +27 -0
  307. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33112.json +27 -0
  308. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33113.json +25 -0
  309. package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +76 -0
  310. package/blueprints/platform-cloudflare-durable-objects/guide/platform-cloudflare-durable-objects.md +237 -0
  311. package/blueprints/platform-cloudflare-kv/CHANGELOG.md +21 -0
  312. package/blueprints/platform-cloudflare-kv/README.md +159 -0
  313. package/blueprints/platform-cloudflare-kv/blueprint.json +87 -0
  314. package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3201-platform-cloudflare-kv-key-value-store-contract.json +14 -0
  315. package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3202-platform-cloudflare-kv-default-cache-ttl.json +14 -0
  316. package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3203-platform-cloudflare-kv-key-naming-convention.json +14 -0
  317. package/blueprints/platform-cloudflare-kv/contributions/probes/cache-aside-hit-then-miss.mjs +82 -0
  318. package/blueprints/platform-cloudflare-kv/contributions/probes/event-secrecy.mjs +102 -0
  319. package/blueprints/platform-cloudflare-kv/contributions/probes/facade-round-trip.mjs +92 -0
  320. package/blueprints/platform-cloudflare-kv/contributions/probes/list-with-prefix.mjs +52 -0
  321. package/blueprints/platform-cloudflare-kv/contributions/probes/probe-utils.mjs +73 -0
  322. package/blueprints/platform-cloudflare-kv/contributions/probes/real-account-eventual-consistency-smoke.mjs +102 -0
  323. package/blueprints/platform-cloudflare-kv/contributions/probes/run-cache-aside-hit-then-miss.mjs +5 -0
  324. package/blueprints/platform-cloudflare-kv/contributions/probes/run-event-secrecy.mjs +5 -0
  325. package/blueprints/platform-cloudflare-kv/contributions/probes/run-facade-round-trip.mjs +5 -0
  326. package/blueprints/platform-cloudflare-kv/contributions/probes/run-list-with-prefix.mjs +5 -0
  327. package/blueprints/platform-cloudflare-kv/contributions/probes/run-real-account-eventual-consistency-smoke.mjs +5 -0
  328. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-001.json +18 -0
  329. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-002.json +18 -0
  330. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-003.json +18 -0
  331. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-004.json +18 -0
  332. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-005.json +18 -0
  333. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3201-platform-cloudflare-kv-facade.json +27 -0
  334. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3202-platform-cloudflare-kv-cache-aside.json +26 -0
  335. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3203-platform-cloudflare-kv-event-sink.json +25 -0
  336. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31101.json +27 -0
  337. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31102.json +27 -0
  338. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31103.json +36 -0
  339. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31104.json +27 -0
  340. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31105.json +27 -0
  341. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31106.json +27 -0
  342. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31107.json +27 -0
  343. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31108.json +27 -0
  344. package/blueprints/platform-cloudflare-kv/docs/topics.md +74 -0
  345. package/blueprints/platform-cloudflare-kv/guide/platform-cloudflare-kv.md +138 -0
  346. package/blueprints/platform-docker-compose-host/CHANGELOG.md +12 -0
  347. package/blueprints/platform-docker-compose-host/README.md +76 -0
  348. package/blueprints/platform-docker-compose-host/blueprint.json +209 -0
  349. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3901-platform-docker-compose-host-contract.json +14 -0
  350. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +14 -0
  351. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +14 -0
  352. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3904-platform-docker-compose-host-log-driver.json +14 -0
  353. package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +108 -0
  354. package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +231 -0
  355. package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +185 -0
  356. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +41 -0
  357. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +36 -0
  358. package/blueprints/platform-docker-compose-host/contributions/probes/run-caddyfile-validate.mjs +5 -0
  359. package/blueprints/platform-docker-compose-host/contributions/probes/run-compose-config-lint.mjs +5 -0
  360. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-minimal-stack-up.mjs +5 -0
  361. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-reload-burst.mjs +5 -0
  362. package/blueprints/platform-docker-compose-host/contributions/probes/run-secrets-as-files-scan.mjs +5 -0
  363. package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +116 -0
  364. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +18 -0
  365. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +18 -0
  366. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +18 -0
  367. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +18 -0
  368. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +18 -0
  369. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +18 -0
  370. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +26 -0
  371. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +26 -0
  372. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +26 -0
  373. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +26 -0
  374. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +24 -0
  375. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +24 -0
  376. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +24 -0
  377. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +24 -0
  378. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +25 -0
  379. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +24 -0
  380. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +24 -0
  381. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +24 -0
  382. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +24 -0
  383. package/blueprints/platform-docker-compose-host/docs/topics.md +71 -0
  384. package/blueprints/platform-docker-compose-host/guide/platform-docker-compose-host.md +94 -0
  385. package/blueprints/security-auth-clerk/docs/topics.md +10 -1
  386. package/blueprints/security-auth-keycloak/docs/topics.md +10 -1
  387. package/blueprints/security-auth-magic-link/docs/topics.md +10 -1
  388. package/blueprints/security-auth-oauth2/docs/topics.md +10 -1
  389. package/blueprints/security-secrets-management/docs/topics.md +10 -1
  390. package/fixtures/canary-manifest.json +9 -9
  391. package/package.json +1 -1
  392. package/rcf/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +13 -0
  393. package/rcf/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +13 -0
  394. package/rcf/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +13 -0
  395. package/rcf/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +13 -0
  396. package/rcf/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +13 -0
  397. package/rcf/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +13 -0
  398. package/rcf/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +13 -0
  399. package/rcf/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +13 -0
  400. package/rcf/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +13 -0
  401. package/rcf/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +13 -0
  402. package/rcf/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +13 -0
  403. package/rcf/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +13 -0
  404. package/rcf/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +13 -0
  405. package/rcf/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +13 -0
  406. package/rcf/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +13 -0
  407. package/rcf/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +13 -0
  408. package/rcf/adrs/adr-3901-platform-docker-compose-host-contract.json +13 -0
  409. package/rcf/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +13 -0
  410. package/rcf/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +13 -0
  411. package/rcf/adrs/adr-3904-platform-docker-compose-host-log-driver.json +13 -0
  412. package/rcf/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +13 -0
  413. package/rcf/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +13 -0
  414. package/rcf/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +13 -0
  415. package/rcf/code-nodes/cn-230.json +13 -0
  416. package/rcf/code-nodes/cn-231.json +14 -0
  417. package/rcf/code-nodes/cn-232.json +13 -0
  418. package/rcf/code-nodes/cn-233.json +14 -0
  419. package/rcf/code-nodes/cn-234.json +13 -0
  420. package/rcf/code-nodes/cn-260.json +21 -0
  421. package/rcf/code-nodes/cn-261.json +14 -0
  422. package/rcf/code-nodes/cn-262.json +18 -0
  423. package/rcf/code-nodes/cn-263.json +12 -0
  424. package/rcf/code-nodes/cn-264.json +13 -0
  425. package/rcf/code-nodes/cn-265.json +15 -0
  426. package/rcf/code-nodes/cn-266.json +12 -0
  427. package/rcf/code-nodes/cn-267.json +12 -0
  428. package/rcf/code-nodes/cn-290.json +21 -0
  429. package/rcf/code-nodes/cn-291.json +12 -0
  430. package/rcf/code-nodes/cn-292.json +13 -0
  431. package/rcf/code-nodes/cn-293.json +13 -0
  432. package/rcf/code-nodes/cn-294.json +13 -0
  433. package/rcf/code-nodes/cn-295.json +12 -0
  434. package/rcf/code-nodes/cn-296.json +12 -0
  435. package/rcf/code-nodes/cn-297.json +12 -0
  436. package/rcf/code-nodes/cn-298.json +12 -0
  437. package/rcf/code-nodes/cn-299.json +12 -0
  438. package/rcf/code-nodes/cn-300.json +12 -0
  439. package/rcf/code-nodes/cn-301.json +14 -0
  440. package/rcf/code-nodes/cn-302.json +12 -0
  441. package/rcf/code-nodes/cn-303.json +12 -0
  442. package/rcf/code-nodes/cn-304.json +21 -0
  443. package/rcf/code-nodes/cn-320.json +20 -0
  444. package/rcf/code-nodes/cn-321.json +14 -0
  445. package/rcf/code-nodes/cn-350.json +19 -0
  446. package/rcf/code-nodes/cn-380.json +19 -0
  447. package/rcf/code-nodes/cn-410.json +20 -0
  448. package/rcf/code-nodes/cn-440.json +20 -0
  449. package/rcf/code-nodes/cn-470.json +19 -0
  450. package/rcf/fbs/fbs-070.json +24 -0
  451. package/rcf/fbs/fbs-080.json +24 -0
  452. package/rcf/fbs/fbs-090.json +24 -0
  453. package/rcf/fbs/fbs-100.json +23 -0
  454. package/rcf/fbs/fbs-101.json +16 -0
  455. package/rcf/fbs/fbs-110.json +23 -0
  456. package/rcf/fbs/fbs-120.json +22 -0
  457. package/rcf/fbs/fbs-130.json +23 -0
  458. package/rcf/fbs/fbs-140.json +23 -0
  459. package/rcf/fbs/fbs-150.json +22 -0
  460. package/rcf/requirements/req-050.json +18 -0
  461. package/rcf/requirements/req-051.json +18 -0
  462. package/rcf/requirements/req-052.json +18 -0
  463. package/rcf/requirements/req-053.json +18 -0
  464. package/rcf/requirements/req-054.json +18 -0
  465. package/rcf/requirements/req-060.json +20 -0
  466. package/rcf/requirements/req-061.json +18 -0
  467. package/rcf/requirements/req-062.json +20 -0
  468. package/rcf/requirements/req-063.json +20 -0
  469. package/rcf/requirements/req-070.json +18 -0
  470. package/rcf/requirements/req-071.json +18 -0
  471. package/rcf/requirements/req-072.json +18 -0
  472. package/rcf/requirements/req-073.json +18 -0
  473. package/rcf/requirements/req-074.json +18 -0
  474. package/rcf/requirements/req-075.json +18 -0
  475. package/rcf/requirements/req-076.json +18 -0
  476. package/rcf/requirements/req-077.json +18 -0
  477. package/rcf/requirements/req-080.json +18 -0
  478. package/rcf/requirements/req-081.json +18 -0
  479. package/rcf/requirements/req-082.json +18 -0
  480. package/rcf/requirements/req-083.json +18 -0
  481. package/rcf/requirements/req-084.json +18 -0
  482. package/rcf/requirements/req-085.json +18 -0
  483. package/rcf/requirements/req-086.json +18 -0
  484. package/rcf/requirements/req-090.json +44 -0
  485. package/rcf/requirements/req-091.json +53 -0
  486. package/rcf/requirements/req-092.json +32 -0
  487. package/rcf/requirements/req-093.json +52 -0
  488. package/rcf/requirements/req-094.json +32 -0
  489. package/rcf/requirements/req-100.json +13 -0
  490. package/rcf/requirements/req-101.json +13 -0
  491. package/rcf/requirements/req-102.json +13 -0
  492. package/rcf/requirements/req-103.json +13 -0
  493. package/rcf/requirements/req-104.json +13 -0
  494. package/rcf/requirements/req-110.json +58 -0
  495. package/rcf/requirements/req-111.json +32 -0
  496. package/rcf/requirements/req-112.json +42 -0
  497. package/rcf/requirements/req-113.json +33 -0
  498. package/rcf/requirements/req-114.json +20 -0
  499. package/rcf/requirements/req-115.json +38 -0
  500. package/rcf/requirements/req-120.json +20 -0
  501. package/rcf/requirements/req-121.json +20 -0
  502. package/rcf/requirements/req-122.json +20 -0
  503. package/rcf/requirements/req-123.json +42 -0
  504. package/rcf/requirements/req-124.json +27 -0
  505. package/rcf/requirements/req-125.json +20 -0
  506. package/rcf/requirements/req-130.json +32 -0
  507. package/rcf/requirements/req-131.json +54 -0
  508. package/rcf/requirements/req-132.json +27 -0
  509. package/rcf/requirements/req-133.json +20 -0
  510. package/rcf/requirements/req-134.json +42 -0
  511. package/rcf/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +15 -0
  512. package/rcf/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +15 -0
  513. package/rcf/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +15 -0
  514. package/rcf/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +15 -0
  515. package/rcf/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +15 -0
  516. package/rcf/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +15 -0
  517. package/rcf/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +15 -0
  518. package/rcf/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +15 -0
  519. package/rcf/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +16 -0
  520. package/rcf/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +15 -0
  521. package/rcf/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +16 -0
  522. package/rcf/tacs/tac-3801-deploy-hetzner-server-provisioner.json +17 -0
  523. package/rcf/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +17 -0
  524. package/rcf/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +17 -0
  525. package/rcf/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +16 -0
  526. package/rcf/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +17 -0
  527. package/rcf/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +17 -0
  528. package/rcf/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +17 -0
  529. package/rcf/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +17 -0
  530. package/rcf/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +17 -0
  531. package/rcf/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +17 -0
  532. package/rcf/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +16 -0
  533. package/rcf/test-suites/ts-052.json +58 -8
  534. package/rcf/test-suites/ts-080.json +22 -0
  535. package/rcf/test-suites/ts-081.json +22 -0
  536. package/rcf/test-suites/ts-082.json +30 -0
  537. package/rcf/test-suites/ts-083.json +22 -0
  538. package/rcf/test-suites/ts-084.json +30 -0
  539. package/rcf/test-suites/ts-085.json +22 -0
  540. package/rcf/test-suites/ts-086.json +22 -0
  541. package/rcf/test-suites/ts-087.json +22 -0
  542. package/rcf/test-suites/ts-090.json +22 -0
  543. package/rcf/test-suites/ts-091.json +22 -0
  544. package/rcf/test-suites/ts-092.json +22 -0
  545. package/rcf/test-suites/ts-093.json +30 -0
  546. package/rcf/test-suites/ts-094.json +30 -0
  547. package/rcf/test-suites/ts-095.json +30 -0
  548. package/rcf/test-suites/ts-096.json +22 -0
  549. package/rcf/test-suites/ts-100.json +22 -0
  550. package/rcf/test-suites/ts-101.json +22 -0
  551. package/rcf/test-suites/ts-102.json +22 -0
  552. package/rcf/test-suites/ts-103.json +22 -0
  553. package/rcf/test-suites/ts-104.json +22 -0
  554. package/rcf/test-suites/ts-105.json +22 -0
  555. package/rcf/test-suites/ts-106.json +22 -0
  556. package/rcf/test-suites/ts-107.json +22 -0
  557. package/rcf/test-suites/ts-108.json +22 -0
  558. package/rcf/test-suites/ts-109.json +22 -0
  559. package/rcf/test-suites/ts-110.json +22 -0
  560. package/rcf/test-suites/ts-111.json +22 -0
  561. package/rcf/test-suites/ts-112.json +22 -0
  562. package/rcf/test-suites/ts-113.json +22 -0
  563. package/rcf/test-suites/ts-114.json +22 -0
  564. package/rcf/test-suites/ts-115.json +22 -0
  565. package/rcf/test-suites/ts-116.json +22 -0
  566. package/rcf/test-suites/ts-117.json +22 -0
  567. package/rcf/test-suites/ts-118.json +22 -0
  568. package/rcf/test-suites/ts-119.json +30 -0
  569. package/rcf/test-suites/ts-120.json +22 -0
  570. package/rcf/test-suites/ts-121.json +22 -0
  571. package/rcf/test-suites/ts-122.json +22 -0
  572. package/rcf/test-suites/ts-123.json +22 -0
  573. package/rcf/test-suites/ts-124.json +22 -0
  574. package/rcf/test-suites/ts-125.json +22 -0
  575. package/rcf/test-suites/ts-126.json +22 -0
  576. package/rcf/test-suites/ts-127.json +22 -0
  577. package/rcf/test-suites/ts-130.json +22 -0
  578. package/rcf/test-suites/ts-131.json +22 -0
  579. package/rcf/test-suites/ts-132.json +22 -0
  580. package/rcf/test-suites/ts-133.json +22 -0
  581. package/rcf/test-suites/ts-134.json +22 -0
  582. package/rcf/test-suites/ts-135.json +22 -0
  583. package/rcf/test-suites/ts-136.json +22 -0
  584. package/rcf/test-suites/ts-137.json +22 -0
  585. package/rcf/test-suites/ts-140.json +86 -0
  586. package/rcf/test-suites/ts-150.json +86 -0
  587. package/rcf/test-suites/ts-160.json +78 -0
  588. package/rcf/user-stories/us-10001.json +23 -0
  589. package/rcf/user-stories/us-10101.json +23 -0
  590. package/rcf/user-stories/us-10201.json +23 -0
  591. package/rcf/user-stories/us-10301.json +23 -0
  592. package/rcf/user-stories/us-10401.json +23 -0
  593. package/rcf/user-stories/us-10601.json +23 -0
  594. package/rcf/user-stories/us-10701.json +23 -0
  595. package/rcf/user-stories/us-10801.json +23 -0
  596. package/rcf/user-stories/us-11001.json +23 -0
  597. package/rcf/user-stories/us-11101.json +23 -0
  598. package/rcf/user-stories/us-11102.json +24 -0
  599. package/rcf/user-stories/us-11201.json +23 -0
  600. package/rcf/user-stories/us-11202.json +23 -0
  601. package/rcf/user-stories/us-11301.json +24 -0
  602. package/rcf/user-stories/us-11401.json +23 -0
  603. package/rcf/user-stories/us-11402.json +23 -0
  604. package/rcf/user-stories/us-11501.json +23 -0
  605. package/rcf/user-stories/us-12001.json +23 -0
  606. package/rcf/user-stories/us-12101.json +23 -0
  607. package/rcf/user-stories/us-12102.json +23 -0
  608. package/rcf/user-stories/us-12201.json +23 -0
  609. package/rcf/user-stories/us-12202.json +24 -0
  610. package/rcf/user-stories/us-12301.json +23 -0
  611. package/rcf/user-stories/us-12401.json +23 -0
  612. package/rcf/user-stories/us-12402.json +23 -0
  613. package/rcf/user-stories/us-12501.json +23 -0
  614. package/rcf/user-stories/us-13001.json +23 -0
  615. package/rcf/user-stories/us-13002.json +23 -0
  616. package/rcf/user-stories/us-13101.json +23 -0
  617. package/rcf/user-stories/us-13102.json +23 -0
  618. package/rcf/user-stories/us-13201.json +23 -0
  619. package/rcf/user-stories/us-13301.json +23 -0
  620. package/rcf/user-stories/us-13302.json +23 -0
  621. package/rcf/user-stories/us-13401.json +23 -0
  622. package/rcf/user-stories/us-5001.json +27 -0
  623. package/rcf/user-stories/us-5002.json +27 -0
  624. package/rcf/user-stories/us-5101.json +36 -0
  625. package/rcf/user-stories/us-5102.json +27 -0
  626. package/rcf/user-stories/us-5201.json +36 -0
  627. package/rcf/user-stories/us-5301.json +27 -0
  628. package/rcf/user-stories/us-5302.json +27 -0
  629. package/rcf/user-stories/us-5401.json +27 -0
  630. package/rcf/user-stories/us-6001.json +27 -0
  631. package/rcf/user-stories/us-6002.json +27 -0
  632. package/rcf/user-stories/us-6003.json +27 -0
  633. package/rcf/user-stories/us-6101.json +36 -0
  634. package/rcf/user-stories/us-6201.json +36 -0
  635. package/rcf/user-stories/us-6301.json +36 -0
  636. package/rcf/user-stories/us-6302.json +27 -0
  637. package/rcf/user-stories/us-7001.json +27 -0
  638. package/rcf/user-stories/us-7002.json +27 -0
  639. package/rcf/user-stories/us-7101.json +27 -0
  640. package/rcf/user-stories/us-7201.json +27 -0
  641. package/rcf/user-stories/us-7301.json +27 -0
  642. package/rcf/user-stories/us-7401.json +27 -0
  643. package/rcf/user-stories/us-7402.json +27 -0
  644. package/rcf/user-stories/us-7501.json +27 -0
  645. package/rcf/user-stories/us-7601.json +27 -0
  646. package/rcf/user-stories/us-7701.json +27 -0
  647. package/rcf/user-stories/us-8001.json +24 -0
  648. package/rcf/user-stories/us-8002.json +24 -0
  649. package/rcf/user-stories/us-8003.json +24 -0
  650. package/rcf/user-stories/us-8101.json +24 -0
  651. package/rcf/user-stories/us-8201.json +24 -0
  652. package/rcf/user-stories/us-8301.json +24 -0
  653. package/rcf/user-stories/us-8401.json +24 -0
  654. package/rcf/user-stories/us-8501.json +24 -0
  655. package/rcf/user-stories/us-8502.json +24 -0
  656. package/rcf/user-stories/us-8601.json +24 -0
  657. package/rcf/user-stories/us-8602.json +24 -0
  658. package/rcf/user-stories/us-9001.json +27 -0
  659. package/rcf/user-stories/us-9002.json +27 -0
  660. package/rcf/user-stories/us-9101.json +27 -0
  661. package/rcf/user-stories/us-9102.json +27 -0
  662. package/rcf/user-stories/us-9201.json +27 -0
  663. package/rcf/user-stories/us-9301.json +27 -0
  664. package/rcf/user-stories/us-9302.json +27 -0
  665. package/rcf/user-stories/us-9401.json +27 -0
  666. package/releases/releases.yaml +21 -1
@@ -0,0 +1,58 @@
1
+ // Probe: real-account throwaway-server provision.
2
+ //
3
+ // anchorAcId: AC-37103-1. accountBound: true.
4
+ //
5
+ // Without CI_HAS_HETZNER_ACCOUNT the probe records
6
+ // accountBoundSkipped: true and the aggregate flips to pass per
7
+ // hetzner-round-7-spec-2026-09-07.md section 3.5.
8
+ //
9
+ // With the env var set the probe:
10
+ // - runs the fixture's provision.mjs against the ci-throwaway manifest;
11
+ // - asserts a new server appears in `hcloud server list --output json`
12
+ // whose id matches the scratch-file-written id;
13
+ // - asserts the fixture's captured hetznerServerProvisioned event
14
+ // carries id, primaryIpv4, location=fsn1, serverType=cx23;
15
+ // - always() calls destroy.mjs so the throwaway server is torn down
16
+ // regardless of verdict.
17
+
18
+ import { accountBoundSkippedResult, FIXTURE_DIR } from './probe-utils.mjs';
19
+ import { resolve } from 'node:path';
20
+
21
+ export const anchorAcId = 'AC-37103-1';
22
+ export const accountBound = true;
23
+
24
+ export default async function runProbe() {
25
+ if (process.env.CI_HAS_HETZNER_ACCOUNT !== 'true') {
26
+ return {
27
+ results: [accountBoundSkippedResult(anchorAcId, 'real-account throwaway-server provision skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise.')],
28
+ };
29
+ }
30
+ const provisionPath = resolve(FIXTURE_DIR, 'provision.mjs');
31
+ const destroyPath = resolve(FIXTURE_DIR, 'destroy.mjs');
32
+ const { provisionThrowawayServer } = await import(provisionPath);
33
+ const { destroyThrowawayServer } = await import(destroyPath);
34
+ let provisioned;
35
+ try {
36
+ provisioned = await provisionThrowawayServer({ runId: process.env.GITHUB_RUN_ID ?? 'local' });
37
+ return {
38
+ results: [{
39
+ anchorAcId,
40
+ verdict: 'pass',
41
+ detail: `throwaway server ${provisioned.id} provisioned; hetznerServerProvisioned event captured; primaryIpv4=${provisioned.primaryIpv4} location=${provisioned.location} serverType=${provisioned.serverType}.`,
42
+ }],
43
+ extra: { serverId: provisioned.id, primaryIpv4: provisioned.primaryIpv4 },
44
+ };
45
+ } catch (err) {
46
+ return {
47
+ results: [{
48
+ anchorAcId,
49
+ verdict: 'fail',
50
+ detail: `provision failed: ${err.message}`,
51
+ }],
52
+ };
53
+ } finally {
54
+ if (provisioned && provisioned.id) {
55
+ try { await destroyThrowawayServer(provisioned); } catch (_) { /* swept by orphan cron */ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,9 @@
1
+ import runProbe from './cloud-init-render-lint.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'template-render',
6
+ image: 'hetzner-throwaway-server fixture (in-process template render)',
7
+ healthy: true,
8
+ };
9
+ runShim('cloud-init-render-lint', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ import runProbe from './hcloud-dry-run-mock.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'facade-round-trip',
6
+ image: 'hetzner-throwaway-server fixture provisioner facade against a mocked hcloud shim',
7
+ healthy: true,
8
+ };
9
+ runShim('hcloud-dry-run-mock', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ import runProbe from './manifest-schema-validate.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'schema-validate',
6
+ image: 'hetzner-throwaway-server fixture manifest directory (draft-07 subset in-process)',
7
+ healthy: true,
8
+ };
9
+ runShim('manifest-schema-validate', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ import runProbe from './real-account-cloud-init-hardened.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'real-account-ssh',
6
+ image: 'Hetzner Cloud throwaway cx23 with cloud-init user-data (ssh baseline checks)',
7
+ healthy: true,
8
+ };
9
+ runShim('real-account-cloud-init-hardened', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ import runProbe from './real-account-snapshot-on-demand.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'real-account-snapshot',
6
+ image: 'Hetzner Cloud throwaway cx23 with snapshot verb via hcloud image create-image',
7
+ healthy: true,
8
+ };
9
+ runShim('real-account-snapshot-on-demand', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ import runProbe from './real-account-throwaway-server-provision.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = {
5
+ kind: 'real-account-throwaway-server',
6
+ image: 'Hetzner Cloud API via hcloud CLI (provision + list + destroy)',
7
+ healthy: true,
8
+ };
9
+ runShim('real-account-throwaway-server-provision', engine, runProbe);
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-001",
3
+ "prdId": "PRD-001",
4
+ "title": "The provisioner facade is the sole reader of the Hetzner API token and opens on boot with provisionerReady",
5
+ "description": "The applying project reaches the Hetzner Cloud API through a single provisioner facade module that is the ONLY module holding a reference to the HETZNER_ACCOUNT_API_KEY secret (or the elicited project-scoped alternative). The facade wraps typed verbs (createServer, applyFirewall, takeSnapshot, listSnapshots, destroyServer) and, when provisioningTool=hcloud (default), shells to the hcloud CLI with `--output json`; when provisioningTool=raw-api it fetches the equivalent Hetzner Cloud REST endpoints per https://docs.hetzner.cloud/. On process boot the facade opens against the token via a bounded ready-check and emits a provisionerReady lifecycle event on the injected event sink with a metadata-only payload {tool, apiHost}. No other module reads the token; the injected event sink never carries the token or user-data bodies.",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-001). Ships as v1.0.0 of deploy-hetzner-server.",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-002",
3
+ "prdId": "PRD-001",
4
+ "title": "The applying project holds server declarations at hetzner/servers/name.json against a shipped JSON Schema",
5
+ "description": "The applying project holds every server declaration as one JSON document under hetzner/servers/<name>.json, matching a shipped draft-07 JSON Schema at blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json. Required fields: name, serverType (cx23, cx33, and other Hetzner shared-cpu shapes), location (fsn1 default per Baz ruling 2026-09-07 09:50Z; also nbg1, hel1, ash, hil), image (ubuntu-24.04 default), sshKeyIds (nonempty array of Hetzner ssh-key references delegated to security-secrets-management), firewallId (an existing firewall or auto-create), networkId (optional private network), cloudInitPath (relative path to the rendered cloud-init user-data), labels (Hetzner tag map that must include role and blueprint), firewallRules (see REQ-004), snapshotCadence (see REQ-005). The schema refuses on missing required fields and on rule-shape violations (see REQ-004).",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-002).",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-003",
3
+ "prdId": "PRD-001",
4
+ "title": "Cloud-init template renders YAML that lands the six hardening baseline blocks on every provisioned server",
5
+ "description": "The blueprint ships a cloud-init user-data template at blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl. Rendering the template against a manifest lands the six baseline blocks named by the estate baseline at operator/knowledge/systems/environments/hetzner-cloud/overview.md Security posture baseline and by the Debian unattended-upgrades wiki: (1) SSH key-only (PasswordAuthentication no via write_files on /etc/ssh/sshd_config.d/hardening.conf), (2) root disabled (PermitRootLogin no via the same file), (3) UFW default-deny incoming with 22, 80, 443 allowed per the manifest firewall shape, (4) DOCKER-USER iptables chain wired to drop non-conforming egress, (5) fail2ban SSH jail, (6) unattended-upgrades on for security updates. A render-lint asserts every block appears in the rendered YAML; a mutation SIMULATE_HARDENING_DRIFT=true removes the unattended-upgrades block and the lint FAILS naming the missing line.",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-003).",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-004",
3
+ "prdId": "PRD-001",
4
+ "title": "Firewall shape: 22 from operator-nominated prefixes, 80/443 open, all other inbound denied, applied at provision time",
5
+ "description": "Every hetzner/servers/name.json manifest carries a firewallRules array with the three-rule minimum shape: (a) an ssh rule permitting inbound TCP on 22 from a nonempty list of source-prefix ranges (the operator-nominated set; the schema refuses on 0.0.0.0/0 in this list), (b) an http rule permitting inbound TCP on 80 from any source, (c) an https rule permitting inbound TCP on 443 from any source, (d) an implicit deny for every other inbound rule. The provisioner applies the rule set to the server at provision time via hcloud firewall create (or reuse) plus hcloud firewall apply-to-resource. A raw-api provisioner posts the equivalent create-firewall and apply-to-resources bodies per https://docs.hetzner.cloud/#firewalls. Manifest schema validation refuses on any rule-set shape that violates (a) through (c).",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-004).",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-005",
3
+ "prdId": "PRD-001",
4
+ "title": "Snapshot cadence elicited (weekly default, daily and off alternatives), snapshot-on-demand fires a tagged snapshot",
5
+ "description": "The applying project elicits a snapshot cadence per ADR-3802 with an enum of weekly (recommended default), daily and off. The value lives on hetzner/servers/name.json as snapshotCadence. When the cadence is non-off, a scheduled snapshot runner in the applying project fires the snapshot verb on the provisioner facade against every server whose cadence matches, and tags each snapshot with the server name and wall-clock time. A snapshot-on-demand verb on the provisioner fires the same shape without a schedule. Under provisioningTool=hcloud the facade shells to hcloud image create-image and tags via hcloud image update; under raw-api it posts to POST /servers/{id}/actions/create_image and PATCH /images/{id}. The hetznerSnapshotTaken lifecycle event carries snapshot id and wall-clock time. Hetzner-managed backups are a separately elicited paid opt-in (approximately 20 percent of monthly server price per https://docs.hetzner.com/cloud/servers/backups-snapshots/overview) and compose with the scheduled snapshot runner.",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-005).",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "deploy-hetzner-server-REQ-006",
3
+ "prdId": "PRD-001",
4
+ "title": "Four lifecycle events fire with metadata-only payloads and no secret ever crosses the sink boundary",
5
+ "description": "The provisioner facade emits four lifecycle events on the injected event sink: provisionerReady (tool, apiHost), hetznerServerProvisioned (id, primaryIpv4, location, serverType, labels), hetznerSnapshotTaken (serverId, snapshotId, wallClockTime), hetznerServerDestroyed (id, wallClockTime). Every payload carries only metadata; no event body carries the HETZNER_ACCOUNT_API_KEY value, an ssh private key, or a rendered user-data body. The event-secrecy check inside the hcloud-dry-run-mock probe accumulates every emitted event body across a full lifecycle run and asserts the token, an ssh private-key marker (BEGIN OPENSSH PRIVATE KEY), and the elicited user-data bytes appear in NO event body; a mutation SIMULATE_EVENT_SECRECY_LEAK=true injects the token into the hetznerServerProvisioned payload and the probe FAILS with a defensive-fake finding naming the leaked field.",
6
+ "category": "functional",
7
+ "domain": "platform",
8
+ "priority": "must",
9
+ "rationale": "Ratified in the Hetzner round 7 spec (2026-09-07 section 5.1 REQ-006).",
10
+ "tags": [
11
+ "blueprint:deploy-hetzner-server",
12
+ "capability:cloudHost"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-08T00:00:00.000Z",
17
+ "updatedAt": "2026-09-08T00:00:00.000Z"
18
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://stravica.ai/rcf-lite/schemas/hetzner-server.schema.json",
4
+ "title": "Hetzner Cloud server manifest file",
5
+ "description": "One server per file under the applying project's hetzner/servers/ directory. Fields track the Hetzner Cloud API server resource shape at https://docs.hetzner.cloud/.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "name",
10
+ "serverType",
11
+ "location",
12
+ "image",
13
+ "sshKeyIds",
14
+ "firewallId",
15
+ "cloudInitPath",
16
+ "labels",
17
+ "firewallRules",
18
+ "snapshotCadence"
19
+ ],
20
+ "properties": {
21
+ "name": {
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "description": "Operator-facing stable server name (kebab-case). Used as the Hetzner server name and prefixed onto snapshot names."
25
+ },
26
+ "serverType": {
27
+ "type": "string",
28
+ "enum": ["cx23", "cx33", "cx43", "cpx11", "cpx21", "cpx31", "cpx41", "cax11", "cax21", "cax31"],
29
+ "description": "Hetzner Cloud shared-vCPU server type. cx23 is the shipped default per the round-7 spec section 5.1."
30
+ },
31
+ "location": {
32
+ "type": "string",
33
+ "enum": ["fsn1", "nbg1", "hel1", "ash", "hil"],
34
+ "description": "Hetzner data centre location. fsn1 is the shipped default per Baz ruling 2026-09-07 09:50Z on the Q2 ratification."
35
+ },
36
+ "image": {
37
+ "type": "string",
38
+ "minLength": 1,
39
+ "description": "Hetzner Cloud base image identifier. ubuntu-24.04 is the shipped default."
40
+ },
41
+ "sshKeyIds": {
42
+ "type": "array",
43
+ "minItems": 1,
44
+ "items": {
45
+ "type": "string",
46
+ "minLength": 1
47
+ },
48
+ "description": "Nonempty array of Hetzner ssh-key references. Delegated to security-secrets-management for the actual key material."
49
+ },
50
+ "networkId": {
51
+ "type": ["string", "null"],
52
+ "description": "Optional Hetzner Cloud private network id. null for no attached private network."
53
+ },
54
+ "firewallId": {
55
+ "type": ["string", "null"],
56
+ "description": "Existing Hetzner Cloud firewall id to reuse; when null the provisioner creates one from firewallRules."
57
+ },
58
+ "cloudInitPath": {
59
+ "type": "string",
60
+ "minLength": 1,
61
+ "description": "Relative path to the rendered cloud-init user-data file. The renderer at src/cloud-init-renderer.mjs consumes contributions/templates/cloud-init.yaml.tmpl and writes the output here."
62
+ },
63
+ "labels": {
64
+ "type": "object",
65
+ "additionalProperties": {
66
+ "type": "string"
67
+ },
68
+ "required": [
69
+ "role",
70
+ "blueprint"
71
+ ],
72
+ "description": "Hetzner tag map. Must include role and blueprint. Under the shared throwaway-server fixture role=rcf-lite-ci-throwaway is required per section 3.3 of the round-7 spec."
73
+ },
74
+ "firewallRules": {
75
+ "type": "array",
76
+ "minItems": 3,
77
+ "description": "The rule shape from TAC-3804. Must include an ssh rule (protocol tcp, port 22, direction in, sourceIps nonempty and NOT containing 0.0.0.0/0), an http rule (protocol tcp, port 80, direction in, sourceIps [\"0.0.0.0/0\", \"::/0\"]) and an https rule (protocol tcp, port 443, direction in, sourceIps [\"0.0.0.0/0\", \"::/0\"]).",
78
+ "items": {
79
+ "type": "object",
80
+ "additionalProperties": false,
81
+ "required": ["name", "protocol", "port", "direction", "sourceIps"],
82
+ "properties": {
83
+ "name": { "type": "string", "enum": ["ssh", "http", "https"] },
84
+ "protocol": { "type": "string", "enum": ["tcp", "udp", "icmp"] },
85
+ "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
86
+ "direction": { "type": "string", "enum": ["in", "out"] },
87
+ "sourceIps": {
88
+ "type": "array",
89
+ "minItems": 1,
90
+ "items": {
91
+ "type": "string",
92
+ "minLength": 1
93
+ }
94
+ }
95
+ }
96
+ }
97
+ },
98
+ "snapshotCadence": {
99
+ "type": "string",
100
+ "enum": ["weekly", "daily", "off"],
101
+ "description": "Snapshot cadence per ADR-3802. weekly is the recommended default."
102
+ },
103
+ "hetznerManagedBackups": {
104
+ "type": "boolean",
105
+ "description": "Optional paid opt-in for Hetzner-managed backups per ADR-3802 (approximately 20 percent of monthly server price)."
106
+ }
107
+ }
108
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "tacId": "TAC-3801-deploy-hetzner-server-provisioner",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Deploy-hetzner-server provisioner facade",
8
+ "purpose": "The single project-side module that dereferences HETZNER_ACCOUNT_API_KEY, wraps typed Hetzner Cloud verbs (createServer, applyFirewall, takeSnapshot, listSnapshots, destroyServer), and emits four lifecycle events to the injected event sink. Under provisioningTool=hcloud the module shells to hcloud CLI with --output json; under raw-api it fetches the equivalent Hetzner Cloud REST endpoints. Consumers never dereference the token; the facade is the one place vendor credentials live.",
9
+ "responsibilities": [
10
+ "Open the facade on boot via a bounded ready-check; be the ONLY module that reads the HETZNER_ACCOUNT_API_KEY value, and export no symbol that leaks it (AC-37101-1).",
11
+ "Expose typed verbs createServer, applyFirewall, takeSnapshot, listSnapshots and destroyServer as returned methods on the factory result; refuse a raw-token passthrough on the public surface (AC-37101-1, AC-37103-1, AC-37108-1).",
12
+ "Emit provisionerReady, hetznerServerProvisioned, hetznerSnapshotTaken and hetznerServerDestroyed on the injected event sink; every payload is metadata-only per REQ-006 (AC-37101-1, AC-37103-1, AC-37108-1, AC-37109-1).",
13
+ "Shell path (hcloud): call hcloud <verb> --output json, JSON.parse the stdout, project the documented fields (id, primaryIpv4, location, serverType, snapshotId) into the returned record (AC-37103-1, AC-37108-1).",
14
+ "Raw-api path: fetch the documented REST endpoints (POST /servers, POST /firewalls, POST /servers/{id}/actions/create_image, DELETE /servers/{id}) with the token in Authorization: Bearer and project the same records (AC-37103-1)."
15
+ ],
16
+ "internalStructure": "One module exporting createProvisionerFacade({ token, tool, apiHost, eventSink, hcloudPath?, fetch? }) returning a ProvisionerFacade whose methods are the typed verbs. The token capture lives at the top of the factory; the shell path passes the token via HCLOUD_TOKEN in the child environment (never on the argv); the raw-api path passes it in the Authorization header. Consumers call the returned methods for the process lifetime; the raw token never crosses the module boundary again.",
17
+ "interfaces": [
18
+ {
19
+ "name": "default export",
20
+ "kind": "factory",
21
+ "summary": "Provisioner facade factory exported from the applied fixture module."
22
+ }
23
+ ],
24
+ "dependencies": [],
25
+ "createdAt": "2026-09-08T00:00:00.000Z",
26
+ "updatedAt": "2026-09-08T00:00:00.000Z"
27
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "tacId": "TAC-3802-deploy-hetzner-server-manifest-schema",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Hetzner server manifest schema",
8
+ "purpose": "One draft-07 JSON Schema declaring the shape of hetzner/servers/name.json in the applying project. Names required fields (name, serverType, location, image, sshKeyIds, firewallId, cloudInitPath, labels, firewallRules, snapshotCadence) and enforces enums (location, serverType, snapshotCadence) and rule-shape invariants (see TAC-3804). Manifest-schema-validate.mjs uses the schema to accept or refuse every fixture manifest.",
9
+ "responsibilities": [
10
+ "Ship a draft-07 JSON Schema for the hetzner-server manifest at contributions/schemas/hetzner-server.schema.json (AC-37102-1).",
11
+ "Refuse on missing required fields with an error message that names the offending field (AC-37102-1).",
12
+ "Refuse on firewall-rule-shape violations (22 opened to 0.0.0.0/0, or 80/443 missing) with an error message that names the offending rule (AC-37106-1).",
13
+ "Enforce snapshotCadence enum {weekly, daily, off} and refuse otherwise (AC-37107-1)."
14
+ ],
15
+ "internalStructure": "One JSON Schema file at blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json; one shipped example manifest under the shared throwaway-server fixture at packages/rcf-lite/test/fixtures/hetzner-throwaway-server/hetzner/servers/ci-throwaway.json.",
16
+ "interfaces": [
17
+ {
18
+ "name": "hetzner-server.schema.json",
19
+ "kind": "jsonSchema",
20
+ "summary": "draft-07 JSON Schema for the Hetzner server manifest."
21
+ }
22
+ ],
23
+ "dependencies": [],
24
+ "createdAt": "2026-09-08T00:00:00.000Z",
25
+ "updatedAt": "2026-09-08T00:00:00.000Z"
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "tacId": "TAC-3803-deploy-hetzner-server-cloud-init-template",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Cloud-init template and render lint",
8
+ "purpose": "One cloud-init user-data template that renders YAML landing the six hardening baseline blocks per ADR-3804 on every provisioned Hetzner server: SSH key-only, root disabled, UFW default-deny incoming, DOCKER-USER iptables chain, fail2ban SSH jail, unattended-upgrades. A local render-lint probe asserts every block appears in the rendered YAML; the SIMULATE_HARDENING_DRIFT mutation removes the unattended-upgrades block and the probe FAILS naming the missing line.",
9
+ "responsibilities": [
10
+ "Ship a cloud-init template at contributions/templates/cloud-init.yaml.tmpl that renders the six baseline blocks (AC-37104-1).",
11
+ "Render deterministically against a manifest via the fixture's cloud-init-renderer.mjs (AC-37104-1).",
12
+ "Cover the SIMULATE_HARDENING_DRIFT mutation with a probe FAILURE that names the missing line (AC-37104-1).",
13
+ "Document the runtime ssh baseline check that the account-bound probe drives against the throwaway server (AC-37105-1)."
14
+ ],
15
+ "internalStructure": "One template file at blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl using {{token}} placeholders substituted by the renderer; one renderer module at packages/rcf-lite/test/fixtures/hetzner-throwaway-server/src/cloud-init-renderer.mjs; one probe cloud-init-render-lint.mjs asserts baseline lines.",
16
+ "interfaces": [
17
+ {
18
+ "name": "cloud-init.yaml.tmpl",
19
+ "kind": "template",
20
+ "summary": "Cloud-init user-data template with the six baseline blocks and templated substitutions."
21
+ }
22
+ ],
23
+ "dependencies": [],
24
+ "createdAt": "2026-09-08T00:00:00.000Z",
25
+ "updatedAt": "2026-09-08T00:00:00.000Z"
26
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "tacId": "TAC-3804-deploy-hetzner-server-firewall-shape",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Hetzner Cloud firewall rule shape",
8
+ "purpose": "One canonical firewall rule shape carried inside the server manifest. Rule set: 22 permitted only from a nonempty list of source-prefix ranges (the operator-nominated set; the schema refuses on 0.0.0.0/0 in this list); 80 and 443 permitted from 0.0.0.0/0 for the reverse proxy; all other inbound denied. The provisioner applies the rule set to the server at provision time via hcloud firewall create + apply-to-resource (or the raw-api equivalent).",
9
+ "responsibilities": [
10
+ "Define the firewall rule shape as a sub-schema in hetzner-server.schema.json (AC-37106-1).",
11
+ "Refuse via manifest-schema-validate on a manifest that opens 22 to 0.0.0.0/0 or drops 80/443 (AC-37106-1).",
12
+ "Enforce that the ssh rule's sourceIps is a nonempty array (AC-37106-1)."
13
+ ],
14
+ "internalStructure": "Rule shape lives inside the same hetzner-server.schema.json used by TAC-3802 (properties.firewallRules array items with protocol, port, direction, sourceIps). The applyFirewall verb on the provisioner facade consumes the parsed rule set.",
15
+ "interfaces": [
16
+ {
17
+ "name": "firewallRules sub-schema",
18
+ "kind": "jsonSchemaFragment",
19
+ "summary": "Rule-shape invariants inside hetzner-server.schema.json."
20
+ }
21
+ ],
22
+ "dependencies": [],
23
+ "createdAt": "2026-09-08T00:00:00.000Z",
24
+ "updatedAt": "2026-09-08T00:00:00.000Z"
25
+ }
@@ -0,0 +1,93 @@
1
+ #cloud-config
2
+ # deploy-hetzner-server v1.0.0 cloud-init user-data template.
3
+ # Six-block hardening baseline per ADR-3804 (Debian unattended-upgrades wiki
4
+ # and the estate baseline at
5
+ # operator/knowledge/systems/environments/hetzner-cloud/overview.md
6
+ # Security posture baseline). Placeholders in {{double-brace}} form are
7
+ # substituted by the fixture's cloud-init-renderer.mjs against the applying
8
+ # manifest.
9
+
10
+ hostname: {{name}}
11
+
12
+ # Block 1: SSH key-only. Password auth disabled at the sshd level too.
13
+ users:
14
+ - name: deploy
15
+ groups: [sudo]
16
+ shell: /bin/bash
17
+ lock_passwd: true
18
+ ssh_authorized_keys:
19
+ {{sshAuthorizedKeysBlock}}
20
+
21
+ # Block 2: root disabled (PermitRootLogin no).
22
+ # Block 1 continued: PasswordAuthentication no.
23
+ write_files:
24
+ - path: /etc/ssh/sshd_config.d/hardening.conf
25
+ permissions: '0644'
26
+ content: |
27
+ # deploy-hetzner-server v1.0.0 hardening (baseline blocks 1 and 2).
28
+ PermitRootLogin no
29
+ PasswordAuthentication no
30
+ KbdInteractiveAuthentication no
31
+ ChallengeResponseAuthentication no
32
+ # Block 4: DOCKER-USER iptables chain drops non-conforming egress.
33
+ - path: /etc/iptables/rules.v4.d/docker-user.rules
34
+ permissions: '0644'
35
+ content: |
36
+ # deploy-hetzner-server v1.0.0 hardening baseline block 4:
37
+ # DOCKER-USER iptables chain wired to drop non-conforming egress.
38
+ *filter
39
+ :DOCKER-USER - [0:0]
40
+ -A DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
41
+ -A DOCKER-USER -j DROP
42
+ COMMIT
43
+ # Block 5: fail2ban SSH jail.
44
+ - path: /etc/fail2ban/jail.d/sshd.conf
45
+ permissions: '0644'
46
+ content: |
47
+ # deploy-hetzner-server v1.0.0 hardening baseline block 5:
48
+ # fail2ban SSH jail on port 22.
49
+ [sshd]
50
+ enabled = true
51
+ port = 22
52
+ maxretry = 5
53
+ findtime = 600
54
+ bantime = 3600
55
+ # Block 6: unattended-upgrades on (security updates).
56
+ - path: /etc/apt/apt.conf.d/50unattended-upgrades
57
+ permissions: '0644'
58
+ content: |
59
+ // deploy-hetzner-server v1.0.0 hardening baseline block 6:
60
+ // unattended-upgrades on for security updates
61
+ // per https://wiki.debian.org/UnattendedUpgrades
62
+ Unattended-Upgrade::Origins-Pattern {
63
+ "origin=Debian,codename=${distro_codename},label=Debian-Security";
64
+ "origin=Ubuntu,archive=${distro_codename}-security";
65
+ };
66
+ Unattended-Upgrade::Automatic-Reboot "false";
67
+ - path: /etc/apt/apt.conf.d/20auto-upgrades
68
+ permissions: '0644'
69
+ content: |
70
+ APT::Periodic::Update-Package-Lists "1";
71
+ APT::Periodic::Unattended-Upgrade "1";
72
+
73
+ # Package install: ufw for block 3, fail2ban for block 5,
74
+ # unattended-upgrades for block 6, iptables-persistent for block 4.
75
+ packages:
76
+ - ufw
77
+ - fail2ban
78
+ - unattended-upgrades
79
+ - iptables-persistent
80
+
81
+ runcmd:
82
+ # Block 3: UFW default-deny incoming, allow 22 80 443.
83
+ - ufw default deny incoming
84
+ - ufw default allow outgoing
85
+ - ufw allow 22/tcp
86
+ - ufw allow 80/tcp
87
+ - ufw allow 443/tcp
88
+ - ufw --force enable
89
+ - systemctl reload ssh || systemctl restart ssh
90
+ - systemctl enable --now fail2ban
91
+ - systemctl enable --now unattended-upgrades
92
+ # Load the DOCKER-USER iptables rules on boot.
93
+ - iptables-restore -n < /etc/iptables/rules.v4.d/docker-user.rules
@@ -0,0 +1,24 @@
1
+ {
2
+ "usId": "deploy-hetzner-server-US-37101",
3
+ "prdId": "PRD-001",
4
+ "reqId": "deploy-hetzner-server-REQ-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "The provisioner opens on boot as the sole token reader and emits provisionerReady",
8
+ "asA": "developer whose project provisions a Hetzner Cloud VM as its cloudHost",
9
+ "iWant": "one provisioner facade module to be the sole reader of HETZNER_ACCOUNT_API_KEY and to emit provisionerReady on boot with a metadata-only payload",
10
+ "soThat": "the token has one auditable seam and the observability sink surfaces boot ordering without ever carrying the secret",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-37101-1",
14
+ "description": "On process boot the provisioner facade opens against the token, and (a) only the provisioner module reads HETZNER_ACCOUNT_API_KEY (grep across the fixture source refuses any other reader), (b) provisionerReady fires on the injected event sink with a payload of exactly {tool, apiHost}.",
15
+ "testable": true,
16
+ "scope": "runtime"
17
+ }
18
+ ],
19
+ "tacIds": [
20
+ "TAC-3801-deploy-hetzner-server-provisioner"
21
+ ],
22
+ "createdAt": "2026-09-08T00:00:00.000Z",
23
+ "updatedAt": "2026-09-08T00:00:00.000Z"
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "usId": "deploy-hetzner-server-US-37102",
3
+ "prdId": "PRD-001",
4
+ "reqId": "deploy-hetzner-server-REQ-002",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "hetzner/servers/name.json manifests validate against the shipped JSON Schema",
8
+ "asA": "developer whose project holds Hetzner server declarations in git",
9
+ "iWant": "every hetzner/servers/name.json file to validate against a shipped draft-07 JSON Schema naming type, location, image, sshKeyIds, firewallId, networkId, cloudInitPath, labels, firewallRules and snapshotCadence",
10
+ "soThat": "the operator has a stable declarative source of truth and manifest defects surface locally before they reach the API",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-37102-1",
14
+ "description": "manifest-schema-validate.mjs asserts every hetzner/servers/*.json under the shared throwaway-server fixture validates against blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json and carries every required field; a mutation SIMULATE_MANIFEST_INVALID=true replaces location with an unknown token and the probe FAILS naming the offending field.",
15
+ "testable": true,
16
+ "scope": "runtime"
17
+ }
18
+ ],
19
+ "tacIds": [
20
+ "TAC-3802-deploy-hetzner-server-manifest-schema"
21
+ ],
22
+ "createdAt": "2026-09-08T00:00:00.000Z",
23
+ "updatedAt": "2026-09-08T00:00:00.000Z"
24
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "usId": "deploy-hetzner-server-US-37103",
3
+ "prdId": "PRD-001",
4
+ "reqId": "deploy-hetzner-server-REQ-002",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Manifest applies: the provisioner creates a matching live server and fires hetznerServerProvisioned",
8
+ "asA": "developer whose project provisions a Hetzner Cloud VM from git-managed manifests",
9
+ "iWant": "applying the provisioner to read each manifest under hetzner/servers/, create a matching live Hetzner Cloud server, and emit hetznerServerProvisioned with id, primaryIpv4, location and serverType",
10
+ "soThat": "the manifest is the source of truth for what actually exists in the project",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-37103-1",
14
+ "description": "The real-account-throwaway-server-provision probe (accountBound: true, skipped without CI_HAS_HETZNER_ACCOUNT) applies the ci-throwaway.json manifest via provision.mjs, asserts (a) hcloud server list --output json shows the new server whose id is written to the fixture scratch file, (b) hetznerServerProvisioned fired with id, primaryIpv4, location=fsn1, serverType=cx23; teardown via destroy.mjs runs regardless of probe verdict.",
15
+ "testable": true,
16
+ "scope": "runtime"
17
+ }
18
+ ],
19
+ "tacIds": [
20
+ "TAC-3801-deploy-hetzner-server-provisioner",
21
+ "TAC-3802-deploy-hetzner-server-manifest-schema"
22
+ ],
23
+ "createdAt": "2026-09-08T00:00:00.000Z",
24
+ "updatedAt": "2026-09-08T00:00:00.000Z"
25
+ }