rcf-lite 0.24.0 → 0.26.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 (313) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/blueprints/application-account-settings/docs/topics.md +4 -1
  3. package/blueprints/application-admin-console/docs/topics.md +4 -1
  4. package/blueprints/application-api-rest/docs/topics.md +4 -1
  5. package/blueprints/application-charts/docs/topics.md +4 -1
  6. package/blueprints/application-dashboard/docs/topics.md +4 -1
  7. package/blueprints/application-datatable/docs/topics.md +4 -1
  8. package/blueprints/application-empty-error-states/docs/topics.md +4 -1
  9. package/blueprints/application-error-handling/docs/topics.md +4 -1
  10. package/blueprints/application-file-upload/docs/topics.md +4 -1
  11. package/blueprints/application-forms-wizard/docs/topics.md +4 -1
  12. package/blueprints/application-notifications-in-app/docs/topics.md +4 -1
  13. package/blueprints/application-onboarding-tour/docs/topics.md +4 -1
  14. package/blueprints/application-spa/docs/topics.md +4 -1
  15. package/blueprints/delivery-ci-workflows/docs/topics.md +4 -1
  16. package/blueprints/deploy-cloudflare-workers/docs/topics.md +4 -1
  17. package/blueprints/deploy-hetzner-server/CHANGELOG.md +55 -0
  18. package/blueprints/deploy-hetzner-server/README.md +202 -0
  19. package/blueprints/deploy-hetzner-server/blueprint.json +233 -0
  20. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +14 -0
  21. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +14 -0
  22. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +20 -0
  23. package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +14 -0
  24. package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +71 -0
  25. package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +164 -0
  26. package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +182 -0
  27. package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +112 -0
  28. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +64 -0
  29. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +60 -0
  30. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +58 -0
  31. package/blueprints/deploy-hetzner-server/contributions/probes/run-cloud-init-render-lint.mjs +9 -0
  32. package/blueprints/deploy-hetzner-server/contributions/probes/run-hcloud-dry-run-mock.mjs +9 -0
  33. package/blueprints/deploy-hetzner-server/contributions/probes/run-manifest-schema-validate.mjs +9 -0
  34. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-cloud-init-hardened.mjs +9 -0
  35. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-snapshot-on-demand.mjs +9 -0
  36. package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-throwaway-server-provision.mjs +9 -0
  37. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-001.json +18 -0
  38. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-002.json +18 -0
  39. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-003.json +18 -0
  40. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-004.json +18 -0
  41. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-005.json +18 -0
  42. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-006.json +18 -0
  43. package/blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json +108 -0
  44. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json +27 -0
  45. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +26 -0
  46. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +26 -0
  47. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +25 -0
  48. package/blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl +113 -0
  49. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37101.json +24 -0
  50. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37102.json +24 -0
  51. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37103.json +25 -0
  52. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37104.json +24 -0
  53. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37105.json +24 -0
  54. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37106.json +25 -0
  55. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37107.json +24 -0
  56. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37108.json +24 -0
  57. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37109.json +24 -0
  58. package/blueprints/deploy-hetzner-server/docs/topics.md +48 -0
  59. package/blueprints/deploy-hetzner-server/guide/deploy-hetzner-server.md +180 -0
  60. package/blueprints/edge-cloudflare-access/docs/topics.md +4 -1
  61. package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +4 -1
  62. package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +23 -0
  63. package/blueprints/edge-cloudflare-tunnel/README.md +257 -0
  64. package/blueprints/edge-cloudflare-tunnel/blueprint.json +168 -0
  65. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +23 -0
  66. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +19 -0
  67. package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +19 -0
  68. package/blueprints/edge-cloudflare-tunnel/contributions/probes/aud-presence-check.mjs +114 -0
  69. package/blueprints/edge-cloudflare-tunnel/contributions/probes/cloudflared-config-lint.mjs +80 -0
  70. package/blueprints/edge-cloudflare-tunnel/contributions/probes/manifest-schema-validate.mjs +237 -0
  71. package/blueprints/edge-cloudflare-tunnel/contributions/probes/probe-utils.mjs +231 -0
  72. package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-connector-healthy.mjs +143 -0
  73. package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-tunnel-hostname-routes.mjs +166 -0
  74. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-aud-presence-check.mjs +4 -0
  75. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-cloudflared-config-lint.mjs +4 -0
  76. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-manifest-schema-validate.mjs +4 -0
  77. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-connector-healthy.mjs +4 -0
  78. package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-tunnel-hostname-routes.mjs +4 -0
  79. package/blueprints/edge-cloudflare-tunnel/contributions/probes/tunnel-manifest.schema.json +55 -0
  80. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-001.json +18 -0
  81. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-002.json +18 -0
  82. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-003.json +18 -0
  83. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-004.json +18 -0
  84. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-005.json +18 -0
  85. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +26 -0
  86. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +26 -0
  87. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +25 -0
  88. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39101.json +24 -0
  89. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39102.json +24 -0
  90. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39103.json +24 -0
  91. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39104.json +24 -0
  92. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39105.json +24 -0
  93. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39106.json +24 -0
  94. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39107.json +24 -0
  95. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39108.json +24 -0
  96. package/blueprints/edge-cloudflare-tunnel/docs/topics.md +72 -0
  97. package/blueprints/edge-cloudflare-tunnel/guide/edge-cloudflare-tunnel.md +204 -0
  98. package/blueprints/edge-cloudflare-turnstile/docs/topics.md +4 -1
  99. package/blueprints/email-smtp-resend/docs/topics.md +4 -1
  100. package/blueprints/jobs-background/docs/topics.md +4 -1
  101. package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +19 -0
  102. package/blueprints/messaging-queue-cloudflare/README.md +2 -2
  103. package/blueprints/messaging-queue-cloudflare/blueprint.json +1 -1
  104. package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +192 -37
  105. package/blueprints/messaging-queue-cloudflare/docs/topics.md +4 -1
  106. package/blueprints/object-storage-s3/CHANGELOG.md +11 -0
  107. package/blueprints/object-storage-s3/README.md +14 -1
  108. package/blueprints/object-storage-s3/blueprint.json +12 -1
  109. package/blueprints/object-storage-s3/contributions/adrs/adr-2905-object-storage-s3-hetzner-object-storage-provider.json +30 -0
  110. package/blueprints/object-storage-s3/contributions/probes/hetzner-object-storage-round-trip.mjs +136 -0
  111. package/blueprints/object-storage-s3/contributions/probes/run-hetzner-object-storage-round-trip.mjs +11 -0
  112. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-101.json +18 -0
  113. package/blueprints/object-storage-s3/contributions/tacs/tac-2904-object-storage-s3-hetzner-endpoint-helper.json +34 -0
  114. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28110.json +25 -0
  115. package/blueprints/object-storage-s3/docs/topics.md +4 -1
  116. package/blueprints/object-storage-s3/guide/object-storage-s3.md +36 -0
  117. package/blueprints/observability-essentials/docs/topics.md +4 -1
  118. package/blueprints/observability-logging/docs/topics.md +4 -1
  119. package/blueprints/observability-probe-endpoints/docs/topics.md +4 -1
  120. package/blueprints/persistence-data-d1/docs/topics.md +4 -1
  121. package/blueprints/persistence-data-postgres/docs/topics.md +4 -1
  122. package/blueprints/persistence-data-sqlite/docs/topics.md +4 -1
  123. package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +4 -1
  124. package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +15 -0
  125. package/blueprints/platform-cloudflare-durable-objects/blueprint.json +1 -1
  126. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/namespace-facade-ready.mjs +3 -3
  127. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/probe-utils.mjs +28 -14
  128. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/real-account-storage-smoke.mjs +132 -26
  129. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/sole-reader-scan.mjs +40 -39
  130. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/storage-round-trip.mjs +26 -16
  131. package/blueprints/platform-cloudflare-durable-objects/contributions/probes/websocket-hub-broadcast.mjs +31 -34
  132. package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +4 -1
  133. package/blueprints/platform-cloudflare-kv/CHANGELOG.md +40 -1
  134. package/blueprints/platform-cloudflare-kv/README.md +41 -13
  135. package/blueprints/platform-cloudflare-kv/blueprint.json +1 -1
  136. package/blueprints/platform-cloudflare-kv/contributions/probes/cache-aside-hit-then-miss.mjs +26 -26
  137. package/blueprints/platform-cloudflare-kv/contributions/probes/event-secrecy.mjs +49 -31
  138. package/blueprints/platform-cloudflare-kv/contributions/probes/facade-round-trip.mjs +58 -16
  139. package/blueprints/platform-cloudflare-kv/contributions/probes/list-with-prefix.mjs +6 -5
  140. package/blueprints/platform-cloudflare-kv/contributions/probes/real-account-eventual-consistency-smoke.mjs +131 -67
  141. package/blueprints/platform-cloudflare-kv/docs/topics.md +4 -1
  142. package/blueprints/platform-docker-compose-host/CHANGELOG.md +12 -0
  143. package/blueprints/platform-docker-compose-host/README.md +76 -0
  144. package/blueprints/platform-docker-compose-host/blueprint.json +209 -0
  145. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3901-platform-docker-compose-host-contract.json +14 -0
  146. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +14 -0
  147. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +14 -0
  148. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3904-platform-docker-compose-host-log-driver.json +14 -0
  149. package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +108 -0
  150. package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +231 -0
  151. package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +185 -0
  152. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +41 -0
  153. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +36 -0
  154. package/blueprints/platform-docker-compose-host/contributions/probes/run-caddyfile-validate.mjs +5 -0
  155. package/blueprints/platform-docker-compose-host/contributions/probes/run-compose-config-lint.mjs +5 -0
  156. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-minimal-stack-up.mjs +5 -0
  157. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-reload-burst.mjs +5 -0
  158. package/blueprints/platform-docker-compose-host/contributions/probes/run-secrets-as-files-scan.mjs +5 -0
  159. package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +116 -0
  160. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +18 -0
  161. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +18 -0
  162. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +18 -0
  163. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +18 -0
  164. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +18 -0
  165. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +18 -0
  166. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +26 -0
  167. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +26 -0
  168. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +26 -0
  169. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +26 -0
  170. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +24 -0
  171. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +24 -0
  172. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +24 -0
  173. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +24 -0
  174. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +25 -0
  175. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +24 -0
  176. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +24 -0
  177. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +24 -0
  178. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +24 -0
  179. package/blueprints/platform-docker-compose-host/docs/topics.md +71 -0
  180. package/blueprints/platform-docker-compose-host/guide/platform-docker-compose-host.md +94 -0
  181. package/blueprints/security-auth-clerk/docs/topics.md +4 -1
  182. package/blueprints/security-auth-keycloak/docs/topics.md +4 -1
  183. package/blueprints/security-auth-magic-link/docs/topics.md +4 -1
  184. package/blueprints/security-auth-oauth2/docs/topics.md +4 -1
  185. package/blueprints/security-secrets-management/docs/topics.md +4 -1
  186. package/fixtures/canary-manifest.json +9 -9
  187. package/guidance/harness-template.md +67 -0
  188. package/guidance/managed/agent-instructions-block.hash +1 -1
  189. package/guidance/managed/agent-instructions-block.md +67 -0
  190. package/package.json +2 -2
  191. package/rcf/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +13 -0
  192. package/rcf/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +13 -0
  193. package/rcf/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +13 -0
  194. package/rcf/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +13 -0
  195. package/rcf/adrs/adr-3901-platform-docker-compose-host-contract.json +13 -0
  196. package/rcf/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +13 -0
  197. package/rcf/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +13 -0
  198. package/rcf/adrs/adr-3904-platform-docker-compose-host-log-driver.json +13 -0
  199. package/rcf/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +13 -0
  200. package/rcf/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +13 -0
  201. package/rcf/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +13 -0
  202. package/rcf/code-nodes/cn-410.json +20 -0
  203. package/rcf/code-nodes/cn-440.json +20 -0
  204. package/rcf/code-nodes/cn-470.json +19 -0
  205. package/rcf/code-nodes/cn-500.json +12 -0
  206. package/rcf/code-nodes/cn-510.json +12 -0
  207. package/rcf/code-nodes/cn-520.json +14 -0
  208. package/rcf/code-nodes/cn-521.json +12 -0
  209. package/rcf/code-nodes/cn-522.json +13 -0
  210. package/rcf/code-nodes/cn-523.json +12 -0
  211. package/rcf/code-nodes/cn-524.json +14 -0
  212. package/rcf/code-nodes/cn-525.json +12 -0
  213. package/rcf/code-nodes/cn-526.json +14 -0
  214. package/rcf/fbs/fbs-130.json +23 -0
  215. package/rcf/fbs/fbs-140.json +23 -0
  216. package/rcf/fbs/fbs-150.json +22 -0
  217. package/rcf/fbs/fbs-160.json +15 -0
  218. package/rcf/fbs/fbs-165.json +15 -0
  219. package/rcf/fbs/fbs-170.json +16 -0
  220. package/rcf/fbs/fbs-171.json +16 -0
  221. package/rcf/fbs/fbs-172.json +15 -0
  222. package/rcf/fbs/fbs-173.json +17 -0
  223. package/rcf/fbs/fbs-174.json +17 -0
  224. package/rcf/requirements/req-110.json +58 -0
  225. package/rcf/requirements/req-111.json +32 -0
  226. package/rcf/requirements/req-112.json +42 -0
  227. package/rcf/requirements/req-113.json +33 -0
  228. package/rcf/requirements/req-114.json +20 -0
  229. package/rcf/requirements/req-115.json +38 -0
  230. package/rcf/requirements/req-120.json +20 -0
  231. package/rcf/requirements/req-121.json +20 -0
  232. package/rcf/requirements/req-122.json +20 -0
  233. package/rcf/requirements/req-123.json +42 -0
  234. package/rcf/requirements/req-124.json +27 -0
  235. package/rcf/requirements/req-125.json +20 -0
  236. package/rcf/requirements/req-130.json +32 -0
  237. package/rcf/requirements/req-131.json +54 -0
  238. package/rcf/requirements/req-132.json +27 -0
  239. package/rcf/requirements/req-133.json +20 -0
  240. package/rcf/requirements/req-134.json +42 -0
  241. package/rcf/requirements/req-140.json +149 -0
  242. package/rcf/requirements/req-145.json +53 -0
  243. package/rcf/requirements/req-150.json +20 -0
  244. package/rcf/requirements/req-151.json +85 -0
  245. package/rcf/requirements/req-152.json +20 -0
  246. package/rcf/requirements/req-153.json +59 -0
  247. package/rcf/requirements/req-154.json +44 -0
  248. package/rcf/tacs/tac-3801-deploy-hetzner-server-provisioner.json +17 -0
  249. package/rcf/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +17 -0
  250. package/rcf/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +17 -0
  251. package/rcf/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +16 -0
  252. package/rcf/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +17 -0
  253. package/rcf/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +17 -0
  254. package/rcf/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +17 -0
  255. package/rcf/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +17 -0
  256. package/rcf/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +17 -0
  257. package/rcf/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +17 -0
  258. package/rcf/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +16 -0
  259. package/rcf/test-suites/ts-071.json +2 -2
  260. package/rcf/test-suites/ts-086.json +2 -2
  261. package/rcf/test-suites/ts-140.json +86 -0
  262. package/rcf/test-suites/ts-150.json +86 -0
  263. package/rcf/test-suites/ts-160.json +78 -0
  264. package/rcf/test-suites/ts-170.json +22 -0
  265. package/rcf/test-suites/ts-175.json +22 -0
  266. package/rcf/test-suites/ts-180.json +30 -0
  267. package/rcf/test-suites/ts-181.json +30 -0
  268. package/rcf/test-suites/ts-182.json +22 -0
  269. package/rcf/test-suites/ts-183.json +38 -0
  270. package/rcf/test-suites/ts-184.json +38 -0
  271. package/rcf/user-stories/us-11001.json +23 -0
  272. package/rcf/user-stories/us-11101.json +23 -0
  273. package/rcf/user-stories/us-11102.json +24 -0
  274. package/rcf/user-stories/us-11201.json +23 -0
  275. package/rcf/user-stories/us-11202.json +23 -0
  276. package/rcf/user-stories/us-11301.json +24 -0
  277. package/rcf/user-stories/us-11401.json +23 -0
  278. package/rcf/user-stories/us-11402.json +23 -0
  279. package/rcf/user-stories/us-11501.json +23 -0
  280. package/rcf/user-stories/us-12001.json +23 -0
  281. package/rcf/user-stories/us-12101.json +23 -0
  282. package/rcf/user-stories/us-12102.json +23 -0
  283. package/rcf/user-stories/us-12201.json +23 -0
  284. package/rcf/user-stories/us-12202.json +24 -0
  285. package/rcf/user-stories/us-12301.json +23 -0
  286. package/rcf/user-stories/us-12401.json +23 -0
  287. package/rcf/user-stories/us-12402.json +23 -0
  288. package/rcf/user-stories/us-12501.json +23 -0
  289. package/rcf/user-stories/us-13001.json +23 -0
  290. package/rcf/user-stories/us-13002.json +23 -0
  291. package/rcf/user-stories/us-13101.json +23 -0
  292. package/rcf/user-stories/us-13102.json +23 -0
  293. package/rcf/user-stories/us-13201.json +23 -0
  294. package/rcf/user-stories/us-13301.json +23 -0
  295. package/rcf/user-stories/us-13302.json +23 -0
  296. package/rcf/user-stories/us-13401.json +23 -0
  297. package/rcf/user-stories/us-14001.json +21 -0
  298. package/rcf/user-stories/us-14501.json +24 -0
  299. package/rcf/user-stories/us-15001.json +26 -0
  300. package/rcf/user-stories/us-15101.json +26 -0
  301. package/rcf/user-stories/us-15201.json +21 -0
  302. package/rcf/user-stories/us-15301.json +31 -0
  303. package/rcf/user-stories/us-15401.json +31 -0
  304. package/releases/releases.yaml +21 -1
  305. package/src/blueprint/apply.js +64 -0
  306. package/src/blueprint/consistency-lint.js +432 -0
  307. package/src/blueprint/disposition-ledger.js +224 -0
  308. package/src/blueprint/dispositions.js +44 -0
  309. package/src/blueprint/index.js +19 -0
  310. package/src/browser-verify/manifest-writer.js +53 -2
  311. package/src/browser-verify/pack-runner.js +18 -0
  312. package/src/cli/blueprint.js +103 -0
  313. package/src/setup/identity-seed.js +18 -0
