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
+ // `rcf define blueprint dispositions <slug> [--json]` sub-verb.
2
+ // Read-only view over the per-slug disposition ledger written by
3
+ // `disposition-ledger.js`. Emits either a human-readable table (one
4
+ // AC per line) or a JSON dump.
5
+
6
+ import { readLedger, ledgerRelPath } from './disposition-ledger.js';
7
+
8
+ /**
9
+ * @param {object} args
10
+ * @param {string} args.projectRoot
11
+ * @param {string} args.slug
12
+ * @param {boolean} [args.asJson]
13
+ * @returns {Promise<{ output: string, exitCode: number }>}
14
+ */
15
+ export async function renderDispositions({ projectRoot, slug, asJson = false }) {
16
+ const doc = await readLedger(projectRoot, slug);
17
+ if (!doc) {
18
+ if (asJson) {
19
+ return {
20
+ output: `${JSON.stringify({ slug, present: false, ledgerPath: ledgerRelPath(slug), records: [] }, null, 2)}\n`,
21
+ exitCode: 0,
22
+ };
23
+ }
24
+ return {
25
+ output: `[blueprint] no disposition ledger found for '${slug}' at ${ledgerRelPath(slug)}\n`,
26
+ exitCode: 0,
27
+ };
28
+ }
29
+ if (asJson) {
30
+ return {
31
+ output: `${JSON.stringify({ slug, present: true, ledgerPath: ledgerRelPath(slug), records: doc.records }, null, 2)}\n`,
32
+ exitCode: 0,
33
+ };
34
+ }
35
+ const lines = [`[blueprint] '${slug}' disposition ledger (${doc.records.length} record(s)) at ${ledgerRelPath(slug)}:`];
36
+ for (const rec of doc.records) {
37
+ const parts = [rec.acId, rec.storyId, rec.action];
38
+ if (rec.reason) parts.push(`reason: ${rec.reason}`);
39
+ if (rec.resolvedAt) parts.push(`resolvedAt: ${rec.resolvedAt}`);
40
+ if (rec.escalatedAt) parts.push(`escalatedAt: ${rec.escalatedAt}`);
41
+ lines.push(` ${parts.join(' ')}`);
42
+ }
43
+ return { output: `${lines.join('\n')}\n`, exitCode: 0 };
44
+ }
@@ -62,3 +62,22 @@ export {
62
62
  parseUstar,
63
63
  sha256Hex,
64
64
  } from './library-fetcher-tarball.js';
