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,27 @@
1
+ {
2
+ "usId": "edge-cloudflare-rate-limiting-US-36105",
3
+ "prdId": "PRD-001",
4
+ "reqId": "edge-cloudflare-rate-limiting-REQ-005",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Composition with security-auth-magic-link: zone rate rule layers over the per-email application rule",
8
+ "asA": "operator applying both edge-cloudflare-rate-limiting and security-auth-magic-link on the same project",
9
+ "iWant": "the guide to name the ADR-3702 layering explicitly, showing that the zone rule refuses IP-per-URL bursts at the CF edge before they reach the origin and the security-auth-magic-link per-email application rule continues to run on requests that pass the edge gate",
10
+ "soThat": "I understand the composition at apply time rather than discovering that both blueprints operate on separate characteristic sets by trial and error",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-36105-1",
14
+ "description": "The guide contains a section titled Composition with security-auth-magic-link that names ADR-3702 explicitly, states the zone rule characteristic (IP-per-URL) and the application rule characteristic (per-email per-minute) verbatim, and shows a copy-paste example of both blueprints applied on the same project.",
15
+ "given": "the shipped guide at blueprints/edge-cloudflare-rate-limiting/guide/edge-cloudflare-rate-limiting.md",
16
+ "when": "the anatomy test scans the guide for the composition section and ADR-3702 reference",
17
+ "then": "the section heading, ADR-3702 reference, both characteristic strings and the copy-paste example are present",
18
+ "testable": true,
19
+ "scope": "documentation"
20
+ }
21
+ ],
22
+ "tacIds": [
23
+ "TAC-3702-edge-cloudflare-rate-limiting-management-surface-doc"
24
+ ],
25
+ "createdAt": "2026-09-07T22:00:00.000Z",
26
+ "updatedAt": "2026-09-07T22:00:00.000Z"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "usId": "edge-cloudflare-rate-limiting-US-36106",
3
+ "prdId": "PRD-001",
4
+ "reqId": "edge-cloudflare-rate-limiting-REQ-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Manifest schema validates every rule file against the shipped JSON Schema and refuses invalid shapes",
8
+ "asA": "operator on the applying project committing new rate-limit rule files under the elicited manifest directory",
9
+ "iWant": "the shipped JSON Schema to validate every rule file's shape (the seven required fields with the correct types) and the manifest-schema-validate probe to surface any file that violates the shape",
10
+ "soThat": "invalid manifest changes are caught in the fixture probe rather than at operator apply time against a live zone",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-36106-1",
14
+ "description": "Given the shipped rate-limit-rule JSON Schema (blueprints/edge-cloudflare-rate-limiting/contributions/schemas/rate-limit-rule.schema.json, draft-07), the manifest-schema-validate probe reads every manifest file in the fixture manifest directory and validates each against the schema; every valid file passes; a manifest file with a missing threshold field (simulated via SIMULATE_SCHEMA_INVALID=true) fails validation and the probe returns aggregateVerdict: fail with the offending field named in the detail.",
15
+ "given": "the cf-edge fixture with the two committed manifest files and the shipped JSON Schema",
16
+ "when": "the manifest-schema-validate probe validates every manifest file",
17
+ "then": "every valid file passes; the SIMULATE_SCHEMA_INVALID=true switch surfaces the missing threshold field and the aggregate verdict is fail",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ }
21
+ ],
22
+ "tacIds": [
23
+ "TAC-3701-edge-cloudflare-rate-limiting-manifest-schema"
24
+ ],
25
+ "createdAt": "2026-09-07T22:00:00.000Z",
26
+ "updatedAt": "2026-09-07T22:00:00.000Z"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "usId": "edge-cloudflare-rate-limiting-US-36107",
3
+ "prdId": "PRD-001",
4
+ "reqId": "edge-cloudflare-rate-limiting-REQ-004",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Drift-audit records carry metadata-only fields (ruleId, clientIpHash, outcome, timestamp) with no full IP, no body, no user agent",
8
+ "asA": "operator on the applying project reading drift-audit reports and rate-limit event records through the applied logging companion",
9
+ "iWant": "every drift-audit record and every rate-limit event record to carry only metadata-safe fields (ruleId, clientIpHash, outcome, timestamp, plus the drift diff fields where applicable), never a full client IP, never a request body, never a user agent string",
10
+ "soThat": "the audit trail is safe to store, forward and read without additional PII scrubbing at the audit sink",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-36107-1",
14
+ "description": "The event-secrecy probe drives a synthetic drift-audit payload constructed from a fixture rule and a fake live-zone response; every record on the sink carries only {ruleId, clientIpHash, outcome, timestamp} plus (for drift records) a diff array with the schema-safe fields; the probe asserts NO full IP (regex 4-octet dotted quad or v6 group), NO request body key, NO user-agent key; the SIMULATE_EVENT_LEAK_IP=true switch injects a full IP into the drift record and the probe returns aggregateVerdict: fail with the leaked key named in the detail.",
15
+ "given": "the shipped drift-audit runner and a synthetic input pair",
16
+ "when": "the event-secrecy probe drives the runner and inspects the resulting records",
17
+ "then": "every record carries only the metadata-safe fields; SIMULATE_EVENT_LEAK_IP=true surfaces a leaked key and the aggregate verdict is fail",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ }
21
+ ],
22
+ "tacIds": [
23
+ "TAC-3703-edge-cloudflare-rate-limiting-drift-audit-runner"
24
+ ],
25
+ "createdAt": "2026-09-07T22:00:00.000Z",
26
+ "updatedAt": "2026-09-07T22:00:00.000Z"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "usId": "edge-cloudflare-rate-limiting-US-36108",
3
+ "prdId": "PRD-001",
4
+ "reqId": "edge-cloudflare-rate-limiting-REQ-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Manifest-presence probe refuses a missing manifest file and names the missing file in the detail",
8
+ "asA": "operator on the applying project accidentally deleting or moving a manifest file under the elicited manifest directory",
9
+ "iWant": "the manifest-presence probe to surface the missing file at fixture probe time rather than at operator apply time against a live zone",
10
+ "soThat": "a manifest under-population defect is caught in the CI probe rather than lingering until an operator notices a missing rule at the dashboard",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-36108-1",
14
+ "description": "Given the cf-edge fixture with the SIMULATE_MANIFEST_MISSING=true switch, one committed manifest file is treated as absent by the probe; the manifest-presence probe returns aggregateVerdict: fail with the missing file's basename named in the detail; without the switch the probe passes and both manifest files are inspected.",
15
+ "given": "the cf-edge fixture with two committed manifest files and the SIMULATE_MANIFEST_MISSING=true switch",
16
+ "when": "the manifest-presence probe scans the fixture manifest directory",
17
+ "then": "the probe returns aggregateVerdict: fail and the missing file basename is present in the detail",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ }
21
+ ],
22
+ "tacIds": [
23
+ "TAC-3701-edge-cloudflare-rate-limiting-manifest-schema"
24
+ ],
25
+ "createdAt": "2026-09-07T22:00:00.000Z",
26
+ "updatedAt": "2026-09-07T22:00:00.000Z"
27
+ }
@@ -0,0 +1,71 @@
1
+ # edge-cloudflare-rate-limiting blueprint coordination vocabulary
2
+
3
+ This file is the edge-cloudflare-rate-limiting half of the cross-blueprint contract. The Phase 1 conflict detector matches scope:global ADR topics by EXACT string equality, and AC ids are unnamespaced by the 0.4.4 grammar. Any blueprint intended to compose with this one must reuse these exact strings and respect these bands.
4
+
5
+ ## Global ADR topics this blueprint contributes (exact strings)
6
+
7
+ | Topic string | edge-cloudflare-rate-limiting contribution | Origin | Composition note |
8
+ | deploy-hetzner-server | 37101-37899 | 38xx | shipped v1.0.0 | `linuxCloudHostContract`, `snapshotAndBackupCadence` |
9
+ | platform-docker-compose-host | 38101-38899 | 39xx | shipped v1.0.0 | `containerHostContract` |
10
+ | edge-cloudflare-tunnel | 39101-39899 | 40xx | shipped v1.0.0 | `edgeIngressBridge` |
11
+ |---|---|---|---|
12
+ | `edgeThrottleContract` | ADR-3701-edge-cloudflare-rate-limiting-throttle-contract | Minted by this blueprint. Names the wire-shape contract for the project-wide edge throttle; the shipped answer is Cloudflare WAF rate-limiting rules per `https://developers.cloudflare.com/waf/rate-limiting-rules/`. | The one project-wide decision on the edge throttle at the shipped-shape boundary. A future non-Cloudflare sibling (Fastly rate-limits, Vercel Edge Config throttles) would contribute the same topic string with a different answer, forcing a DELIBERATE conflict the operator resolves with a project-level ADR. |
13
+
14
+ The edge-cloudflare-rate-limiting blueprint claims one global topic (minted here, shipped as the Cloudflare WAF rate-limiting rules manifest and drift-audit). ADR-3702 layering, ADR-3703 manifest shape and ADR-3704 drift-audit cadence do not contribute global topics; a composing blueprint that holds an opinion on either authors its own project-level ADR.
15
+
16
+ Rules for new topics: lower camel case, one concept per topic, no version suffixes. A topic names the decision area, not the chosen answer.
17
+
18
+ ## Id number bands (registry bootstrap)
19
+
20
+ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. Rows are recorded at ship, never predicted.
21
+
22
+ | Blueprint | US band | ADR/TAC suffix block | Status | Global topics |
23
+ |---|---|---|---|---|
24
+ | application-spa | 1101-1899 | 2xx | shipped v1.3.0 | `clientRouting`, `theming`, `clientState`, `errorEnvelope`, `authModel` |
25
+ | application-api-rest | 2101-2899 | 3xx | shipped v1.0.0 | `errorEnvelope`, `authModel`, `apiVersioning`, `logging` |
26
+ | security-auth-magic-link | 3101-3899 | 5xx | shipped v1.2.0 | `authModel` |
27
+ | email-smtp-resend | 4101-4899 | 4xx | shipped v1.0.0 | none |
28
+ | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
29
+ | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
30
+ | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
31
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
32
+ | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.1 | `secretsSource` |
33
+ | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
34
+ | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
35
+ | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
36
+ | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.2.0 | `deploymentTarget` |
37
+ | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
38
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
39
+ | observability-logging | 15101-15899 | 16xx | shipped v1.0.0 | `logging` |
40
+ | application-error-handling | 16101-16899 | 17xx | shipped v1.0.0 | `errorHandling` |
41
+ | application-datatable | 17101-17899 | 18xx | shipped v1.0.0 | none |
42
+ | application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
43
+ | application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
44
+ | application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
45
+ | application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
46
+ | application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
47
+ | application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
48
+ | application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
49
+ | application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
50
+ | application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
51
+ | persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
52
+ | object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
53
+ | messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
54
+ | jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
55
+ | platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
56
+ | platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
57
+ | platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
58
+ | edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
59
+ | edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
60
+ | edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
61
+
62
+ US 36101-36108 sit at the LOW end of the 36101-36899 band on purpose (watchpost run-4 lesson). ADR/TAC suffixes for this blueprint use the 3701-3799 block, continuing the shelf pattern.
63
+
64
+ ## Shared expectations for future composing blueprints
65
+
66
+ - Reuse `edgeThrottleContract` exactly as spelled here when your blueprint holds an opinion on the edge throttle contract; contribute your own scope:global ADR on that string and let composition surface the pairing.
67
+ - Consumer blueprints reading the `edgeRateLimit` capability declared on `blueprint.json` per section 6a of `blueprint-authoring.md` obtain the shipped rate-limit surface at apply time via the capability-declaration mechanism.
68
+
69
+ ## Deliberate-conflict statement
70
+
71
+ This blueprint's ADR-3701 on `edgeThrottleContract` is the first shipped answer to a topic that will conflict, by design, with future non-Cloudflare siblings. Applying `edge-cloudflare-rate-limiting` alongside such a sibling would raise a `globalAdrTopic` conflict the operator resolves via one of the four documented resolutions (adopt one, keep the existing one, author a project-level supersede ADR, or `--resolve <topic>=project:<ADR-id>` on the add).
@@ -0,0 +1,88 @@
1
+ # edge-cloudflare-rate-limiting guide
2
+
3
+ Round 6 T-6 of the Cloudflare-first blueprint line. Ships zone-level rate limiting as an edge gate in front of Worker handlers. The rule set is a local manifest the applying project commits, and an operator applies it to the live Cloudflare zone through either a wrangler command flow or the Cloudflare dashboard flow, both walked below.
4
+
5
+ ## Manifest
6
+
7
+ The applying project holds its rate-limit rule set as one JSON file per rule under the elicited `rate-limit-rules-dir` (default `cloudflare/rate-limits/`) per ADR-3703. Every file matches the shipped JSON Schema (`contributions/schemas/rate-limit-rule.schema.json`, draft-07) and carries the seven Cloudflare WAF rate-limiting rules documented fields per `https://developers.cloudflare.com/waf/rate-limiting-rules/`.
8
+
9
+ Example (`cloudflare/rate-limits/public-api-per-ip.json`):
10
+
11
+ ```
12
+ {
13
+ "id": "public-api-per-ip",
14
+ "expression": "(http.request.uri.path matches \"^/api/\")",
15
+ "threshold": 60,
16
+ "period": 60,
17
+ "characteristics": ["ip.src", "cf.colo.id"],
18
+ "action": "block",
19
+ "duration": 60,
20
+ "description": "Per-IP-per-colo throttle on /api/*; the (N+1)th request in 60s is blocked for 60s."
21
+ }
22
+ ```
23
+
24
+ The zone id is elicited (`rate-limit-zone-id`) and stored through the applied `secretsManagement` companion; a manifest file never inlines a zone id or an API token.
25
+
26
+ ## Management surface
27
+
28
+ The blueprint ships no committed script that writes rules to the live zone. The operator applies each rule through one of two documented flows, or both. The elicited `rate-limit-management-surface` value records the choice.
29
+
30
+ ### wrangler flow
31
+
32
+ The wrangler flow uses the Cloudflare API through a hand-run command sequence. The steps for one rule are:
33
+
34
+ 1. Set `CLOUDFLARE_API_TOKEN` (and `CLOUDFLARE_ACCOUNT_ID` for the account scope) in the operator's environment. Store both through the applied `secretsManagement` companion; never commit them to the git tree.
35
+ 2. Load the elicited zone id: `export CF_ZONE_ID=$(cat rcf/blueprints/edge-cloudflare-rate-limiting.applied.json | jq -r .elicits.rateLimitZoneId)` or read it from the applied vault seam.
36
+ 3. Fetch the existing rate-limiting ruleset id for the zone via the wrangler-installed API-fetch helper: `wrangler api curl "/zones/${CF_ZONE_ID}/rulesets?phase=http_ratelimit" --method GET` and note the `id` on the returned ruleset (create one if none exists per the vendor doc).
37
+ 4. For each rule file, `POST` the rule shape to the ruleset's `/rules` endpoint. The rule body is built from the manifest file by mapping each field one-to-one: `expression`, `action`, and a `ratelimit` object carrying `characteristics`, `period`, `requests_per_period` (from `threshold`), and `mitigation_timeout` (from `duration`).
38
+ 5. Verify by listing the ruleset again and confirming every manifest rule appears with the expected fields.
39
+
40
+ The vendor doc `https://developers.cloudflare.com/waf/rate-limiting-rules/` names the endpoint shape verbatim; the wrangler flow is a hand-run reproduction of that shape.
41
+
42
+ ### Cloudflare dashboard flow
43
+
44
+ The dashboard flow applies each rule through the Cloudflare zone dashboard. The steps for one rule are:
45
+
46
+ 1. Open the target zone in the Cloudflare dashboard.
47
+ 2. Navigate to Security -> WAF -> Rate limiting rules.
48
+ 3. Click Create rule; give the rule the manifest file's `id` as the operator-facing name.
49
+ 4. In When incoming requests match, set the Custom filter expression to the manifest `expression` (Edit expression toggle to paste raw).
50
+ 5. In Then take action, set the action to the manifest `action` (Block, Managed challenge, JS challenge or Log). Set the Duration to the manifest `duration` in seconds.
51
+ 6. In With the following properties, set the counting period to the manifest `period` seconds, the requests per period to the manifest `threshold`, and the characteristics to the manifest `characteristics` array (each string mapped to the dashboard's Same request property selectors).
52
+ 7. Save the rule. Repeat for every file in the manifest directory.
53
+
54
+ Both flows produce the same shape on the live zone; the operator picks the flow that fits the project's operating discipline. The elicited `rate-limit-management-surface` records which flow the operator committed to at apply time.
55
+
56
+ ## Composition with security-auth-magic-link
57
+
58
+ Per ADR-3702, when both `edge-cloudflare-rate-limiting` and `security-auth-magic-link` apply on the same project, the zone-level rate rule layers OVER the per-email application rule. The two rules operate on different characteristic sets and are additive:
59
+
60
+ | Rule | Characteristic set | Where it runs |
61
+ | --- | --- | --- |
62
+ | Zone rule (this blueprint) | IP-per-URL (e.g. `ip.src` + `http.request.uri.path`) | Cloudflare edge, before any origin Worker code |
63
+ | Application rule (magic-link) | per-email per-minute | Origin Worker mint-surface handler |
64
+
65
+ Copy-paste example (applying both blueprints in the same project):
66
+
67
+ ```
68
+ rcf define blueprint add ./blueprints/edge-cloudflare-rate-limiting \
69
+ --answer rate-limit-rules-dir=cloudflare/rate-limits \
70
+ --answer rate-limit-zone-id=<vault-ref> \
71
+ --answer rate-limit-management-surface=both \
72
+ --answer rate-limit-drift-audit-cadence=daily
73
+
74
+ rcf define blueprint add ./blueprints/security-auth-magic-link \
75
+ --answer magic-link-mint-rate-limit=5perMinute
76
+ ```
77
+
78
+ The applied recorder records both blueprints so the operator sees the two-rule shape at apply time.
79
+
80
+ ## Drift audit
81
+
82
+ The blueprint ships a scheduled drift-audit runner realisation in the `cf-edge` fixture at `packages/rcf-lite/test/fixtures/cf-edge/src/drift-audit-runner.mjs`. The runner exports `createDriftAuditRunner({env, eventSink, fetch, clock, cadence, manifestLoader})` per TAC-3703 and fetches the live rules on the elicited zone via `https://api.cloudflare.com/client/v4/zones/{zone_id}/rulesets`, diffs field-by-field against the local manifest, and constructs one drift-audit record per mismatched rule with the metadata-only shape `{ruleId, clientIpHash, outcome, timestamp, diff}`. No record carries a full client IP, a request body or a user agent (event-secrecy discipline per REQ-005 and AC-36107-1).
83
+
84
+ The elicited `rate-limit-drift-audit-cadence` per ADR-3704 picks `off` (runner not wired), `daily` (24-hour cadence, `recommendedDefault`), or `hourly`.
85
+
86
+ ## Runtime observable and CI
87
+
88
+ Per spec section 3.1 and ruling 6, the runtime observable for `AC-rateLimiting-overThresholdBlocks` (US-36103/AC-36103-1) is the real-account burst probe. In CI without `CI_HAS_CLOUDFLARE_ACCOUNT` and `CF_RATE_LIMIT_URL`, the probe records `accountBoundSkipped: true` and aggregates to `pass`; this IS the accepted CI verdict. The three local probes (manifest presence, manifest schema validate, event secrecy) always run and always gate the ship.
@@ -0,0 +1,13 @@
1
+ # edge-cloudflare-tunnel CHANGELOG
2
+
3
+ ## 1.0.0 - 2026-09-08
4
+
5
+ Initial release. Round-7 T-3 of the Hetzner spec at `projects/blueprint-library/specs/hetzner-round-7-spec-2026-09-07.md`.
6
+
7
+ - Mints capability `tunnelBridge` and global topic `edgeIngressBridge`.
8
+ - Five REQs, eight USs, three TACs, three ADRs; five Node-only probes.
9
+ - Extends the shared throwaway-Hetzner-server fixture with a cloudflared connector in both runtime shapes (compose-service alongside the T-2 web and caddy services when `containerHost` is applied; systemd-unit for a bare `cloudHost`) and both hostname modes (access-gated when `zeroTrustGate` is applied; public-hostname when absent) plus five `run-<probe>.mjs` delegate shims.
10
+ - manifest-schema-validate carries five fixture-side mutation switches (`SIMULATE_MANIFEST_INVALID_TUNNEL_ID`, `SIMULATE_MANIFEST_CREDENTIALS_INLINE`, `SIMULATE_MANIFEST_MISSING_CATCHALL`, `SIMULATE_ORIGIN_PORT_OPEN`, `SIMULATE_EVENT_SECRECY_LEAK`); cloudflared-config-lint carries `SIMULATE_INGRESS_INVALID` and runs `cloudflared tunnel ingress validate` via the `cloudflare/cloudflared:2026.8.3` container when a local binary is not on PATH; aud-presence-check carries `SIMULATE_AUD_DROP`.
11
+ - Mutation-discipline (T-2 gate ruling carried forward): every `SIMULATE_*` switch lives in the fixture-side delegate shim; the probe modules read only `RCF_LITE_T3_FIXTURE_ROOT` and never branch on being under mutation.
12
+ - Connector-runtime choice elicited via `connector-runtime` (compose-service default when `containerHost` applied; systemd-unit alternative for bare `cloudHost`, per the vendor cloudflared as-a-service local-configuration-file docs); hostname-mode discovered (not elicited) from `appliedCapabilities` via the sidecar per ADR-4003.
13
+ - Consumers: `w-2026-09-06-dave-010` follow-on (make the librarian API and workspace viewer reachable without Mullvad) is the estate consumer; blueprint acceptance never depends on that consumer, and the ops-01 migration mints as its own work item.
@@ -0,0 +1,257 @@
1
+ # edge-cloudflare-tunnel
2
+
3
+ Round-7 T-3 core blueprint on the rcf-lite shelf. Bridges a service on a
4
+ `cloudHost` (bare, systemd shape) or a `containerHost` (compose-service
5
+ shape) to the Cloudflare edge through a Cloudflare Tunnel, with no
6
+ public origin ports. When applied alongside `edge-cloudflare-access`
7
+ (via the `zeroTrustGate` capability) the tunnel binds an Access AUD;
8
+ when applied without it the tunnel serves in public-hostname mode.
9
+
10
+ - Slug: `edge-cloudflare-tunnel`
11
+ - Version: `1.0.0`
12
+ - Category: `edge`
13
+ - Capabilities: `["tunnelBridge"]`
14
+ - Mints global topic: `edgeIngressBridge`
15
+ - Contribution count: 5 REQs, 8 USs, 3 TACs, 3 ADRs, 5 probes
16
+ - Consumers: ops-01 has no consumer today (SSH is the only inbound path). Estate consumer is the follow-on make-the-librarian-API-and-workspace-viewer-reachable-without-Mullvad work that `w-2026-09-06-dave-010` is expected to green-light. Blueprint acceptance never depends on that consumer; the ops-01 migration mints as a separate work item at that point (`w-2026-09-07-dave-004`).
17
+
18
+ ## Five REQs
19
+
20
+ | Id | Contract |
21
+ |---|---|
22
+ | edge-cloudflare-tunnel-REQ-001 | Connector install shape switches on applied `containerHost` (compose-service default; systemd-unit for bare `cloudHost`); `cloudflaredReady` fires on boot with connector id, region and version metadata. |
23
+ | edge-cloudflare-tunnel-REQ-002 | Tunnel manifest schema at `cloudflare/tunnels/<name>.yaml` (uuid tunnel id, `credentialsFile.secretRef` reference, ingress rules with catch-all `http_status:404`). |
24
+ | edge-cloudflare-tunnel-REQ-003 | No public origin ports on the host; T-1 firewall stays closed on 80/443 unless a reverse proxy is applied; manifest refuses ingress rules whose service URL binds to a host public interface. |
25
+ | edge-cloudflare-tunnel-REQ-004 | Access-gated composition: `zeroTrustGate` applied attaches `originRequest.access.aud`; absent omits the block and serves in public-hostname mode. |
26
+ | edge-cloudflare-tunnel-REQ-005 | Credentials-file discipline (host mode 0o400, referenced via `secretRef`, not committed, grep-refuse, no leak in event bodies). |
27
+
28
+ ## Connector runtime shapes
29
+
30
+ The connector runtime is elicited via `connector-runtime` (ADR-4002) with
31
+ `recommendedDefault: compose-service`.
32
+
33
+ - **compose-service** (default when `containerHost` is applied). The
34
+ cloudflared container ships alongside the applying project services on
35
+ the same web-net network. No host ports; restart `unless-stopped`;
36
+ logging driver aligned with the T-2 compose-host log-driver elicit.
37
+ Fixture: `packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/compose-service/`.
38
+ - **systemd-unit** (alternative for a bare `cloudHost`). The cloudflared
39
+ binary is installed via the vendor package per the cloudflared
40
+ as-a-service documented systemd unit and runs as a systemd service
41
+ reading the local configuration file. Fixture:
42
+ `packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/systemd-unit/`.
43
+
44
+ When to reach for which: pick compose-service when the project already
45
+ runs docker compose on the host (natural home, same log driver, same
46
+ restart discipline); pick systemd-unit when the host runs bare and there
47
+ is no compose stack to add a service to (or when the project deliberately
48
+ keeps cloudflared outside the compose lifecycle for boot ordering).
49
+
50
+ ## Tunnel manifest shape
51
+
52
+ The manifest lives at `cloudflare/tunnels/<name>.yaml` under the
53
+ applying project. The shipped JSON schema
54
+ (`contributions/probes/tunnel-manifest.schema.json`) requires:
55
+
56
+ - `tunnel`: uuid-shaped Cloudflare Tunnel id.
57
+ - `credentialsFile.secretRef`: reference into `security-secrets-management`
58
+ (never a literal path or JSON body inline).
59
+ - `ingress`: array of `{ hostname?, service, originRequest? }`. The last
60
+ entry MUST be a catch-all `service: http_status:404`. When the
61
+ Access-gated shape is applied every non-catch-all rule attaches
62
+ `originRequest.access.aud` with the AUD from the sidecar.
63
+
64
+ Example (compose-service, public-hostname mode):
65
+
66
+ ```yaml
67
+ tunnel: 00000000-0000-4000-8000-0000000012ab
68
+ credentialsFile:
69
+ secretRef: hq-estate/CLOUDFLARE_TUNNEL_CREDENTIALS_MY_PROJECT
70
+ ingress:
71
+ - hostname: my-app.example.com
72
+ service: http://web:8080
73
+ - service: http_status:404
74
+ ```
75
+
76
+ Example (Access-gated shape adds one block per non-catch-all rule):
77
+
78
+ ```yaml
79
+ ingress:
80
+ - hostname: my-app.example.com
81
+ service: http://web:8080
82
+ originRequest:
83
+ access:
84
+ aud: AUD-example-cloudflare-team
85
+ teamName: my-team
86
+ required: true
87
+ - service: http_status:404
88
+ ```
89
+
90
+ ## Credentials-file discipline
91
+
92
+ The tunnel credentials JSON file lands on the host at mode 0o400 (owner
93
+ read only). The manifest references it as a `credentialsFile.secretRef`;
94
+ the fixture placeholder at
95
+ `packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/*/credentials/probe.json.example`
96
+ documents the pattern. The credentials file MUST NOT be committed to
97
+ the applying project tree; a grep across the working tree for the
98
+ tunnel id and account tag literals refuses on any tracked file. Every
99
+ `cloudflaredReady`, `tunnelConnectorUp` and `ingressRuleReloaded` event
100
+ body carries metadata only; the event-secrecy scan refuses on a body
101
+ that mentions the credentials literal.
102
+
103
+ Rotate credentials by rewriting the secret pointed to by `secretRef`
104
+ and re-applying; the connector reloads on the next boot cycle.
105
+
106
+ ## Composition point (Access-gated vs public-hostname)
107
+
108
+ The hostname mode is discovered from the applied capability set (not
109
+ elicited; see ADR-4003). The blueprint reads the sidecar at
110
+ `rcf/blueprints/edge-cloudflare-tunnel.applied.json` and inspects
111
+ `appliedCapabilities`.
112
+
113
+ - When `zeroTrustGate` is present (i.e. `edge-cloudflare-access` v1.0.0
114
+ is applied on the same project), every ingress rule attaches
115
+ `originRequest.access.aud` and cloudflared refuses at the edge any
116
+ request without a valid Access JWT for that AUD.
117
+ - When `zeroTrustGate` is absent, the block is omitted and the tunnel
118
+ serves in public-hostname mode (open ingress on the public hostname;
119
+ authorization is whatever the origin service itself carries).
120
+
121
+ The `aud-presence-check` probe refuses when the gated variant drifts to
122
+ omit the AUD block (defensive against silent degradation).
123
+
124
+ Graceful degrade: when Access is not applied (T-4 absent from
125
+ `origin/main` or the applying project simply does not want the gate),
126
+ the blueprint still ships in public-hostname mode. The probe assertion
127
+ runs on both fixture variants so the shape flip is proven on every
128
+ reviewer boot.
129
+
130
+ ## No-public-ports rule
131
+
132
+ The T-1 firewall on a `cloudHost` allows 22 unconditionally and 80/443
133
+ only when a reverse proxy is applied. A project applying only T-1 plus
134
+ T-3 (no reverse proxy) declares zero 80/443 rules; the tunnel is the
135
+ sole path from the edge to the origin. The manifest schema refuses
136
+ ingress rules whose service URL binds to `0.0.0.0`, a non-loopback
137
+ numeric IP, or an unresolvable shape.
138
+
139
+ ## Elicited parameters
140
+
141
+ - `tunnel-name` (string; default `probe`): the Cloudflare Tunnel name
142
+ and the manifest filename under `cloudflare/tunnels/<name>.yaml`.
143
+ - `cloudflare-zone-secret` (string; default `hq-estate/CLOUDFLARE_ZONE_ID`):
144
+ `security-secrets-management` reference to the Cloudflare zone the
145
+ tunnel serves under.
146
+ - `public-hostname-template` (string; default `<service>.<zone>`):
147
+ template for the public hostname, expanded per ingress rule.
148
+ - `ingress-rules` (string; default `[]`): ingress rules array (hostname
149
+ + service URL pairs).
150
+ - `access-aud` (string; default empty): Access AUD tag for the gated
151
+ shape. Presence toggles the gated shape when `zeroTrustGate` is
152
+ applied.
153
+ - `connector-runtime` (enum: `compose-service`, `systemd-unit`; default
154
+ `compose-service`): the connector runtime per ADR-4002.
155
+
156
+ ## Companions
157
+
158
+ - `suggestedCompanions[logging]`: every `cloudflaredReady`,
159
+ `tunnelConnectorUp`, `tunnelConnectorDown`, `ingressRuleReloaded` and
160
+ `accessGateRefused` event writes through the applied logger.
161
+ - `suggestedCompanions[errorHandling]`: a cloudflared exit, a JWT-check
162
+ failure, an ingress-rule schema violation, a hostname-DNS-route API
163
+ refusal constructs an internal error record.
164
+
165
+ `providesRoles: []`.
166
+
167
+ ## Five probes
168
+
169
+ Every probe writes its report envelope to
170
+ `.rcf/reports/blueprints/edge-cloudflare-tunnel/<probe-name>.json`
171
+ under the repo root.
172
+
173
+ - **manifest-schema-validate** (local). Anchors AC-tunnel-manifestSchema,
174
+ AC-tunnel-noPublicOrigin, AC-tunnel-credentialsDiscipline. `accountBound: false`.
175
+ Ajv-free walker over the shipped JSON schema; runs on all four
176
+ variants; refuses on `SIMULATE_MANIFEST_INVALID_TUNNEL_ID`,
177
+ `SIMULATE_MANIFEST_CREDENTIALS_INLINE`, `SIMULATE_MANIFEST_MISSING_CATCHALL`,
178
+ `SIMULATE_ORIGIN_PORT_OPEN`, `SIMULATE_EVENT_SECRECY_LEAK`.
179
+ - **cloudflared-config-lint** (local). Anchors AC-tunnel-hostnameRoutes.
180
+ `accountBound: false`. Runs `cloudflared tunnel --config <path> ingress validate`
181
+ via a local binary or the vendor container image
182
+ `cloudflare/cloudflared:2026.8.3`; refuses on `SIMULATE_INGRESS_INVALID`.
183
+ - **aud-presence-check** (local). Anchors AC-tunnel-accessGated,
184
+ AC-tunnel-accessGatedRefuse. `accountBound: false`. Reads the sidecar
185
+ and the paired manifests; asserts the shape flips correctly; refuses
186
+ on `SIMULATE_AUD_DROP` when the gated fixture drifts to open ingress.
187
+ - **real-account-connector-healthy** (account-bound). Anchors
188
+ AC-tunnel-connectorHealthy. `accountBound: true` on
189
+ `CI_HAS_CLOUDFLARE_ACCOUNT` AND `CI_HAS_HETZNER_ACCOUNT`. Without
190
+ both, records `accountBoundSkipped: true` and the aggregate flips to
191
+ `pass`.
192
+ - **real-account-tunnel-hostname-routes** (account-bound). Anchors
193
+ AC-tunnel-hostnameRoutes (public sub-case) and AC-tunnel-accessGated
194
+ (gated sub-case). `accountBound: true`. The public-hostname sub-case
195
+ runs on `CI_HAS_CLOUDFLARE_ACCOUNT` + `CI_HAS_HETZNER_ACCOUNT`; the
196
+ access-gated sub-case adds `CI_HAS_CLOUDFLARE_ACCESS` per the round-7
197
+ Q4 ratification. Sub-cases skip independently.
198
+
199
+ The delegate shims at
200
+ `packages/rcf-lite/test/fixtures/hetzner-throwaway-server/run-<probe>.mjs`
201
+ read the `SIMULATE_*` env vars and prepare mutated inputs in a scratch
202
+ dir; the probe modules never read a `SIMULATE_` env var and never
203
+ branch on being under mutation.
204
+
205
+ ## Two fixture variants times two hostname modes
206
+
207
+ The fixture lives under
208
+ `packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/`:
209
+
210
+ - `compose-service/compose-fragment.yaml`: the cloudflared compose
211
+ service alongside the T-2 web and caddy services.
212
+ - `systemd-unit/cloudflared.service`: the systemd unit per the vendor
213
+ as-a-service docs.
214
+ - `<runtime>/cloudflare/tunnels/public-hostname.yaml`: manifest without
215
+ the AUD block.
216
+ - `<runtime>/cloudflare/tunnels/access-gated.yaml`: manifest with the
217
+ AUD block on every non-catch-all rule.
218
+ - `<runtime>/credentials/probe.json.example`: placeholder credentials
219
+ documenting the 0o400 mode discipline.
220
+ - `sidecars/access-gated.applied.json`: `appliedCapabilities` includes
221
+ `zeroTrustGate`.
222
+ - `sidecars/public-hostname.applied.json`: `appliedCapabilities`
223
+ excludes `zeroTrustGate`.
224
+
225
+ Reviewer boot (mocked, no account) from the fixture directory:
226
+
227
+ ```
228
+ cd packages/rcf-lite/test/fixtures/hetzner-throwaway-server
229
+ node ./run-tunnel-manifest-schema-validate.mjs && node ./run-cloudflared-config-lint.mjs && node ./run-aud-presence-check.mjs
230
+ ```
231
+
232
+ Reviewer boot (real account, throwaway server): set
233
+ `CI_HAS_CLOUDFLARE_ACCOUNT=true` and `CI_HAS_HETZNER_ACCOUNT=true`
234
+ (and `CI_HAS_CLOUDFLARE_ACCESS=true` for the gated sub-case) with the
235
+ account tokens loaded via `security-secrets-management`, then invoke the
236
+ two `run-real-account-*.mjs` scripts.
237
+
238
+ ## Composition on the shelf
239
+
240
+ Consumes:
241
+ - `platform-docker-compose-host` v1.0.0 (`containerHost` capability) for
242
+ the compose-service runtime path.
243
+ - `deploy-hetzner-server` v1.0.0 (`cloudHost` capability) for the bare
244
+ systemd-unit runtime path.
245
+ - `security-secrets-management` v1.0.1 (`secretsProvider` capability) for
246
+ the tunnel credentials `secretRef`.
247
+ - Optionally `edge-cloudflare-access` v1.0.0 (`zeroTrustGate` capability)
248
+ for the Access-gated shape.
249
+
250
+ Provides:
251
+ - `tunnelBridge` (declared under `capabilities` on `blueprint.json`).
252
+ - New global topic `edgeIngressBridge` on ADR-4001 (scope global).
253
+
254
+ Conflict-by-design with future non-Cloudflare siblings on the
255
+ `edgeIngressBridge` topic: Tailscale Funnel, Fly.io proxy, etc.
256
+ would contribute the same topic string with a different mechanism.
257
+ Round 7 ships only the Cloudflare Tunnel provider.