@@ -0,0 +1,44 @@
1
+ {
2
+ "createdAt": "2026-09-08T12:16:30.083Z",
3
+ "updatedAt": "2026-09-08T12:16:30.218Z",
4
+ "description": "The four Cloudflare-platform blueprints (platform-cloudflare-kv, platform-cloudflare-durable-objects, messaging-queue-cloudflare, edge-cloudflare-tunnel) carry mutation-purity, envelope-hygiene and marker-wording defects surfaced by stage-2 semantic and stage-1 mechanical passes: SIMULATE_ env reads in probe bodies (cache-aside-hit-then-miss, event-secrecy, sole-reader-scan, storage-round-trip, websocket-hub-broadcast); a committed fail envelope at .rcf/reports/blueprints/platform-cloudflare-kv/event-secrecy.json; comments labelling local doubles as fake state / fake WebSocket pair / fake clock in ways the stage-1 marker sweep flagged. This train moves every probe-body SIMULATE_ branch into a fixture-side shim under packages/rcf-lite/test/fixtures/cf-platform/ or .../cf-edge/ (new shim files carry the h2-cf-platform-probe-integrity slug prefix, short form h2-cf acceptable), deletes the committed fail envelope and commits a shipped-code pass envelope in its place, regenerates the other kv envelopes so committed envelopes reflect the re-anchored shipped-code runs, and reworks probe comments to name the local test doubles honestly (or records adjudicated-acceptable with reason in the PR body). No capability change; 0.25.x patch scope.",
5
+ "category": "functional",
6
+ "domain": "functional",
7
+ "priority": "must",
8
+ "reqId": "REQ-154",
9
+ "prdId": "PRD-001",
10
+ "title": "H-2 cross-cutting probe hygiene: SIMULATE_ branches out of probe bodies into fixture shims; no fail envelope committed; probe comments name test doubles honestly",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "webUi",
16
+ "httpApi",
17
+ "persistence"
18
+ ],
19
+ "reason": "keyword-scan",
20
+ "classifiedAt": "2026-09-08T12:16:30.216Z",
21
+ "signals": [
22
+ {
23
+ "source": "description",
24
+ "shape": "persistence",
25
+ "match": "durable"
26
+ },
27
+ {
28
+ "source": "description",
29
+ "shape": "persistence",
30
+ "match": "storage"
31
+ },
32
+ {
33
+ "source": "description",
34
+ "shape": "webUi",
35
+ "match": "form"
36
+ },
37
+ {
38
+ "source": "description",
39
+ "shape": "httpApi",
40
+ "match": "delete"
41
+ }
42
+ ]
43
+ }
44
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:56.835Z",
3
+ "updatedAt": "2026-09-07T23:57:58.678Z",
4
+ "tacId": "TAC-3801-deploy-hetzner-server-provisioner",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "T-1 repo-chain TAC mirror for the shipped blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json contribution. Defines the provisioner Node module that wraps hcloud CLI verbs (create server, apply firewall, take snapshot, list snapshots, destroy server) and, under provisioningTool=raw-api, wraps the equivalent Hetzner Cloud REST endpoints. Sole-reader guarantee: only this module reads the HETZNER_ACCOUNT_API_KEY via security-secrets-management (or the project-scoped alternative). Anchors AC-11001-1 (repo chain).",
10
+ "responsibilities": [
11
+ "Wrap hcloud CLI verbs (create server, apply firewall, take snapshot, list snapshots, destroy server) and the raw Hetzner Cloud REST endpoints behind one facade (AC-11001-1, AC-11102-1, AC-11402-1).",
12
+ "Be the sole reader of HETZNER_ACCOUNT_API_KEY via security-secrets-management; every other module reads from the facade (AC-11001-1).",
13
+ "Emit provisionerReady, hetznerServerProvisioned, hetznerSnapshotTaken and hetznerServerDestroyed with metadata-only payloads (AC-11001-1, AC-11501-1)."
14
+ ],
15
+ "name": "deploy-hetzner-server provisioner module: sole reader of the Hetzner API token, hcloud shell path and raw-api fork",
16
+ "internalStructure": "One module blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json plus the provisioner facade proto shipped in the fixture (packages/rcf-lite/test/fixtures/hetzner-throwaway-server/src/provisioner-facade.mjs) reading the token from a single seam and firing provisionerReady on ready()."
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:57.022Z",
3
+ "updatedAt": "2026-09-07T23:57:58.866Z",
4
+ "tacId": "TAC-3802-deploy-hetzner-server-manifest-schema",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "T-1 repo-chain TAC mirror for the shipped blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json contribution. Defines the JSON Schema shape for the Hetzner server manifest under hetzner/servers/<name>.json: type, location, image, sshKeyIds, firewallId, networkId, cloudInitPath, labels, snapshotCadence. Anchors AC-11101-1 and AC-11102-1 (repo chain).",
10
+ "responsibilities": [
11
+ "Ship a draft-07 JSON Schema for the hetzner-server manifest (AC-11101-1, AC-11301-1, AC-11401-1).",
12
+ "Refuse on required-field violations (missing type, location, image, sshKeyIds, firewallId, cloudInitPath, labels or snapshotCadence).",
13
+ "Refuse on firewall-rule-shape violations (22 opened to 0.0.0.0/0, or 80/443 missing) (AC-11301-1)."
14
+ ],
15
+ "name": "deploy-hetzner-server server manifest schema and file layout at hetzner/servers/*.json",
16
+ "internalStructure": "One draft-07 JSON Schema at blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json and one shipped example manifest under the shared throwaway-server fixture (packages/rcf-lite/test/fixtures/hetzner-throwaway-server/hetzner/servers/ci-throwaway.json)."
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:57.210Z",
3
+ "updatedAt": "2026-09-07T23:57:59.054Z",
4
+ "tacId": "TAC-3803-deploy-hetzner-server-cloud-init-template",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "T-1 repo-chain TAC mirror for the shipped blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json contribution. Defines the cloud-init user-data template landing the six hardening baseline blocks: SSH key-only, root disabled, UFW default-deny incoming, DOCKER-USER iptables chain, fail2ban SSH jail, unattended-upgrades. Local render-lint asserts every block appears in the rendered YAML. Anchors AC-11201-1 and AC-11202-1 (repo chain).",
10
+ "responsibilities": [
11
+ "Ship a cloud-init user-data template that renders the six hardening baseline blocks (AC-11201-1, AC-11202-1).",
12
+ "Provide the render-lint check that asserts each block appears in the rendered YAML (AC-11201-1).",
13
+ "Cover the SIMULATE_HARDENING_DRIFT mutation with a probe FAILURE that names the missing line (AC-11201-1)."
14
+ ],
15
+ "name": "deploy-hetzner-server cloud-init template with the six hardening baseline blocks and render lint",
16
+ "internalStructure": "One template file at blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl and one render module at packages/rcf-lite/test/fixtures/hetzner-throwaway-server/src/cloud-init-renderer.mjs; the render-lint probe consumes the rendered output."
17
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:57.397Z",
3
+ "updatedAt": "2026-09-07T23:57:59.243Z",
4
+ "tacId": "TAC-3804-deploy-hetzner-server-firewall-shape",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "T-1 repo-chain TAC mirror for the shipped blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json contribution. Defines the Hetzner Cloud firewall rule shape carried inside the server manifest: 22 permitted only from an operator-nominated set of source-prefix ranges; 80/443 permitted from 0.0.0.0/0 for the reverse proxy; all other inbound denied. Manifest schema refuses on a rule set that opens 22 to 0.0.0.0/0 or drops 80/443. Anchors AC-11301-1 (repo chain).",
10
+ "responsibilities": [
11
+ "Define the firewall rule shape inside the manifest: 22 permitted only from a nonempty list of source-prefix ranges; 80 and 443 permitted; all other inbound denied (AC-11301-1).",
12
+ "Refuse (via manifest-schema-validate) on a manifest that opens 22 to 0.0.0.0/0 or drops 80/443."
13
+ ],
14
+ "name": "deploy-hetzner-server firewall rule shape: 22 from operator-nominated prefixes, 80/443 open, deny all else, applied at provision time",
15
+ "internalStructure": "Rule shape carried inside the same hetzner-server.schema.json used by TAC-3802; the applyFirewall verb on the provisioner facade consumes the parsed rule set."
16
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:20.942Z",
3
+ "updatedAt": "2026-09-08T01:44:10.970Z",
4
+ "tacId": "TAC-3901-platform-docker-compose-host-compose-layout",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The applying project ships one compose.yaml at the repo root whose services key names every container the stack runs. Every entry is one image running one container; networks and volumes are top-level named entries; a colocated .env carries non-secret configuration values (never inline). The container host reads compose.yaml as the runtime topology source and refuses to bring the stack up on layout drift.",
10
+ "responsibilities": [
11
+ "Serve compose.yaml at the repo root as the sole topology surface (AC-12001-1, AC-12202-1).",
12
+ "Guarantee service-per-container: each entry under services: runs one image (AC-12001-1).",
13
+ "Declare all networks and volumes as top-level named entries: no bare defaults (AC-12001-1).",
14
+ "Bind non-secret configuration through a colocated .env: no inline literals (AC-12001-1)."
15
+ ],
16
+ "name": "T-2 platform-docker-compose-host compose layout"
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:21.128Z",
3
+ "updatedAt": "2026-09-08T01:44:11.343Z",
4
+ "tacId": "TAC-3902-platform-docker-compose-host-secrets-mount",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The compose file declares each secret under its top-level secrets: key with a file: source. Services reference secrets through their service-level secrets: array so docker mounts them as files at 0o400 inside the container. When security-secrets-management is applied, the source path resolves through that facade; when it is not, the guide names a file-based fallback. No plaintext secret literal appears anywhere in compose.yaml or a referenced service config (grep-refuse).",
10
+ "responsibilities": [
11
+ "Declare every secret through a compose secrets: file mount (AC-12101-1, AC-12102-1).",
12
+ "Refuse a plaintext secret literal anywhere in compose.yaml (AC-12102-1).",
13
+ "Mount each secret file at 0o400 inside the container (AC-12101-1).",
14
+ "Bind to security-secrets-management when applied; document the file-based fallback (AC-12101-1)."
15
+ ],
16
+ "name": "T-2 platform-docker-compose-host secrets mount"
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:21.313Z",
3
+ "updatedAt": "2026-09-08T01:44:11.716Z",
4
+ "tacId": "TAC-3903-platform-docker-compose-host-healthcheck-lint",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "A lint pass runs before docker compose up. It asserts every HTTP-terminating service declares a healthcheck: block; every service declares a restart: policy whose value is one of unless-stopped or on-failure; every service declares a logging: driver: entry whose value is one of journald or loki. The lint refuses on any missing or unclassified line, naming the service and the offending field.",
10
+ "responsibilities": [
11
+ "Assert every HTTP-terminating service declares a healthcheck: block (AC-12201-1).",
12
+ "Assert every service declares a restart policy in the allowed set (AC-12301-1).",
13
+ "Assert every service declares a logging driver in the allowed set (AC-12501-1).",
14
+ "Refuse on missing or unclassified fields, naming the service (AC-12201-1, AC-12301-1, AC-12501-1)."
15
+ ],
16
+ "name": "T-2 platform-docker-compose-host healthcheck and lifecycle lint"
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:21.500Z",
3
+ "updatedAt": "2026-09-08T01:44:12.088Z",
4
+ "tacId": "TAC-3904-platform-docker-compose-host-reverse-proxy-artefact",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The reverse-proxy config file (caddy/Caddyfile when reverseProxy=caddy, traefik/traefik.yaml when reverseProxy=traefik) lives as a first-class checked-in artefact under the applying repo. The compose file bind-mounts the artefact read-only into the proxy service. The gate runs the vendor validator against the artefact and refuses on an invalid directive. Under the reload verb (docker compose exec caddy caddy reload or the Traefik equivalent), a burst against the proxy inside the elicited window sees no non-2xx and no dropped connection.",
10
+ "responsibilities": [
11
+ "Ship the reverse-proxy config as a checked-in artefact bind-mounted into the proxy (AC-12401-1).",
12
+ "Validate the artefact with the vendor validator at gate time (AC-12401-1).",
13
+ "Prove zero-downtime reload with a real-account burst (AC-12402-1).",
14
+ "Name the reload verb per proxy in the guide and the fixture README (AC-12401-1, AC-12402-1)."
15
+ ],
16
+ "name": "T-2 platform-docker-compose-host reverse-proxy artefact"
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:08.838Z",
3
+ "updatedAt": "2026-09-08T03:23:08.838Z",
4
+ "tacId": "TAC-4001-edge-cloudflare-tunnel-connector-shape",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The cloudflared connector installs in one of two runtime shapes as selected by ADR-4002 from the applied capability set. When containerHost is applied (T-2 platform-docker-compose-host on top of T-1 deploy-hetzner-server) the connector ships as a compose service alongside the applying project services on the same web-net network with no host ports and a healthcheck. When the host runs bare (only T-1 applied) the connector ships as a systemd unit per the vendor local-configuration-file docs. Either shape emits cloudflaredReady on boot with connector id, region and version metadata (metadata only).",
10
+ "responsibilities": [
11
+ "Ship the compose-service variant under packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/compose-service/ (AC-13001-1).",
12
+ "Ship the systemd-unit variant under packages/rcf-lite/test/fixtures/hetzner-throwaway-server/cloudflared/systemd-unit/ (AC-13001-1).",
13
+ "Emit cloudflaredReady on boot with connector id, region and version metadata (AC-13002-1).",
14
+ "Never expose an origin port on the host firewall (AC-13201-1)."
15
+ ],
16
+ "name": "edge-cloudflare-tunnel TAC"
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:09.027Z",
3
+ "updatedAt": "2026-09-08T03:23:09.027Z",
4
+ "tacId": "TAC-4002-edge-cloudflare-tunnel-manifest-schema",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The tunnel manifest at cloudflare/tunnels/<name>.yaml under the applying project is the sole runtime source of truth for what the cloudflared connector serves. The shipped JSON schema requires a uuid-shaped tunnel id, a secretRef credentials reference (never a literal path or JSON body inline), and an ingress rules array whose last entry is a catch-all rule returning http_status 404. The schema refuses ingress rules whose service URL binds to a host public interface (only internal addresses reachable through the compose network or a loopback interface are allowed).",
10
+ "responsibilities": [
11
+ "Ship the JSON schema at blueprints/edge-cloudflare-tunnel/contributions/probes/tunnel-manifest.schema.json (AC-13101-1).",
12
+ "Validate the fixture manifests at cloudflared/*/cloudflare/tunnels/probe.yaml on every reviewer boot (AC-13101-1, AC-13102-1).",
13
+ "Refuse ingress rules that bind to a host public port (AC-13201-1).",
14
+ "Refuse a manifest whose credentials reference is not a secretRef (AC-13101-1, AC-13401-1)."
15
+ ],
16
+ "name": "edge-cloudflare-tunnel TAC"
17
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:09.218Z",
3
+ "updatedAt": "2026-09-08T03:23:09.218Z",
4
+ "tacId": "TAC-4003-edge-cloudflare-tunnel-access-binding",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "draft",
9
+ "purpose": "The blueprint reads the applying project sidecar rcf/blueprints/edge-cloudflare-tunnel.applied.json at apply time and inspects appliedCapabilities. When zeroTrustGate is present every ingress rule attaches an originRequest.access.aud block naming the Access AUD; when absent the block is omitted and the tunnel serves in public-hostname mode. The shape is a pure function of the sidecar and never silently degrades to open ingress.",
10
+ "responsibilities": [
11
+ "Ship the aud-presence-check probe module (AC-13301-1, AC-13302-1).",
12
+ "Ship both fixture variants (access-gated and public-hostname) under cloudflared/*/access-gated and cloudflared/*/public-hostname (AC-13301-1).",
13
+ "Refuse when the gated variant drifts to open ingress (AC-13302-1)."
14
+ ],
15
+ "name": "edge-cloudflare-tunnel TAC"
16
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "createdAt": "2026-09-06T17:50:13.712Z",
3
- "updatedAt": "2026-09-06T17:51:32.845Z",
3
+ "updatedAt": "2026-09-08T09:26:29.965Z",
4
4
  "purpose": "Cover AC-4101-1..6 via unit tests over the shipped object-storage-s3 blueprint shape (contribution count, capabilities, suggestedCompanions, ADR standardsTraceClause), applies-clean-with-secrets and refuses-without behaviour, six Node-only probe module contract with anchorAcId cross-check, induced-failure switch documentation on the fixture README, and shelf-doc consistency (section 6a table row for objectStorage, shelf-wide docs/topics.md row for object-storage-s3 at 28101-28899 / 29xx).",
