rcf-lite 0.24.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 (232) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/blueprints/application-account-settings/docs/topics.md +3 -0
  3. package/blueprints/application-admin-console/docs/topics.md +3 -0
  4. package/blueprints/application-api-rest/docs/topics.md +3 -0
  5. package/blueprints/application-charts/docs/topics.md +3 -0
  6. package/blueprints/application-dashboard/docs/topics.md +3 -0
  7. package/blueprints/application-datatable/docs/topics.md +3 -0
  8. package/blueprints/application-empty-error-states/docs/topics.md +3 -0
  9. package/blueprints/application-error-handling/docs/topics.md +3 -0
  10. package/blueprints/application-file-upload/docs/topics.md +3 -0
  11. package/blueprints/application-forms-wizard/docs/topics.md +3 -0
  12. package/blueprints/application-notifications-in-app/docs/topics.md +3 -0
  13. package/blueprints/application-onboarding-tour/docs/topics.md +3 -0
  14. package/blueprints/application-spa/docs/topics.md +3 -0
  15. package/blueprints/delivery-ci-workflows/docs/topics.md +3 -0
  16. package/blueprints/deploy-cloudflare-workers/docs/topics.md +3 -0
  17. package/blueprints/deploy-hetzner-server/CHANGELOG.md +34 -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 +64 -0
  25. package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +116 -0
  26. package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +180 -0
  27. package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +106 -0
  28. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +63 -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 +93 -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 +3 -0
  61. package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +3 -0
  62. package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +13 -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 +234 -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 +54 -0
  73. package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-tunnel-hostname-routes.mjs +73 -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 +3 -0
  99. package/blueprints/email-smtp-resend/docs/topics.md +3 -0
  100. package/blueprints/jobs-background/docs/topics.md +3 -0
  101. package/blueprints/messaging-queue-cloudflare/docs/topics.md +3 -0
  102. package/blueprints/object-storage-s3/docs/topics.md +3 -0
  103. package/blueprints/observability-essentials/docs/topics.md +3 -0
  104. package/blueprints/observability-logging/docs/topics.md +3 -0
  105. package/blueprints/observability-probe-endpoints/docs/topics.md +3 -0
  106. package/blueprints/persistence-data-d1/docs/topics.md +3 -0
  107. package/blueprints/persistence-data-postgres/docs/topics.md +3 -0
  108. package/blueprints/persistence-data-sqlite/docs/topics.md +3 -0
  109. package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +3 -0
  110. package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +3 -0
  111. package/blueprints/platform-cloudflare-kv/docs/topics.md +3 -0
  112. package/blueprints/platform-docker-compose-host/CHANGELOG.md +12 -0
  113. package/blueprints/platform-docker-compose-host/README.md +76 -0
  114. package/blueprints/platform-docker-compose-host/blueprint.json +209 -0
  115. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3901-platform-docker-compose-host-contract.json +14 -0
  116. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +14 -0
  117. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +14 -0
  118. package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3904-platform-docker-compose-host-log-driver.json +14 -0
  119. package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +108 -0
  120. package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +231 -0
  121. package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +185 -0
  122. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +41 -0
  123. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +36 -0
  124. package/blueprints/platform-docker-compose-host/contributions/probes/run-caddyfile-validate.mjs +5 -0
  125. package/blueprints/platform-docker-compose-host/contributions/probes/run-compose-config-lint.mjs +5 -0
  126. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-minimal-stack-up.mjs +5 -0
  127. package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-reload-burst.mjs +5 -0
  128. package/blueprints/platform-docker-compose-host/contributions/probes/run-secrets-as-files-scan.mjs +5 -0
  129. package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +116 -0
  130. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +18 -0
  131. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +18 -0
  132. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +18 -0
  133. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +18 -0
  134. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +18 -0
  135. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +18 -0
  136. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +26 -0
  137. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +26 -0
  138. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +26 -0
  139. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +26 -0
  140. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +24 -0
  141. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +24 -0
  142. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +24 -0
  143. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +24 -0
  144. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +25 -0
  145. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +24 -0
  146. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +24 -0
  147. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +24 -0
  148. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +24 -0
  149. package/blueprints/platform-docker-compose-host/docs/topics.md +71 -0
  150. package/blueprints/platform-docker-compose-host/guide/platform-docker-compose-host.md +94 -0
  151. package/blueprints/security-auth-clerk/docs/topics.md +3 -0
  152. package/blueprints/security-auth-keycloak/docs/topics.md +3 -0
  153. package/blueprints/security-auth-magic-link/docs/topics.md +3 -0
  154. package/blueprints/security-auth-oauth2/docs/topics.md +3 -0
  155. package/blueprints/security-secrets-management/docs/topics.md +3 -0
  156. package/fixtures/canary-manifest.json +9 -9
  157. package/package.json +1 -1
  158. package/rcf/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +13 -0
  159. package/rcf/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +13 -0
  160. package/rcf/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +13 -0
  161. package/rcf/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +13 -0
  162. package/rcf/adrs/adr-3901-platform-docker-compose-host-contract.json +13 -0
  163. package/rcf/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +13 -0
  164. package/rcf/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +13 -0
  165. package/rcf/adrs/adr-3904-platform-docker-compose-host-log-driver.json +13 -0
  166. package/rcf/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +13 -0
  167. package/rcf/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +13 -0
  168. package/rcf/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +13 -0
  169. package/rcf/code-nodes/cn-410.json +20 -0
  170. package/rcf/code-nodes/cn-440.json +20 -0
  171. package/rcf/code-nodes/cn-470.json +19 -0
  172. package/rcf/fbs/fbs-130.json +23 -0
  173. package/rcf/fbs/fbs-140.json +23 -0
  174. package/rcf/fbs/fbs-150.json +22 -0
  175. package/rcf/requirements/req-110.json +58 -0
  176. package/rcf/requirements/req-111.json +32 -0
  177. package/rcf/requirements/req-112.json +42 -0
  178. package/rcf/requirements/req-113.json +33 -0
  179. package/rcf/requirements/req-114.json +20 -0
  180. package/rcf/requirements/req-115.json +38 -0
  181. package/rcf/requirements/req-120.json +20 -0
  182. package/rcf/requirements/req-121.json +20 -0
  183. package/rcf/requirements/req-122.json +20 -0
  184. package/rcf/requirements/req-123.json +42 -0
  185. package/rcf/requirements/req-124.json +27 -0
  186. package/rcf/requirements/req-125.json +20 -0
  187. package/rcf/requirements/req-130.json +32 -0
  188. package/rcf/requirements/req-131.json +54 -0
  189. package/rcf/requirements/req-132.json +27 -0
  190. package/rcf/requirements/req-133.json +20 -0
  191. package/rcf/requirements/req-134.json +42 -0
  192. package/rcf/tacs/tac-3801-deploy-hetzner-server-provisioner.json +17 -0
  193. package/rcf/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +17 -0
  194. package/rcf/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +17 -0
  195. package/rcf/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +16 -0
  196. package/rcf/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +17 -0
  197. package/rcf/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +17 -0
  198. package/rcf/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +17 -0
  199. package/rcf/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +17 -0
  200. package/rcf/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +17 -0
  201. package/rcf/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +17 -0
  202. package/rcf/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +16 -0
  203. package/rcf/test-suites/ts-140.json +86 -0
  204. package/rcf/test-suites/ts-150.json +86 -0
  205. package/rcf/test-suites/ts-160.json +78 -0
  206. package/rcf/user-stories/us-11001.json +23 -0
  207. package/rcf/user-stories/us-11101.json +23 -0
  208. package/rcf/user-stories/us-11102.json +24 -0
  209. package/rcf/user-stories/us-11201.json +23 -0
  210. package/rcf/user-stories/us-11202.json +23 -0
  211. package/rcf/user-stories/us-11301.json +24 -0
  212. package/rcf/user-stories/us-11401.json +23 -0
  213. package/rcf/user-stories/us-11402.json +23 -0
  214. package/rcf/user-stories/us-11501.json +23 -0
  215. package/rcf/user-stories/us-12001.json +23 -0
  216. package/rcf/user-stories/us-12101.json +23 -0
  217. package/rcf/user-stories/us-12102.json +23 -0
  218. package/rcf/user-stories/us-12201.json +23 -0
  219. package/rcf/user-stories/us-12202.json +24 -0
  220. package/rcf/user-stories/us-12301.json +23 -0
  221. package/rcf/user-stories/us-12401.json +23 -0
  222. package/rcf/user-stories/us-12402.json +23 -0
  223. package/rcf/user-stories/us-12501.json +23 -0
  224. package/rcf/user-stories/us-13001.json +23 -0
  225. package/rcf/user-stories/us-13002.json +23 -0
  226. package/rcf/user-stories/us-13101.json +23 -0
  227. package/rcf/user-stories/us-13102.json +23 -0
  228. package/rcf/user-stories/us-13201.json +23 -0
  229. package/rcf/user-stories/us-13301.json +23 -0
  230. package/rcf/user-stories/us-13302.json +23 -0
  231. package/rcf/user-stories/us-13401.json +23 -0
  232. package/releases/releases.yaml +11 -1
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:22.057Z",
3
+ "updatedAt": "2026-09-08T01:44:12.646Z",
4
+ "adrId": "ADR-3903-platform-docker-compose-host-reject-coolify",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "accepted",
9
+ "title": "T-2 Coolify rejected per Baz decision 20 (it shadows what the blueprints contract and adds its own DB and UI as a second source of state)",
10
+ "context": "Coolify was proposed as a candidate platform-* sibling in the round-7 proposal. It is a self-hosted PaaS with its own database and UI. Baz decision 20 on 2026-09-07 09:50Z ruled Coolify out for round 7.",
11
+ "decision": "reject; it shadows what the blueprints contract and adds its own DB and UI as a second source of state.",
12
+ "consequences": "No platform-coolify-host blueprint is scoped in round 7 and no reserved slot is allocated. A future platform-coolify-host sibling mints on operator demand under a fresh scope PR. The standards trace clause on this contribution entry is generic enterprise practice; no vendor-doc URL is claimed for the reject decision."
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:42:22.244Z",
3
+ "updatedAt": "2026-09-08T01:44:12.833Z",
4
+ "adrId": "ADR-3904-platform-docker-compose-host-log-driver",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "accepted",
9
+ "title": "T-2 log driver choice: journald default matching Debian 12 and Ubuntu 24.04 baseline; loki opt-in when the project runs Grafana (elicited)",
10
+ "context": "Containers write stdout and stderr to a log driver. Debian 12 and Ubuntu 24.04 (the T-1 cloud-init baseline) ship journald. Grafana users on the estate reach for loki as a native sink. A one-choice hard-code loses either journald parity with the OS or loki when the operator runs Grafana.",
11
+ "decision": "The log driver is elicited via the log-driver parameter. The shipped default is journald matching the Debian 12 and Ubuntu 24.04 baselines T-1 sets up. The alternative is loki, opted into when the applying project runs Grafana. When observability-logging is applied, the compose file wires the elicited driver to that companion. Standards trace clause: generic enterprise practice.",
12
+ "consequences": "A project applying log-driver=journald gets the systemd-native path; the journald sink is queried via journalctl. A project applying log-driver=loki targets the Grafana loki endpoint; the observability-logging companion supplies the endpoint address. Neither choice adds a runtime npm dependency. The compose-config-lint refuses on any driver value outside the allowed set."
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:09.408Z",
3
+ "updatedAt": "2026-09-08T03:23:09.408Z",
4
+ "adrId": "ADR-4001-edge-cloudflare-tunnel-ingress-bridge-contract",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "proposed",
9
+ "title": "T-3 edge ingress bridge contract: Cloudflare Tunnel as the shipped ingress-bridge shape from a cloudHost service to the CF edge (scope global, new topic edgeIngressBridge)",
10
+ "context": "An applying project running on a Linux cloudHost needs one shipped answer to the question of how a service on that host reaches the public internet without opening origin ports. Round-7 T-3 mints the edgeIngressBridge topic on this ADR. Cloudflare Tunnel is the shipped v1.0.0 mechanism (cloudflared connector out to the CF edge; DNS route on a Cloudflare zone; ingress rules mapping public hostname to internal service URL). Every applied ingress bridge needs one project-wide answer to the edgeIngressBridge topic; a future non-Cloudflare sibling (Tailscale Funnel, Fly.io proxy) would contribute the same topic string with a different mechanism, forcing a DELIBERATE conflict the operator resolves per the round-2 conflict pattern. Standards trace clause: Cloudflare Tunnel overview and get-started documented mechanics per hetzner-round-7-spec-2026-09-07.md.",
11
+ "decision": "The shipped v1.0.0 default is a Cloudflare Tunnel connector as the edgeIngressBridge provider. A cloudflared connector on the applying host (compose service by default when containerHost is applied per ADR-4002; systemd unit on a bare cloudHost) reads a tunnel manifest at cloudflare/tunnels/<name>.yaml and terminates ingress at the CF edge. The edgeIngressBridge topic scope is global on this blueprint; the topic string is edgeIngressBridge (lower camelCase, one concept per topic, no version suffix, per the round-2 rules-for-new-topics clause on the shelf registry). Standards trace clause: Cloudflare Tunnel overview and get-started documented mechanics per hetzner-round-7-spec-2026-09-07.md.",
12
+ "consequences": "Consumer blueprints that expose a service publicly declare capabilities: [tunnelBridge] on their applied contract to know a bridge is in place. Composition with zeroTrustGate (edge-cloudflare-access) toggles the Access-gated ingress shape per ADR-4003. A T-3-only project (no reverse proxy) declares no 80/443 firewall rule; the tunnel is the sole path from the edge to the origin. Rebuild-from-manifest is always possible: the manifest is the source of truth, the running connector is derivative. Folding this shape into edge-cloudflare-access was rejected: Access is an authorisation gate, Tunnel is an ingress bridge; the responsibilities are distinct and one applies without the other."
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:09.604Z",
3
+ "updatedAt": "2026-09-08T03:23:09.604Z",
4
+ "adrId": "ADR-4002-edge-cloudflare-tunnel-connector-runtime",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "proposed",
9
+ "title": "T-3 connector runtime: compose-service default when containerHost applied; systemd-unit alternative on bare cloudHost",
10
+ "context": "The cloudflared connector runs in one of two supported vendor shapes: as a container image published on the cloudflared downloads page, or as a systemd unit installed via the vendor package per the cloudflared as-a-service local-configuration-file docs. An applying project running its stack under docker compose has a natural home for the connector alongside its other services (same network, same logging driver, same restart policy). An applying project running bare on the host has no compose stack and needs a systemd unit for boot ordering and journald logging. Standards trace clause: Cloudflare cloudflared as-a-service documented systemd unit per hetzner-round-7-spec-2026-09-07.md.",
11
+ "decision": "The connector runtime is elicited via ADR-4002 with enum {compose-service, systemd-unit} and recommendedDefault compose-service. When the containerHost capability is applied (T-2 platform-docker-compose-host) the shipped default is compose-service; when the host runs bare (only T-1 applied) the operator picks systemd-unit at apply time. Standards trace clause: Cloudflare cloudflared as-a-service documented systemd unit per hetzner-round-7-spec-2026-09-07.md.",
12
+ "consequences": "The fixture ships both variants and both pass the local probes (manifest-schema-validate, cloudflared-config-lint, aud-presence-check). A future non-Cloudflare tunnel sibling (Tailscale Funnel, Fly.io proxy) reuses the runtime enum shape but the elicit lives on that siblings own ADR (conflict-by-design on edgeIngressBridge per ADR-4001). The systemd variant carries an install caveat in the guide: the vendor package landed via apt/curl per the as-a-service docs, which is out of scope for the blueprint itself."
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:23:09.794Z",
3
+ "updatedAt": "2026-09-08T03:23:09.794Z",
4
+ "adrId": "ADR-4003-edge-cloudflare-tunnel-hostname-mode",
5
+ "prdId": "PRD-001",
6
+ "tadId": "TAD-001",
7
+ "version": "0.1.0",
8
+ "status": "proposed",
9
+ "title": "T-3 hostname mode: access-gated when zeroTrustGate applied (ingress attaches AUD); public-hostname when absent (block omitted)",
10
+ "context": "A tunnel can serve a public hostname openly (any request reaches the origin, protected only by whatever authentication the origin itself carries) or Access-gated (cloudflared refuses at the edge any request without a valid Access JWT for a named AUD, per the vendor self-hosted-public-app docs). The hostname mode is not elicited: it is DISCOVERED from the applied capability set. When zeroTrustGate is applied (edge-cloudflare-access v1.0.0), the tunnel binds the Access AUD; when it is not, the tunnel serves in public-hostname mode. Standards trace clause: Cloudflare Access self-hosted-public-app documented shape per hetzner-round-7-spec-2026-09-07.md.",
11
+ "decision": "ADR-4003 records the hostname mode as elicited: false and discovered from applied capabilities via the sidecar rcf/blueprints/edge-cloudflare-tunnel.applied.json. When appliedCapabilities includes zeroTrustGate, every ingress rule under the tunnel manifest attaches an originRequest.access block naming the AUD; when it does not, the block is omitted. The aud-presence-check probe runs on both fixture variants and asserts the shape flips correctly. Standards trace clause: Cloudflare Access self-hosted-public-app documented shape per hetzner-round-7-spec-2026-09-07.md.",
12
+ "consequences": "A project that applies zeroTrustGate later inherits the Access-gated shape on the next reapply of edge-cloudflare-tunnel without a manual manifest edit; a project that removes zeroTrustGate drops to public-hostname mode explicitly. A silent drift (the sidecar keeps zeroTrustGate but the ingress loses the AUD block) is caught by aud-presence-check refusing before the shape ships. Fixture variants live under cloudflared/*/access-gated and cloudflared/*/public-hostname; the SIMULATE_AUD_DROP mutation on the gated fixture proves the refuse path."
13
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "cnId": "CN-410",
3
+ "path": "../../blueprints/deploy-hetzner-server/blueprint.json",
4
+ "implementsAcIds": [
5
+ "AC-11001-1",
6
+ "AC-11101-1",
7
+ "AC-11102-1",
8
+ "AC-11201-1",
9
+ "AC-11202-1",
10
+ "AC-11301-1",
11
+ "AC-11401-1",
12
+ "AC-11402-1",
13
+ "AC-11501-1"
14
+ ],
15
+ "dependencies": [],
16
+ "version": "0.1.0",
17
+ "status": "draft",
18
+ "createdAt": "2026-09-07T23:59:16.031Z",
19
+ "updatedAt": "2026-09-07T23:59:16.220Z"
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "cnId": "CN-440",
3
+ "path": "../../blueprints/platform-docker-compose-host/blueprint.json",
4
+ "implementsAcIds": [
5
+ "AC-12001-1",
6
+ "AC-12101-1",
7
+ "AC-12102-1",
8
+ "AC-12201-1",
9
+ "AC-12202-1",
10
+ "AC-12301-1",
11
+ "AC-12401-1",
12
+ "AC-12402-1",
13
+ "AC-12501-1"
14
+ ],
15
+ "dependencies": [],
16
+ "version": "0.1.0",
17
+ "status": "draft",
18
+ "createdAt": "2026-09-08T01:45:43.708Z",
19
+ "updatedAt": "2026-09-08T01:45:43.708Z"
20
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "cnId": "CN-470",
3
+ "path": "../../blueprints/edge-cloudflare-tunnel/blueprint.json",
4
+ "implementsAcIds": [
5
+ "AC-13001-1",
6
+ "AC-13002-1",
7
+ "AC-13101-1",
8
+ "AC-13102-1",
9
+ "AC-13201-1",
10
+ "AC-13301-1",
11
+ "AC-13302-1",
12
+ "AC-13401-1"
13
+ ],
14
+ "dependencies": [],
15
+ "version": "0.1.0",
16
+ "status": "draft",
17
+ "createdAt": "2026-09-08T03:25:10.642Z",
18
+ "updatedAt": "2026-09-08T03:25:10.642Z"
19
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:59:15.656Z",
3
+ "updatedAt": "2026-09-07T23:59:15.844Z",
4
+ "acIds": [
5
+ "AC-11001-1",
6
+ "AC-11101-1",
7
+ "AC-11102-1",
8
+ "AC-11201-1",
9
+ "AC-11202-1",
10
+ "AC-11301-1",
11
+ "AC-11401-1",
12
+ "AC-11402-1",
13
+ "AC-11501-1"
14
+ ],
15
+ "fbsId": "FBS-130",
16
+ "prdId": "PRD-001",
17
+ "bsId": "BS-001",
18
+ "buildOrder": 60,
19
+ "executionStatus": "notStarted",
20
+ "title": "T-1 deploy-hetzner-server v1.0.0: 6 REQs 9 USs 4 TACs 4 ADRs 6 Node-only probes; shared hetzner-throwaway-server fixture mint with provision/destroy/sweep-orphans and dry-run mock",
21
+ "summary": "HQ round-7 T-1: deploy-hetzner-server v1.0.0 blueprint on the shelf under blueprints/deploy-hetzner-server/ (23 contributions: 6 REQs, 9 USs, 4 TACs, 4 ADRs; inventory per hetzner-round-7-spec-2026-09-07 section 5.1). Mints the shared throwaway-Hetzner-server fixture at packages/rcf-lite/test/fixtures/hetzner-throwaway-server/ (provision.mjs, destroy.mjs, sweep-orphans.mjs, hcloud-mock shim, cloud-init renderer, provisioner-facade proto, hetzner/servers/ci-throwaway.json manifest, README) that T-2 and T-3 will extend. Six Node-only probes under blueprints/deploy-hetzner-server/contributions/probes/: cloud-init-render-lint (AC-11201-1; SIMULATE_HARDENING_DRIFT mutation), manifest-schema-validate (AC-11101-1, AC-11301-1, AC-11401-1; SIMULATE_MANIFEST_INVALID mutation), hcloud-dry-run-mock (AC-11001-1, AC-11501-1; JSON-parser-strip mutation plus event-secrecy leak mutation), real-account-throwaway-server-provision (AC-11102-1; accountBound), real-account-cloud-init-hardened (AC-11202-1; accountBound), real-account-snapshot-on-demand (AC-11402-1; accountBound). Blueprint README, guide, CHANGELOG, docs/topics.md; shelf-wide topics.md sweep adding the deploy-hetzner-server row across every prior blueprint; section 6a cloudHost row on packages/rcf-lite/docs/blueprint-authoring.md. New global topics minted: linuxCloudHostContract, snapshotAndBackupCadence. Repo chain: REQ-110..115, US-11001, 11101, 11102, 11201, 11202, 11301, 11401, 11402, 11501, TS-140 with nine TCs, FBS-130, CN-410, TAC-3801..3804, ADR-3801..3804 minted via rcf define create --id per HQ round-7 T-1 reserved-block ruling (REQ-110..119 / TS-140..149 / FBS-130..139 / CN-410..439). Base commit origin/main 150d9c6.",
22
+ "dependsOnFbsIds": []
23
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:45:31.629Z",
3
+ "updatedAt": "2026-09-08T01:45:31.816Z",
4
+ "acIds": [
5
+ "AC-12001-1",
6
+ "AC-12101-1",
7
+ "AC-12102-1",
8
+ "AC-12201-1",
9
+ "AC-12202-1",
10
+ "AC-12301-1",
11
+ "AC-12401-1",
12
+ "AC-12402-1",
13
+ "AC-12501-1"
14
+ ],
15
+ "fbsId": "FBS-140",
16
+ "prdId": "PRD-001",
17
+ "bsId": "BS-001",
18
+ "buildOrder": 61,
19
+ "executionStatus": "notStarted",
20
+ "title": "T-2 platform-docker-compose-host v1.0.0: 6 REQs 9 USs 4 TACs 4 ADRs 5 Node-only probes; extend shared hetzner-throwaway-server fixture with compose stack, Caddyfile, secret file mount and healthchecked service",
21
+ "summary": "HQ round-7 T-2: platform-docker-compose-host v1.0.0 blueprint on the shelf under blueprints/platform-docker-compose-host/ (23 contributions: 6 REQs, 9 USs, 4 TACs, 4 ADRs; inventory per hetzner-round-7-spec-2026-09-07 section 5.2). Extends the shared throwaway-Hetzner-server fixture minted by T-1 (packages/rcf-lite/test/fixtures/hetzner-throwaway-server/) with a compose stack (compose.yaml, caddy/Caddyfile, secrets/web-token file mount, src/serve.mjs healthchecked stub) plus five run-<probe>.mjs delegate shims. Five Node-only probes under blueprints/platform-docker-compose-host/contributions/probes/: compose-config-lint (AC-12201-1, AC-12301-1, AC-12501-1; SIMULATE_MISSING_HEALTHCHECK, SIMULATE_UNCLASSIFIED_RESTART, SIMULATE_UNCLASSIFIED_LOG_DRIVER, SIMULATE_EVENT_SECRECY_LEAK mutations), secrets-as-files-scan (AC-12101-1, AC-12102-1; SIMULATE_PLAINTEXT_SECRET mutation), caddyfile-validate (AC-12401-1; SIMULATE_INVALID_CADDYFILE mutation; runs the caddy:2 vendor container so a caddy binary on PATH is optional), real-account-minimal-stack-up (AC-12202-1; accountBound), real-account-reload-burst (AC-12402-1; accountBound). Blueprint README, guide, CHANGELOG, docs/topics.md; shelf-wide topics.md sweep adding the platform-docker-compose-host row across every prior blueprint; section 6a containerHost row on packages/rcf-lite/docs/blueprint-authoring.md. New global topic minted: containerHostContract. Repo chain: REQ-120..125, US-12001, 12101, 12102, 12201, 12202, 12301, 12401, 12402, 12501, TS-150 with nine TCs, FBS-140, CN-440, TAC-3901..3904, ADR-3901..3904 minted via rcf define create --id per HQ round-7 T-2 reserved-block ruling (REQ-120..129 / TS-150..159 / FBS-140..149 / CN-440..469). Base commit origin/main 30f7b77.",
22
+ "dependsOnFbsIds": []
23
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "createdAt": "2026-09-08T03:25:02.808Z",
3
+ "updatedAt": "2026-09-08T03:25:02.808Z",
4
+ "acIds": [
5
+ "AC-13001-1",
6
+ "AC-13002-1",
7
+ "AC-13101-1",
8
+ "AC-13102-1",
9
+ "AC-13201-1",
10
+ "AC-13301-1",
11
+ "AC-13302-1",
12
+ "AC-13401-1"
13
+ ],
14
+ "fbsId": "FBS-150",
15
+ "prdId": "PRD-001",
16
+ "bsId": "BS-001",
17
+ "buildOrder": 62,
18
+ "executionStatus": "notStarted",
19
+ "title": "T-3 edge-cloudflare-tunnel v1.0.0: 5 REQs 8 USs 3 TACs 3 ADRs 5 Node-only probes; extend shared hetzner-throwaway-server fixture with cloudflared connector (compose-service and systemd-unit variants; access-gated and public-hostname sidecar modes)",
20
+ "summary": "HQ round-7 T-3: edge-cloudflare-tunnel v1.0.0 blueprint on the shelf under blueprints/edge-cloudflare-tunnel/ (five REQs, eight USs, three TACs, three ADRs; inventory per hetzner-round-7-spec-2026-09-07 section 5.3). Extends the shared throwaway-Hetzner-server fixture minted by T-1 and extended by T-2 (packages/rcf-lite/test/fixtures/hetzner-throwaway-server/) 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), all under cloudflared/{compose-service,systemd-unit}/{access-gated,public-hostname}/. Five Node-only probes under blueprints/edge-cloudflare-tunnel/contributions/probes/: manifest-schema-validate (AC-13101-1, AC-13201-1, AC-13401-1; fixture-side SIMULATE_MANIFEST_INVALID_TUNNEL_ID, SIMULATE_MANIFEST_CREDENTIALS_INLINE, SIMULATE_MANIFEST_MISSING_CATCHALL, SIMULATE_ORIGIN_PORT_OPEN, SIMULATE_EVENT_SECRECY_LEAK mutations), cloudflared-config-lint (AC-13102-1; SIMULATE_INGRESS_INVALID mutation; runs the cloudflare/cloudflared vendor container so a cloudflared binary on PATH is optional), aud-presence-check (AC-13301-1, AC-13302-1; SIMULATE_AUD_DROP mutation; runs on both fixture variants and asserts the sidecar-read shape flips), real-account-connector-healthy (AC-13002-1; accountBound on CI_HAS_CLOUDFLARE_ACCOUNT plus CI_HAS_HETZNER_ACCOUNT), real-account-tunnel-hostname-routes (AC-13102-1 (secondary), AC-13301-1 (Access-gated sub-case); accountBound; the Access-gated sub-case additionally reads CI_HAS_CLOUDFLARE_ACCESS per Q4 ratification). Blueprint README, guide, CHANGELOG, docs/topics.md; shelf-wide topics.md sweep adding the edge-cloudflare-tunnel row across every prior blueprint; section 6a tunnelBridge row on packages/rcf-lite/docs/blueprint-authoring.md. New global topic minted: edgeIngressBridge. Repo chain: REQ-130..134, US-13001, 13002, 13101, 13102, 13201, 13301, 13302, 13401, TS-160 with eight TCs, FBS-150, CN-470, TAC-4001..4003, ADR-4001..4003 minted via rcf define create --id per HQ round-7 T-3 reserved-block ruling (REQ-130..139 / TS-160..169 / FBS-150..159 / CN-470..499). Base commit origin/main 6b4df05.",
21
+ "dependsOnFbsIds": []
22
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:24.739Z",
3
+ "updatedAt": "2026-09-07T23:53:41.232Z",
4
+ "description": "The provisioner module wraps the hcloud CLI verbs (or the raw Hetzner Cloud API when provisioningTool=raw-api) and is the sole reader of the Hetzner API token via security-secrets-management. It opens on the applying project's boot path and emits a provisionerReady lifecycle event with metadata-only fields (tool, apiHost, sha of the shim). Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07 (REQ-110..119 / TS-140..149 / FBS-130..139 / CN-410..439). Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-110",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: provisioner is sole reader of the Hetzner API token, opens on boot, fires provisionerReady event with metadata-only payload",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "httpApi",
16
+ "auth"
17
+ ],
18
+ "reason": "keyword-scan",
19
+ "classifiedAt": "2026-09-07T23:53:24.779Z",
20
+ "signals": [
21
+ {
22
+ "source": "title",
23
+ "shape": "httpApi",
24
+ "match": "API"
25
+ },
26
+ {
27
+ "source": "title",
28
+ "shape": "auth",
29
+ "match": "token"
30
+ },
31
+ {
32
+ "source": "description",
33
+ "shape": "httpApi",
34
+ "match": "API"
35
+ },
36
+ {
37
+ "source": "description",
38
+ "shape": "httpApi",
39
+ "match": "api"
40
+ },
41
+ {
42
+ "source": "description",
43
+ "shape": "httpApi",
44
+ "match": "API"
45
+ },
46
+ {
47
+ "source": "description",
48
+ "shape": "auth",
49
+ "match": "token"
50
+ },
51
+ {
52
+ "source": "description",
53
+ "shape": "httpApi",
54
+ "match": "api"
55
+ }
56
+ ]
57
+ }
58
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:24.971Z",
3
+ "updatedAt": "2026-09-07T23:53:41.419Z",
4
+ "description": "The applying project holds its server declarations as JSON documents under hetzner/servers/<name>.json, one file per server, matching a shipped JSON Schema that names type, location, image, ssh-key ids, firewall id, network id, cloud-init user-data path and labels. Applying the provisioner reads each manifest and creates a matching live server; the hetznerServerProvisioned event carries id, primary IPv4, location and server-type. Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-111",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: server manifest schema at hetzner/servers/*.json applies to a live Hetzner Cloud server",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "persistence"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-07T23:53:25.012Z",
19
+ "signals": [
20
+ {
21
+ "source": "title",
22
+ "shape": "persistence",
23
+ "match": "schema"
24
+ },
25
+ {
26
+ "source": "description",
27
+ "shape": "persistence",
28
+ "match": "Schema"
29
+ }
30
+ ]
31
+ }
32
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:25.205Z",
3
+ "updatedAt": "2026-09-07T23:53:41.612Z",
4
+ "description": "The cloud-init template shipped with the blueprint renders YAML that lands SSH key-only, root disabled, UFW default-deny incoming, DOCKER-USER iptables chain, fail2ban SSH jail and unattended-upgrades on every provisioned Hetzner server. A local render lint asserts the six baseline blocks are present in the rendered YAML before any provision runs. Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-112",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: cloud-init hardening baseline lands the six documented lines on the provisioned server",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "webUi"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-07T23:53:25.246Z",
19
+ "signals": [
20
+ {
21
+ "source": "description",
22
+ "shape": "webUi",
23
+ "match": "template"
24
+ },
25
+ {
26
+ "source": "description",
27
+ "shape": "webUi",
28
+ "match": "renders"
29
+ },
30
+ {
31
+ "source": "description",
32
+ "shape": "webUi",
33
+ "match": "render"
34
+ },
35
+ {
36
+ "source": "description",
37
+ "shape": "webUi",
38
+ "match": "rendered"
39
+ }
40
+ ]
41
+ }
42
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:25.436Z",
3
+ "updatedAt": "2026-09-07T23:53:41.809Z",
4
+ "description": "The firewall rule set lives inside the server manifest and is applied to the server at provision time. Rules: 22 permitted only from an operator-nominated set of source-prefix ranges; 80/443 permitted from anywhere for the reverse proxy; all other inbound traffic denied. Manifest schema validation refuses on a rule set that opens 22 to 0.0.0.0/0 or drops the 80/443 rules. Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-113",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: firewall shape restricts SSH to operator-nominated prefixes, permits 80/443, denies all else",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "httpApi",
16
+ "persistence"
17
+ ],
18
+ "reason": "keyword-scan",
19
+ "classifiedAt": "2026-09-07T23:53:25.477Z",
20
+ "signals": [
21
+ {
22
+ "source": "title",
23
+ "shape": "httpApi",
24
+ "match": "rest"
25
+ },
26
+ {
27
+ "source": "description",
28
+ "shape": "persistence",
29
+ "match": "schema"
30
+ }
31
+ ]
32
+ }
33
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:25.669Z",
3
+ "updatedAt": "2026-09-07T23:53:41.996Z",
4
+ "description": "The applying project elicits a snapshot cadence per ADR-3802 (default weekly, alternatives daily and off). When non-off, the scheduled snapshot runner fires the hcloud snapshot verb and tags the snapshot with server name and wall-clock time; a snapshot-on-demand verb fires the same shape. The hetznerSnapshotTaken event carries snapshot id and wall-clock time. Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-114",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: snapshot cadence elicited (weekly default, daily and off alternatives), snapshot-on-demand fires a tagged snapshot",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "none"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-07T23:53:25.710Z"
19
+ }
20
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "createdAt": "2026-09-07T23:53:25.903Z",
3
+ "updatedAt": "2026-09-07T23:53:42.183Z",
4
+ "description": "The provisioner facade emits four lifecycle events: provisionerReady, hetznerServerProvisioned, hetznerSnapshotTaken and hetznerServerDestroyed. Payloads are metadata-only: id, primary IPv4, location, server-type, snapshot id, wall-clock time. An event-secrecy probe asserts no event body carries the API token, an ssh private key, or a plaintext secret; a mutation that leaks a token into an event body FAILS the probe with a defensive-fake finding. Chain: HQ round-7 T-1 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-1 track of hetzner-round-7-spec-2026-09-07 section 5.1.",
5
+ "reqId": "REQ-115",
6
+ "prdId": "PRD-001",
7
+ "title": "T-1 deploy-hetzner-server v1.0.0 blueprint: four lifecycle events fire with metadata-only payloads and no secret leak",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "httpApi",
16
+ "auth"
17
+ ],
18
+ "reason": "keyword-scan",
19
+ "classifiedAt": "2026-09-07T23:53:25.943Z",
20
+ "signals": [
21
+ {
22
+ "source": "description",
23
+ "shape": "httpApi",
24
+ "match": "API"
25
+ },
26
+ {
27
+ "source": "description",
28
+ "shape": "auth",
29
+ "match": "token"
30
+ },
31
+ {
32
+ "source": "description",
33
+ "shape": "auth",
34
+ "match": "token"
35
+ }
36
+ ]
37
+ }
38
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:39:09.362Z",
3
+ "updatedAt": "2026-09-08T01:39:28.241Z",
4
+ "description": "The applying project runs its containerised services from a single compose.yaml at the repo root. Each service is one container. Networks and volumes are declared with explicit names. Non-secret config lives in a .env file loaded by compose. The compose file is the single source of truth for the runtime topology; the container host reads it to bring the stack up and refuses on unclassified or malformed shape. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07 (REQ-120..129 / TS-150..159 / FBS-140..149 / CN-440..469). Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-120",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host v1.0.0 blueprint: compose.yaml at repo root is the source of truth (service-per-container, named networks and volumes, .env for non-secret config)",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "none"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:39:09.405Z"
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:40:03.788Z",
3
+ "updatedAt": "2026-09-08T01:40:04.018Z",
4
+ "description": "Every secret used by any compose service is injected as a file mount under the compose secrets top-level key. The compose file contains no plaintext secret literal on any service argument, environment variable, or command clause (grep-refuse). When security-secrets-management is applied, the secret is sourced through that facade; when it is not, the guide names a documented file-based fallback path. The mounted secret file lands at mode 0o400 inside the container. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-121",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host: secrets as file mounts, no plaintext literal in compose (grep-refuse); references security-secrets-management when applied",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "none"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:40:03.831Z"
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:40:04.204Z",
3
+ "updatedAt": "2026-09-08T01:40:04.433Z",
4
+ "description": "Every service that terminates HTTP declares a healthcheck block. The compose file refuses at docker compose config time when any HTTP-terminating service is missing the block. The healthcheck defaults per service kind are elicited (http default, tcp and command alternatives). The stack is not considered up until every declared service reaches healthy inside the elicited timeout. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-122",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host: healthcheck contract on every HTTP-terminating service refuses at docker compose config on missing",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "none"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:40:04.247Z"
19
+ }
20
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:40:04.619Z",
3
+ "updatedAt": "2026-09-08T01:40:04.848Z",
4
+ "description": "Every service declares a restart policy. Long-running services declare restart: unless-stopped. Jobs (short-lived services that exit after completion) declare restart: on-failure. Any service that declares neither, or declares an unclassified value outside the two allowed policies, refuses at the compose-config-lint gate before docker compose up runs. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-123",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host: restart discipline (unless-stopped on long-running, on-failure on jobs); refuses at lint on unclassified",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "httpApi"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:40:04.662Z",
19
+ "signals": [
20
+ {
21
+ "source": "title",
22
+ "shape": "httpApi",
23
+ "match": "rest"
24
+ },
25
+ {
26
+ "source": "description",
27
+ "shape": "httpApi",
28
+ "match": "rest"
29
+ },
30
+ {
31
+ "source": "description",
32
+ "shape": "httpApi",
33
+ "match": "rest"
34
+ },
35
+ {
36
+ "source": "description",
37
+ "shape": "httpApi",
38
+ "match": "rest"
39
+ }
40
+ ]
41
+ }
42
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:40:05.035Z",
3
+ "updatedAt": "2026-09-08T01:40:05.264Z",
4
+ "description": "The reverse-proxy config file (caddy/Caddyfile when reverseProxy=caddy; traefik/traefik.yaml when reverseProxy=traefik) is a first-class versioned artefact under the applying repo. The compose runtime bind-mounts the file into the proxy service so an operator change to the file is picked up by the reload verb. The reload verb is docker compose exec caddy caddy reload when Caddy, or the documented Traefik equivalent. The reload window is elicited (10 s default). During the window a client burst against the proxy sees no non-2xx and no dropped connection. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-124",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host: zero-downtime reverse-proxy reload via bind-mounted config; verb per proxy; no non-2xx or dropped connection inside the elicited window (10 s default)",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "webUi"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:40:05.078Z",
19
+ "signals": [
20
+ {
21
+ "source": "description",
22
+ "shape": "webUi",
23
+ "match": "sees"
24
+ }
25
+ ]
26
+ }
27
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "createdAt": "2026-09-08T01:40:05.460Z",
3
+ "updatedAt": "2026-09-08T01:40:05.690Z",
4
+ "description": "Every container writes stdout and stderr through the elicited log driver. Journald is the shipped default matching the Debian 12 and Ubuntu 24.04 baselines the T-1 cloud-init sets up. Loki is the opt-in alternative when the applying project runs Grafana. The choice is elicited via the log-driver ADR. When observability-logging is applied, the compose file wires the elicited driver to that companion. Chain: HQ round-7 T-2 reserved-block per HQ chain-block ruling 2026-09-07. Round-7 T-2 track of hetzner-round-7-spec-2026-09-07 section 5.2.",
5
+ "reqId": "REQ-125",
6
+ "prdId": "PRD-001",
7
+ "title": "T-2 platform-docker-compose-host: log shipping to the elicited observability-logging sink (journald default; loki opt-in when the project runs Grafana)",
8
+ "category": "functional",
9
+ "domain": "functional",
10
+ "priority": "must",
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "shapeClassification": {
14
+ "shapes": [
15
+ "none"
16
+ ],
17
+ "reason": "keyword-scan",
18
+ "classifiedAt": "2026-09-08T01:40:05.504Z"
19
+ }
20
+ }