65
+ export {
66
+ loadForLint,
67
+ loadSuppressions,
68
+ runLint,
69
+ runPass1,
70
+ runPass2,
71
+ } from './consistency-lint.js';
72
+ export {
73
+ APPLY_DISPOSITION_PROMPT,
74
+ LEDGER_SCHEMA_NOTE,
75
+ initialiseLedger,
76
+ ledgerAbsPath,
77
+ ledgerExists,
78
+ ledgerRelPath,
79
+ readLedger,
80
+ upsertLedgerRecord,
81
+ writeLedger,
82
+ } from './disposition-ledger.js';
83
+ export { renderDispositions } from './dispositions.js';
@@ -94,7 +94,10 @@ export function composeBrowserVerificationRecord({
94
94
  invariantChecks, authSmokeChecks = [], probePacks = [], notes, now = new Date(),
95
95
  }) {
96
96
  const id = nextBrowserVerificationId(manifest, fbsId);
97
- const verdict = aggregateVerdict(invariantChecks, authSmokeChecks, probePacks);
97
+ const composedProbePacks = Array.isArray(probePacks)
98
+ ? probePacks.map(remapPackForPositiveEvidence)
99
+ : probePacks;
100
+ const verdict = aggregateVerdict(invariantChecks, authSmokeChecks, composedProbePacks);
98
101
  const record = {
99
102
  id,
100
103
  fbsId,
@@ -107,11 +110,59 @@ export function composeBrowserVerificationRecord({
107
110
  verdict,
108
111
  };
109
112
  if (authSmokeChecks && authSmokeChecks.length > 0) record.authSmokeChecks = authSmokeChecks;
110
- if (Array.isArray(probePacks) && probePacks.length > 0) record.probePacks = probePacks;
113
+ if (Array.isArray(composedProbePacks) && composedProbePacks.length > 0) record.probePacks = composedProbePacks;
111
114
  if (typeof notes === 'string' && notes.length > 0) record.notes = notes;
112
115
  return record;
113
116
  }
114
117
 
118
+ /**
119
+ * Positive-evidence remap (authoring standard section 7d / section 8c).
120
+ *
121
+ * A `checks[]` or `preChecks[]` record with `verdict: 'pass'` is legal
122
+ * only when it carries either an `evidence` field of one of the four
123
+ * shapes named in section 7d (a request id, a response body excerpt, a
124
+ * created-then-deleted resource id in an inventory diff, or a
125
+ * rendered-bytes hash), or an `accountBoundSkipped: true` field with a
126
+ * non-empty `reason`. A pass record with neither is remapped to
127
+ * `verdict: 'fail'` with `detail: 'positive-evidence-missing'` at
128
+ * record-composition time; the composed record is what the manifest
129
+ * carries so the fail surfaces at the ship gate.
130
+ *
131
+ * @param {object} pack
132
+ * @returns {object}
133
+ */
134
+ function remapPackForPositiveEvidence(pack) {
135
+ if (!pack || typeof pack !== 'object') return pack;
136
+ const nextPack = { ...pack };
137
+ if (Array.isArray(pack.checks)) {
138
+ nextPack.checks = pack.checks.map(remapCheckForPositiveEvidence);
139
+ }
140
+ if (Array.isArray(pack.preChecks)) {
141
+ nextPack.preChecks = pack.preChecks.map(remapCheckForPositiveEvidence);
142
+ }
143
+ return nextPack;
144
+ }
145
+
146
+ function remapCheckForPositiveEvidence(check) {
147
+ if (!check || typeof check !== 'object') return check;
148
+ if (check.verdict !== 'pass') return check;
149
+ if (checkCarriesPositiveEvidence(check)) return check;
150
+ return { ...check, verdict: 'fail', detail: 'positive-evidence-missing' };
151
+ }
152
+
153
+ function checkCarriesPositiveEvidence(check) {
154
+ if (check.accountBoundSkipped === true) {
155
+ const reason = check.reason;
156
+ if (typeof reason === 'string' && reason.length > 0) return true;
157
+ return false;
158
+ }
159
+ if (check.evidence != null) {
160
+ if (typeof check.evidence === 'string') return check.evidence.length > 0;
161
+ if (typeof check.evidence === 'object') return true;
162
+ }
163
+ return false;
164
+ }
165
+
115
166
  function stripSeverity(check) {
116
167
  const out = { invariant: check.invariant, verdict: check.verdict };
117
168
  if (typeof check.detail === 'string' && check.detail.length > 0) out.detail = check.detail;
@@ -81,10 +81,16 @@ export async function runProbePacksForFbs({
81
81
  for (const pre of pack.preChecks) {
82
82
  let verdict = 'pass';
83
83
  let detail;
84
+ let preEvidence;
85
+ let preAccountBoundSkipped;
86
+ let preReason;
84
87
  try {
85
88
  const outcome = await pre.run({ fbs, uiBaseline, manifest, runtimeUrl, fetch, browser });
86
89
  verdict = outcome?.verdict ?? 'pass';
87
90
  detail = outcome?.detail;
91
+ preEvidence = outcome?.evidence;
92
+ preAccountBoundSkipped = outcome?.accountBoundSkipped;
93
+ preReason = outcome?.reason;
88
94
  } catch (err) {
89
95
  verdict = 'fail';
90
96
  detail = `pre-check threw: ${err.message}`;
@@ -94,6 +100,9 @@ export async function runProbePacksForFbs({
94
100
  verdict,
95
101
  severity: pre.severity,
96
102
  ...(typeof detail === 'string' && detail.length > 0 ? { detail } : {}),
103
+ ...(preEvidence != null ? { evidence: preEvidence } : {}),
104
+ ...(preAccountBoundSkipped === true ? { accountBoundSkipped: true } : {}),
105
+ ...(typeof preReason === 'string' && preReason.length > 0 ? { reason: preReason } : {}),
97
106
  });
98
107
  if (verdict === 'fail') failedPreCheckIds.add(pre.id);
99
108
  if (verdict === 'fail' && pre.severity === 'block') highest = 'block';
@@ -154,10 +163,16 @@ export async function runProbePacksForFbs({
154
163
  : { browser, fetch, runtimeUrl, route: primaryRoute, theme: primaryTheme, projectRoot };
155
164
  let verdict = 'pass';
156
165
  let detail;
166
+ let checkEvidence;
167
+ let checkAccountBoundSkipped;
168
+ let checkReason;
157
169
  try {
158
170
  const outcome = await check.run(context);
159
171
  verdict = outcome?.verdict ?? 'pass';
160
172
  detail = outcome?.detail;
173
+ checkEvidence = outcome?.evidence;
174
+ checkAccountBoundSkipped = outcome?.accountBoundSkipped;
175
+ checkReason = outcome?.reason;
161
176
  } catch (err) {
162
177
  verdict = 'fail';
163
178
  detail = `check threw: ${err.message}`;
@@ -167,6 +182,9 @@ export async function runProbePacksForFbs({
167
182
  verdict,
168
183
  severity: check.severity,
169
184
  ...(typeof detail === 'string' && detail.length > 0 ? { detail } : {}),
185
+ ...(checkEvidence != null ? { evidence: checkEvidence } : {}),
186
+ ...(checkAccountBoundSkipped === true ? { accountBoundSkipped: true } : {}),
187
+ ...(typeof checkReason === 'string' && checkReason.length > 0 ? { reason: checkReason } : {}),
170
188
  });
171
189
  if (verdict === 'fail' && check.severity === 'block') highest = 'block';
172
190
  else if (verdict === 'fail' && check.severity === 'warn' && highest !== 'block') highest = 'warn';
@@ -36,6 +36,12 @@ import {
36
36
  } from '../blueprint/index.js';
37
37
  import { conflictReportJson, renderConflictReport } from '../blueprint/conflicts.js';
38
38
  import { handleLibraryVerb, LIBRARY_HELP } from './blueprint-library.js';
39
+ import {
40
+ loadForLint,
41
+ loadSuppressions,
42
+ runLint,
43
+ renderDispositions,
44
+ } from '../blueprint/index.js';
39
45
 
40
46
  export const HELP = `Usage: rcf define blueprint <verb> [options]
41
47
 
@@ -115,6 +121,23 @@ Verbs:
115
121
  'rcf define blueprint library --help' for the
116
122
  full surface. Phase 2b covers local sources;
117
123
  network fetchers land in Phase 2c.
124
+ lint-consistency <source>
125
+ Run the single-definition ownership and REQ
126
+ delivery lint over one blueprint source (pass 1
127
+ catches literals restated outside their owning
128
+ TAC; pass 2 catches REQs promising properties
129
+ with no delivering TAC or ADR). Exit 0 on
130
+ clean, exit 3 on unsuppressed findings, exit 2
131
+ on usage error. --json emits the machine
132
+ envelope; pass-1 findings are suppressible via
133
+ a "Known chain-consistency-lint suppressions"
134
+ section in the blueprint README (see spec
135
+ section 5.8).
136
+ dispositions <slug> Read the per-slug disposition ledger at
137
+ rcf/blueprints/<slug>.disposition.json. Prints
138
+ one line per contributed AC with its recorded
139
+ disposition; --json emits the raw ledger.
140
+ Read-only.
118
141
 
119
142
  Options:
120
143
  --namespace <slug> Override the blueprint's default namespace
@@ -204,6 +227,11 @@ const OPTION_SPEC = {
204
227
  'allow-no-queue-yet': { type: 'boolean' },
205
228
  answer: { type: 'string', multiple: true },
206
229
  answers: { type: 'string' },
230
+ // Integration and contradiction protocol (spec 2026-09-09 section
231
+ // 3.6 and 7.1): the operator (or the wrapping harness) can suppress
232
+ // the disposition prompt printed after a fresh apply. The ledger is
233
+ // still written; only the human-facing prompt line is skipped.
234
+ 'no-disposition-prompt': { type: 'boolean' },
207
235
  };
208
236
 
209
237
  /**
@@ -244,6 +272,14 @@ export async function main(argv, deps = {}) {
244
272
  return handleLibraryVerb(parsed, rest, { stdout, stderr, cwd, now, stdin: deps.stdin });
245
273
  }
246
274
 
275
+ // `lint-consistency <source>` runs over a blueprint source directory
276
+ // and does not require an rcf/ tree; wire it before the projectRoot
277
+ // walk so it stays usable from a fresh clone (and from the shipping
278
+ // CI gate).
279
+ if (verb === 'lint-consistency') {
280
+ return handleLintConsistencyVerb({ rest, parsed, cwd, stdout, stderr });
281
+ }
282
+
247
283
  const projectRoot = await findProjectRoot(cwd);
248
284
  if (!projectRoot) {
249
285
  stderr.write('[error] no rcf/ tree found in this directory or any ancestor.\n');
@@ -433,6 +469,13 @@ export async function main(argv, deps = {}) {
433
469
  }
434
470
  if (!parsed.values.quiet) {
435
471
  stdout.write(`[blueprint] applied '${result.slug}' at ${result.version} (${result.contributions.length} contribution(s)).\n`);
472
+ // Disposition prompt (spec section 3.6 + 3.7). Printed once per
473
+ // fresh apply; a re-apply on the same slug omits it because the
474
+ // ledger is left untouched. Suppressible with the CLI flag
475
+ // --no-disposition-prompt.
476
+ if (result.dispositionPrompt && parsed.values['no-disposition-prompt'] !== true) {
477
+ stdout.write(`${result.dispositionPrompt}\n`);
478
+ }
436
479
  }
437
480
  // Companion-suggestion mechanism (spec 2.6). Runs AFTER the apply
438
481
  // writes so a failed apply never produces a suggestion block.
@@ -614,6 +657,17 @@ export async function main(argv, deps = {}) {
614
657
  });
615
658
  }
616
659
 
660
+ if (verb === 'dispositions') {
661
+ if (rest.length === 0) {
662
+ stderr.write('[error] blueprint dispositions: missing <slug>\n');
663
+ return 2;
664
+ }
665
+ const slug = rest[0];
666
+ const rendered = await renderDispositions({ projectRoot, slug, asJson: parsed.values.json === true });
667
+ stdout.write(rendered.output);
668
+ return rendered.exitCode;
669
+ }
670
+
617
671
  stderr.write(`[error] blueprint: unknown verb '${verb}'\n`);
618
672
  stderr.write(HELP);
619
673
  return 2;
@@ -850,6 +904,55 @@ function parseResolveOptions(rawList, reason) {
850
904
  * @param {{ stdin: NodeJS.ReadableStream, stdout: NodeJS.WritableStream }} deps
851
905
  * @returns {Promise<(prompt: string) => Promise<string>>}
852
906
  */
907
+ /**
908
+ * `rcf define blueprint lint-consistency <source>` handler. Resolves
909
+ * <source> (path or shelf slug), loads the blueprint via loadForLint,
910
+ * reads any suppressions in the blueprint's README, runs both passes,
911
+ * and prints either a human summary or a JSON envelope.
912
+ *
913
+ * Exit codes:
914
+ * 0 clean (or every finding suppressed)
915
+ * 2 usage error / cannot resolve source
916
+ * 3 unsuppressed findings
917
+ */
918
+ async function handleLintConsistencyVerb({ rest, parsed, cwd, stdout, stderr }) {
919
+ if (rest.length === 0) {
920
+ stderr.write('[error] blueprint lint-consistency: missing <source>\n');
921
+ return 2;
922
+ }
923
+ const rawSource = rest[0];
924
+ // Reuse the shipping shelf resolver so a bare slug (edge-cloudflare-turnstile)
925
+ // or a @stock/<slug> reference resolves to the packaged shelf, and a
926
+ // path resolves relative to cwd.
927
+ const resolved = await resolveBlueprintSource(rawSource, { projectRoot: cwd });
928
+ if (isRcfError(resolved)) {
929
+ stderr.write(`[error] blueprint lint-consistency: ${resolved.message}\n`);
930
+ return 2;
931
+ }
932
+ const sourcePath = resolved.resolved;
933
+ const loaded = await loadForLint(sourcePath);
934
+ if ('error' in loaded) {
935
+ stderr.write(`[error] blueprint lint-consistency: ${loaded.error}\n`);
936
+ return 2;
937
+ }
938
+ const suppressions = await loadSuppressions(sourcePath);
939
+ const result = runLint(loaded, suppressions);
940
+ const asJson = parsed.values.json === true;
941
+ if (asJson) {
942
+ stdout.write(`${JSON.stringify(result, null, 2)}\n`);
943
+ } else {
944
+ stdout.write(`[blueprint] lint-consistency '${result.blueprint}': ${result.verdict} `
945
+ + `(pass1=${result.passCounts.pass1}, pass2=${result.passCounts.pass2}, `
946
+ + `suppressed=${result.passCounts.suppressed})\n`);
947
+ for (const f of result.findings) {
948
+ const tag = f.suppressed ? '[suppressed]' : '[finding]';
949
+ stdout.write(` ${tag} ${f.id} (${f.pass}, ${f.kind}): ${f.message}\n`);
950
+ if (f.suppressed && f.suppressionReason) stdout.write(` reason: ${f.suppressionReason}\n`);
951
+ }
952
+ }
953
+ return result.verdict === 'pass' ? 0 : 3;
954
+ }
955
+
853
956
  async function createCustomAuthReadLine({ stdin, stdout }) {
854
957
  const { createInterface } = await import('node:readline');
855
958
  const rl = createInterface({ input: stdin, output: stdout, terminal: true });
@@ -57,6 +57,24 @@ _(how you like to work: casual or formal register, verbose or terse
57
57
  responses, willingness to be pushed back on, anything the agent should
58
58
  know before choosing its default posture)_
59
59
 
60
+ ## Register
61
+
62
+ _(how the agent should frame decisions when it needs your ruling. One
63
+ of the three values below on a single line; a line that reads only
64
+ \`unstated\` is fine and reads as productOwner on the first
65
+ escalation.)_
66
+
67
+ - \`productOwner\`: escalations arrive as one plain-English sentence
68
+ naming the decision and its consequences, then two or three named
69
+ choices with what each costs. No method vocabulary, no document ids.
70
+ - \`engineer\`: escalations name the AC id, quote the seed's assertion,
71
+ quote the project convention that conflicts, and ask a direct
72
+ question. Fluent in the method vocabulary.
73
+ - \`unstated\`: the agent asks you which register on the first
74
+ exchange after init and holds \`productOwner\` in the meantime.
75
+
76
+ unstated
77
+
60
78
  ## Project-scoped notes
61
79
 
62
80
  _(anything specific to this project that would be useful for the agent