5
5
  "testLevel": "unit",
6
6
  "acIds": [
@@ -20,7 +20,7 @@
20
20
  "acId": "AC-4101-1",
21
21
  "description": "Cover AC-4101-1 via anatomy test",
22
22
  "status": "pending",
23
- "testPointer": "test/blueprint/object-storage-s3-anatomy.test.js::blueprint.json declares 21 contributions with capabilities objectStorage, suggestedCompanions logging and errorHandling, and standardsTraceClause on every ADR entry (TC-071-blueprint-json-shape)"
23
+ "testPointer": "test/blueprint/object-storage-s3-anatomy.test.js::blueprint.json declares 25 contributions at v1.1.0 with capabilities objectStorage, suggestedCompanions logging and errorHandling, and standardsTraceClause on every ADR entry including the Hetzner Object Storage provider entry (TC-071-blueprint-json-shape)"
24
24
  },
25
25
  {
26
26
  "id": "TC-071-applies-clean-with-secrets",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "createdAt": "2026-09-07T10:20:32.919Z",
3
- "updatedAt": "2026-09-07T10:21:02.065Z",
3
+ "updatedAt": "2026-09-08T15:28:06.407Z",
4
4
  "purpose": "Cover AC-5302-1 via event-secrecy probe with two-layer assertions and a mutation-run under SIMULATE_PII_LEAK",
5
5
  "testLevel": "unit",
6
6
  "acIds": [
@@ -15,7 +15,7 @@
15
15
  "acId": "AC-5302-1",
16
16
  "description": "Cover AC-5302-1 via event-secrecy probe: no body bytes / PII / user id reach the sink even under a mutation-run",
17
17
  "status": "pending",
18
- "testPointer": "test/blueprint/platform-cloudflare-kv-anatomy.test.js::event-secrecy probe passes on PII fixture and fails under SIMULATE_PII_LEAK (TC-086-event-secrecy)"
18
+ "testPointer": "test/blueprint/platform-cloudflare-kv-anatomy.test.js::event-secrecy probe passes on PII fixture and fails under fixture-side SIMULATE_PII_LEAK (TC-086-event-secrecy)"
19
19
  }
20
20
  ],
21
21
  "status": "draft"
@@ -0,0 +1,86 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:57:26.071Z",
3
+ "updatedAt": "2026-09-07T23:58:51.258Z",
4
+ "purpose": "Cover the T-1 chain ACs via the shipped anatomy test at test/blueprint/deploy-hetzner-server-anatomy.test.js and via the six blueprint probes driven from the shared throwaway-server fixture",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-11001-1",
8
+ "AC-11101-1",
9
+ "AC-11102-1",
10
+ "AC-11201-1",
11
+ "AC-11202-1",
12
+ "AC-11301-1",
13
+ "AC-11401-1",
14
+ "AC-11402-1",
15
+ "AC-11501-1"
16
+ ],
17
+ "id": "TS-140",
18
+ "usId": "US-11001",
19
+ "title": "T-1 hetzner-server anatomy proof: probe modules and mocked fixture assertions",
20
+ "testCases": [
21
+ {
22
+ "id": "TC-140-provisioner-boot-and-sole-reader",
23
+ "acId": "AC-11001-1",
24
+ "description": "Cover AC-11001-1 via anatomy test: provisioner facade boot emits provisionerReady with metadata-only payload and only the facade reads the token",
25
+ "status": "pending",
26
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11001-1 provisioner boot and sole reader (TC-140)"
27
+ },
28
+ {
29
+ "id": "TC-140-manifest-schema-shape-valid",
30
+ "acId": "AC-11101-1",
31
+ "description": "Cover AC-11101-1 via anatomy test: hetzner-server.schema.json validates the fixture manifests",
32
+ "status": "pending",
33
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11101-1 manifest schema shape valid (TC-140-manifest-schema-shape-valid)"
34
+ },
35
+ {
36
+ "id": "TC-140-manifest-applies-mocked-provision",
37
+ "acId": "AC-11102-1",
38
+ "description": "Cover AC-11102-1 via anatomy test: mocked hcloud shell path returns id, primaryIpv4, location, serverType and hetznerServerProvisioned fires",
39
+ "status": "pending",
40
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11102-1 manifest applies to mocked provision (TC-140-manifest-applies-mocked-provision)"
41
+ },
42
+ {
43
+ "id": "TC-140-cloud-init-render-baseline-present",
44
+ "acId": "AC-11201-1",
45
+ "description": "Cover AC-11201-1 via anatomy test: rendered cloud-init YAML carries the six baseline blocks",
46
+ "status": "pending",
47
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11201-1 cloud-init render baseline present (TC-140-cloud-init-render-baseline-present)"
48
+ },
49
+ {
50
+ "id": "TC-140-cloud-init-hardened-account-bound-probe",
51
+ "acId": "AC-11202-1",
52
+ "description": "Cover AC-11202-1 via anatomy test: probe module manifest declares accountBound true and the fixture readme documents the ssh baseline checks",
53
+ "status": "pending",
54
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11202-1 cloud-init hardened account-bound probe declared (TC-140-cloud-init-hardened-account-bound-probe)"
55
+ },
56
+ {
57
+ "id": "TC-140-firewall-shape-valid-and-refuses-open-ssh",
58
+ "acId": "AC-11301-1",
59
+ "description": "Cover AC-11301-1 via anatomy test: schema accepts a rule set with 22 restricted plus 80/443 open and refuses an open-ssh mutation",
60
+ "status": "pending",
61
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11301-1 firewall shape valid and refuses open ssh (TC-140-firewall-shape-valid-and-refuses-open-ssh)"
62
+ },
63
+ {
64
+ "id": "TC-140-snapshot-cadence-enum",
65
+ "acId": "AC-11401-1",
66
+ "description": "Cover AC-11401-1 via anatomy test: snapshotCadence enum is weekly, daily, off",
67
+ "status": "pending",
68
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11401-1 snapshot cadence enum (TC-140-snapshot-cadence-enum)"
69
+ },
70
+ {
71
+ "id": "TC-140-snapshot-on-demand-account-bound-probe",
72
+ "acId": "AC-11402-1",
73
+ "description": "Cover AC-11402-1 via anatomy test: snapshot on-demand probe declares accountBound true and readme names the hcloud image list check",
74
+ "status": "pending",
75
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11402-1 snapshot on demand account-bound probe declared (TC-140-snapshot-on-demand-account-bound-probe)"
76
+ },
77
+ {
78
+ "id": "TC-140-lifecycle-events-metadata-only",
79
+ "acId": "AC-11501-1",
80
+ "description": "Cover AC-11501-1 via anatomy test: hcloud dry-run mock drives four lifecycle events, payloads carry only metadata fields, event-secrecy mutation FAILS",
81
+ "status": "pending",
82
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::T-1 deploy-hetzner-server AC-11501-1 lifecycle events metadata only (TC-140-lifecycle-events-metadata-only)"
83
+ }
84
+ ],
85
+ "status": "draft"
86
+ }
@@ -0,0 +1,86 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:44:51.205Z",
3
+ "updatedAt": "2026-09-08T01:45:31.442Z",
4
+ "purpose": "Cover the T-2 chain ACs via the shipped anatomy test at test/blueprint/platform-docker-compose-host-anatomy.test.js and via the five blueprint probes driven from the shared throwaway-server fixture (which T-2 extends with a compose stack, Caddyfile, secret file mount and healthchecked service)",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-12001-1",
8
+ "AC-12101-1",
9
+ "AC-12102-1",
10
+ "AC-12201-1",
11
+ "AC-12202-1",
12
+ "AC-12301-1",
13
+ "AC-12401-1",
14
+ "AC-12402-1",
15
+ "AC-12501-1"
16
+ ],
17
+ "id": "TS-150",
18
+ "usId": "US-12001",
19
+ "title": "T-2 platform-docker-compose-host anatomy proof: probe modules and compose-stack fixture assertions",
20
+ "testCases": [
21
+ {
22
+ "id": "TC-150-compose-layout-shape-valid",
23
+ "acId": "AC-12001-1",
24
+ "description": "Cover AC-12001-1 via anatomy test: fixture compose.yaml declares service-per-container, named networks and volumes, and a .env for non-secret config",
25
+ "status": "pending",
26
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12001-1 compose layout shape valid (TC-150-compose-layout-shape-valid)"
27
+ },
28
+ {
29
+ "id": "TC-150-secrets-file-mount-shape",
30
+ "acId": "AC-12101-1",
31
+ "description": "Cover AC-12101-1 via anatomy test: compose.yaml declares secrets under top-level secrets with a file source and mounts them into the web service; the mounted file is 0o400",
32
+ "status": "pending",
33
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12101-1 secrets file mount shape (TC-150-secrets-file-mount-shape)"
34
+ },
35
+ {
36
+ "id": "TC-150-secrets-scan-fails-on-plaintext",
37
+ "acId": "AC-12102-1",
38
+ "description": "Cover AC-12102-1 via anatomy test: secrets-as-files-scan probe passes on the canonical fixture and fails under SIMULATE_PLAINTEXT_SECRET naming the literal",
39
+ "status": "pending",
40
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12102-1 secrets-as-files scan fails on plaintext (TC-150-secrets-scan-fails-on-plaintext)"
41
+ },
42
+ {
43
+ "id": "TC-150-compose-config-lint-refuses-missing-healthcheck",
44
+ "acId": "AC-12201-1",
45
+ "description": "Cover AC-12201-1 via anatomy test: compose-config-lint probe passes on canonical fixture and fails under SIMULATE_MISSING_HEALTHCHECK naming the service",
46
+ "status": "pending",
47
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12201-1 compose-config-lint refuses missing healthcheck (TC-150-compose-config-lint-refuses-missing-healthcheck)"
48
+ },
49
+ {
50
+ "id": "TC-150-real-account-minimal-stack-up-declared-and-skipped-shape",
51
+ "acId": "AC-12202-1",
52
+ "description": "Cover AC-12202-1 via anatomy test: real-account-minimal-stack-up probe declares accountBound true and records accountBoundSkipped when the env var is unset",
53
+ "status": "pending",
54
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12202-1 real-account-minimal-stack-up declared and skipped shape (TC-150-real-account-minimal-stack-up-declared-and-skipped-shape)"
55
+ },
56
+ {
57
+ "id": "TC-150-restart-discipline-lint-refuses-unclassified",
58
+ "acId": "AC-12301-1",
59
+ "description": "Cover AC-12301-1 via anatomy test: compose-config-lint enforces restart policy classification and fails under SIMULATE_UNCLASSIFIED_RESTART naming the service",
60
+ "status": "pending",
61
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12301-1 restart discipline lint refuses unclassified (TC-150-restart-discipline-lint-refuses-unclassified)"
62
+ },
63
+ {
64
+ "id": "TC-150-caddyfile-validate-refuses-invalid-directive",
65
+ "acId": "AC-12401-1",
66
+ "description": "Cover AC-12401-1 via anatomy test: caddyfile-validate probe passes on canonical Caddyfile and fails under SIMULATE_INVALID_CADDYFILE naming the line",
67
+ "status": "pending",
68
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12401-1 caddyfile-validate refuses invalid directive (TC-150-caddyfile-validate-refuses-invalid-directive)"
69
+ },
70
+ {
71
+ "id": "TC-150-real-account-reload-burst-declared-and-skipped-shape",
72
+ "acId": "AC-12402-1",
73
+ "description": "Cover AC-12402-1 via anatomy test: real-account-reload-burst probe declares accountBound true and records accountBoundSkipped when the env var is unset",
74
+ "status": "pending",
75
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12402-1 real-account-reload-burst declared and skipped shape (TC-150-real-account-reload-burst-declared-and-skipped-shape)"
76
+ },
77
+ {
78
+ "id": "TC-150-log-driver-classification",
79
+ "acId": "AC-12501-1",
80
+ "description": "Cover AC-12501-1 via anatomy test: compose-config-lint asserts every service declares a logging driver and fails under SIMULATE_UNCLASSIFIED_LOG_DRIVER naming the service",
81
+ "status": "pending",
82
+ "testPointer": "test/blueprint/platform-docker-compose-host-anatomy.test.js::T-2 platform-docker-compose-host AC-12501-1 log driver classification (TC-150-log-driver-classification)"
83
+ }
84
+ ],
85
+ "status": "draft"
86
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:24:23.156Z",
3
+ "updatedAt": "2026-09-08T03:24:51.162Z",
4
+ "purpose": "Cover the T-3 chain ACs via the shipped anatomy test at test/blueprint/edge-cloudflare-tunnel-anatomy.test.js and via the three local probe modules driven from the shared throwaway-server fixture (which T-3 extends with cloudflared/compose-service and cloudflared/systemd-unit variants, each in both public-hostname and access-gated sidecar modes).",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-13001-1",
8
+ "AC-13002-1",
9
+ "AC-13101-1",
10
+ "AC-13102-1",
11
+ "AC-13201-1",
12
+ "AC-13301-1",
13
+ "AC-13302-1",
14
+ "AC-13401-1"
15
+ ],
16
+ "id": "TS-160",
17
+ "usId": "US-13001",
18
+ "title": "T-3 edge-cloudflare-tunnel anatomy proof: probe modules and cloudflared connector fixture assertions",
19
+ "testCases": [
20
+ {
21
+ "id": "TC-160-connector-shape-variants-shipped",
22
+ "acId": "AC-13001-1",
23
+ "description": "Cover AC-13001-1 via anatomy test: the shared fixture ships both cloudflared/compose-service/ and cloudflared/systemd-unit/ variants and the compose-service variant defines a cloudflared service alongside T-2 web and caddy on the same web-net network with no host ports; the systemd-unit variant ships a cloudflared.service unit file per the vendor local-configuration-file docs.",
24
+ "status": "pending",
25
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13001-1 connector shape variants shipped (TC-160-connector-shape-variants-shipped)"
26
+ },
27
+ {
28
+ "id": "TC-160-real-account-connector-healthy-declared-and-skipped-shape",
29
+ "acId": "AC-13002-1",
30
+ "description": "Cover AC-13002-1 via anatomy test: real-account-connector-healthy probe declares accountBound true and records accountBoundSkipped when CI_HAS_CLOUDFLARE_ACCOUNT or CI_HAS_HETZNER_ACCOUNT is unset.",
31
+ "status": "pending",
32
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13002-1 real-account-connector-healthy declared and skipped shape (TC-160-real-account-connector-healthy-declared-and-skipped-shape)"
33
+ },
34
+ {
35
+ "id": "TC-160-manifest-schema-validate-refuses-invalid",
36
+ "acId": "AC-13101-1",
37
+ "description": "Cover AC-13101-1 via anatomy test: manifest-schema-validate probe passes on the canonical fixture manifests and fails under the three fixture-side mutations SIMULATE_MANIFEST_INVALID_TUNNEL_ID, SIMULATE_MANIFEST_CREDENTIALS_INLINE and SIMULATE_MANIFEST_MISSING_CATCHALL naming the offending field.",
38
+ "status": "pending",
39
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13101-1 manifest schema validate refuses invalid (TC-160-manifest-schema-validate-refuses-invalid)"
40
+ },
41
+ {
42
+ "id": "TC-160-cloudflared-config-lint-passes-and-refuses-invalid-ingress",
43
+ "acId": "AC-13102-1",
44
+ "description": "Cover AC-13102-1 via anatomy test: cloudflared-config-lint probe runs cloudflared tunnel ingress validate through the cloudflare/cloudflared container image and exits 0 on the canonical fixture; fails under SIMULATE_INGRESS_INVALID naming the offending line.",
45
+ "status": "pending",
46
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13102-1 cloudflared-config-lint passes and refuses invalid ingress (TC-160-cloudflared-config-lint-passes-and-refuses-invalid-ingress)"
47
+ },
48
+ {
49
+ "id": "TC-160-no-public-origin-port-refused",
50
+ "acId": "AC-13201-1",
51
+ "description": "Cover AC-13201-1 via anatomy test: manifest-schema-validate refuses under SIMULATE_ORIGIN_PORT_OPEN when an ingress rule service URL binds to a host public interface; the T-1 firewall on the ci-throwaway manifest stays 22 open plus 80/443 open only when a reverse proxy is applied.",
52
+ "status": "pending",
53
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13201-1 no public origin port refused (TC-160-no-public-origin-port-refused)"
54
+ },
55
+ {
56
+ "id": "TC-160-aud-presence-flip-on-both-fixture-variants",
57
+ "acId": "AC-13301-1",
58
+ "description": "Cover AC-13301-1 via anatomy test: aud-presence-check reads each variant sidecar and asserts the ingress rules attach originRequest.access.aud on the access-gated variant and omit the block on the public-hostname variant.",
59
+ "status": "pending",
60
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13301-1 aud-presence-check flips on both fixture variants (TC-160-aud-presence-flip-on-both-fixture-variants)"
61
+ },
62
+ {
63
+ "id": "TC-160-aud-presence-check-refuses-on-drift",
64
+ "acId": "AC-13302-1",
65
+ "description": "Cover AC-13302-1 via anatomy test: aud-presence-check FAILS under SIMULATE_AUD_DROP when the gated fixture ingress drifts to omit the originRequest.access block; the finding names the affected rule.",
66
+ "status": "pending",
67
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13302-1 aud-presence-check refuses on drift (TC-160-aud-presence-check-refuses-on-drift)"
68
+ },
69
+ {
70
+ "id": "TC-160-credentials-discipline-and-event-secrecy",
71
+ "acId": "AC-13401-1",
72
+ "description": "Cover AC-13401-1 via anatomy test: the fixture credentials placeholder documents the 0o400 host mode and secretRef discipline; the event-secrecy scan across lifecycle event bodies passes on canonical fixture and FAILS under SIMULATE_EVENT_SECRECY_LEAK naming the leaked field.",
73
+ "status": "pending",
74
+ "testPointer": "test/blueprint/edge-cloudflare-tunnel-anatomy.test.js::T-3 edge-cloudflare-tunnel AC-13401-1 credentials discipline and event-secrecy scan (TC-160-credentials-discipline-and-event-secrecy)"
75
+ }
76
+ ],
77
+ "status": "draft"
78
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "createdAt": "2026-09-08T09:03:22.340Z",
3
+ "updatedAt": "2026-09-08T09:03:32.202Z",
4
+ "purpose": "Cover the adapter chain AC via the shipped anatomy test at test/blueprint/object-storage-s3-hetzner-anatomy.test.js and via the new probe module hetzner-object-storage-round-trip.mjs driven from the extended infra-s3-and-queue fixture (accountBoundSkipped path without CI_HAS_HETZNER_OBJECT_STORAGE, endpoint-composition mutation via SIMULATE_HETZNER_ENDPOINT_MISSHAPEN)",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-14001-1"
8
+ ],
9
+ "id": "TS-170",
10
+ "usId": "US-14001",
11
+ "title": "Adapter object-storage-s3 v1.1.0 Hetzner Object Storage: probe module anatomy and fixture-side helper contract",
12
+ "testCases": [
13
+ {
14
+ "id": "TC-170-hetzner-endpoint-round-trip-and-skipped-shape",
15
+ "acId": "AC-14001-1",
16
+ "description": "Cover AC-14001-1 via anatomy test: hetzner-endpoint helper composes the vendor pattern <bucket>.<location>.your-objectstorage.com from an elicited bucket and location; the run-hetzner-object-storage-round-trip probe records accountBoundSkipped true and aggregateVerdict pass without CI_HAS_HETZNER_OBJECT_STORAGE; the extended fixture ships hetzner-endpoint.mjs and run-hetzner-object-storage-round-trip.mjs alongside the shipped MinIO and R2 assets; SIMULATE_HETZNER_ENDPOINT_MISSHAPEN true composes an invalid endpoint via the fixture-side shim and the probe FAILS naming the missing subdomain",
17
+ "status": "pending",
18
+ "testPointer": "test/blueprint/object-storage-s3-hetzner-anatomy.test.js::adapter object-storage-s3 v1.1.0 hetzner AC-14001-1 endpoint round-trip and skipped shape (TC-170-hetzner-endpoint-round-trip-and-skipped-shape)"
19
+ }
20
+ ],
21
+ "status": "draft"
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "createdAt": "2026-09-08T10:51:19.406Z",
3
+ "updatedAt": "2026-09-08T10:51:55.354Z",
4
+ "purpose": "Anchor AC-14501-1 via the shipped anatomy test: the hcloud-dry-run-mock probe reads the rendered cloud-init user-data written by the fixture renderer and asserts (a) at least one ssh-ed25519 or ssh-rsa public-key line is present under the deploy user and (b) a write_files or sudoers.d fragment grants NOPASSWD to that user; the probe FAILS on either missing marker. Purity: the three T-1 mocked probes no longer read SIMULATE_ switches inside the probe body; those live in fixture-side shims and alter INPUT only.",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-14501-1"
8
+ ],
9
+ "id": "TS-175",
10
+ "usId": "US-14501",
11
+ "title": "H-1 patch train verifiers for deploy-hetzner-server 1.0.1: hcloud-dry-run-mock consumes the same rendered cloud-init the real path consumes and asserts an ssh public-key line for the deploy user plus a NOPASSWD sudoers.d entry; ssh baseline check module gains an unmocked purity assertion that no SIMULATE_ branch remains in the probes for T-1",
12
+ "testCases": [
13
+ {
14
+ "id": "TC-175-mock-consumes-rendered-file-and-probe-purity",
15
+ "acId": "AC-14501-1",
16
+ "description": "Render the shipped cloud-init.yaml.tmpl against ci-throwaway.json via the fixture renderer with an ssh key material substitution and NOPASSWD sudoers.d fragment for the deploy user. Assert the rendered file appears at hetzner/servers/rendered/ci-throwaway.cloud-init.yaml with at least one ssh-ed25519 or ssh-rsa authorized-keys line under the deploy user and a NOPASSWD directive naming that user. Run the hcloud-dry-run-mock probe: assert the mock reads back that same rendered file and returns pass. Also assert none of the three T-1 mocked probes (cloud-init-render-lint, hcloud-dry-run-mock, manifest-schema-validate) contain the token SIMULATE_ inside the probe body; the switches live only in the fixture-side shims. Anchors AC-14501-1.",
17
+ "status": "pending",
18
+ "testPointer": "test/blueprint/deploy-hetzner-server-anatomy.test.js::H-1 deploy-hetzner-server AC-14501-1 mock consumes the same rendered cloud-init and probes carry no SIMULATE reads (TC-175-mock-consumes-rendered-file-and-probe-purity)"
19
+ }
20
+ ],
21
+ "status": "draft"
22
+ }