rcf-lite 0.21.0 → 0.23.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 (458) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/bin/rcf.js +13 -2
  3. package/blueprints/application-account-settings/CHANGELOG.md +12 -0
  4. package/blueprints/application-account-settings/README.md +114 -0
  5. package/blueprints/application-account-settings/blueprint.json +234 -0
  6. package/blueprints/application-account-settings/contributions/adrs/adr-2601-application-account-settings-capability-vocabulary.json +20 -0
  7. package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +20 -0
  8. package/blueprints/application-account-settings/contributions/adrs/adr-2603-application-account-settings-theme-persistence.json +20 -0
  9. package/blueprints/application-account-settings/contributions/adrs/adr-2604-application-account-settings-reauth-window.json +20 -0
  10. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +18 -0
  11. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +18 -0
  12. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +18 -0
  13. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +18 -0
  14. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +18 -0
  15. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +18 -0
  16. package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +41 -0
  17. package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +28 -0
  18. package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +35 -0
  19. package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +40 -0
  20. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25101.json +34 -0
  21. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25102.json +27 -0
  22. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25103.json +27 -0
  23. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25104.json +27 -0
  24. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +33 -0
  25. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +27 -0
  26. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25107.json +27 -0
  27. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25108.json +27 -0
  28. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25109.json +33 -0
  29. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25110.json +27 -0
  30. package/blueprints/application-account-settings/docs/topics.md +50 -0
  31. package/blueprints/application-account-settings/guide/application-account-settings.md +30 -0
  32. package/blueprints/application-account-settings/probe-packs/application-account-settings.pack.mjs +246 -0
  33. package/blueprints/application-admin-console/docs/topics.md +9 -0
  34. package/blueprints/application-api-rest/docs/topics.md +10 -1
  35. package/blueprints/application-charts/docs/topics.md +9 -0
  36. package/blueprints/application-dashboard/docs/topics.md +9 -0
  37. package/blueprints/application-datatable/docs/topics.md +9 -0
  38. package/blueprints/application-empty-error-states/CHANGELOG.md +9 -0
  39. package/blueprints/application-empty-error-states/README.md +88 -0
  40. package/blueprints/application-empty-error-states/blueprint.json +119 -0
  41. package/blueprints/application-empty-error-states/contributions/adrs/adr-2301-application-empty-error-states-status-contract.json +25 -0
  42. package/blueprints/application-empty-error-states/contributions/adrs/adr-2302-application-empty-error-states-stack-trace-visibility.json +25 -0
  43. package/blueprints/application-empty-error-states/contributions/adrs/adr-2303-application-empty-error-states-offline-strategy.json +25 -0
  44. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +18 -0
  45. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +18 -0
  46. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +18 -0
  47. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +18 -0
  48. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +18 -0
  49. package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +46 -0
  50. package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +36 -0
  51. package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +40 -0
  52. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22101.json +29 -0
  53. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22102.json +29 -0
  54. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22103.json +29 -0
  55. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22104.json +29 -0
  56. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22105.json +29 -0
  57. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22106.json +29 -0
  58. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22107.json +29 -0
  59. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22108.json +29 -0
  60. package/blueprints/application-empty-error-states/docs/topics.md +55 -0
  61. package/blueprints/application-empty-error-states/guide/application-empty-error-states.md +50 -0
  62. package/blueprints/application-empty-error-states/probe-packs/application-empty-error-states.pack.mjs +284 -0
  63. package/blueprints/application-error-handling/docs/topics.md +9 -0
  64. package/blueprints/application-file-upload/CHANGELOG.md +9 -0
  65. package/blueprints/application-file-upload/README.md +85 -0
  66. package/blueprints/application-file-upload/blueprint.json +114 -0
  67. package/blueprints/application-file-upload/contributions/adrs/adr-2401-application-file-upload-transport.json +25 -0
  68. package/blueprints/application-file-upload/contributions/adrs/adr-2402-application-file-upload-accepted-set.json +25 -0
  69. package/blueprints/application-file-upload/contributions/adrs/adr-2403-application-file-upload-virus-scan.json +25 -0
  70. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +18 -0
  71. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +18 -0
  72. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +18 -0
  73. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +18 -0
  74. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +18 -0
  75. package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +46 -0
  76. package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +47 -0
  77. package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +46 -0
  78. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23101.json +28 -0
  79. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +28 -0
  80. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23103.json +29 -0
  81. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23104.json +28 -0
  82. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +29 -0
  83. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23106.json +28 -0
  84. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23107.json +28 -0
  85. package/blueprints/application-file-upload/docs/topics.md +60 -0
  86. package/blueprints/application-file-upload/guide/application-file-upload.md +48 -0
  87. package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +238 -0
  88. package/blueprints/application-forms-wizard/CHANGELOG.md +9 -0
  89. package/blueprints/application-forms-wizard/README.md +102 -0
  90. package/blueprints/application-forms-wizard/blueprint.json +120 -0
  91. package/blueprints/application-forms-wizard/contributions/adrs/adr-2501-application-forms-wizard-navigation.json +25 -0
  92. package/blueprints/application-forms-wizard/contributions/adrs/adr-2502-application-forms-wizard-save-and-return.json +25 -0
  93. package/blueprints/application-forms-wizard/contributions/adrs/adr-2503-application-forms-wizard-step-indicator.json +25 -0
  94. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +18 -0
  95. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +18 -0
  96. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +18 -0
  97. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +18 -0
  98. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +18 -0
  99. package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +46 -0
  100. package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +40 -0
  101. package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +40 -0
  102. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +28 -0
  103. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24102.json +29 -0
  104. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24103.json +28 -0
  105. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24104.json +29 -0
  106. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24105.json +28 -0
  107. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24106.json +28 -0
  108. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24107.json +28 -0
  109. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24108.json +29 -0
  110. package/blueprints/application-forms-wizard/docs/topics.md +51 -0
  111. package/blueprints/application-forms-wizard/guide/application-forms-wizard.md +48 -0
  112. package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +233 -0
  113. package/blueprints/application-notifications-in-app/docs/topics.md +9 -0
  114. package/blueprints/application-onboarding-tour/CHANGELOG.md +12 -0
  115. package/blueprints/application-onboarding-tour/README.md +77 -0
  116. package/blueprints/application-onboarding-tour/blueprint.json +164 -0
  117. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2701-application-onboarding-tour-dismissal-policy.json +20 -0
  118. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2702-application-onboarding-tour-completion-store-shape.json +20 -0
  119. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2703-application-onboarding-tour-checklist-anchor.json +20 -0
  120. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +18 -0
  121. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +18 -0
  122. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +18 -0
  123. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +18 -0
  124. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +41 -0
  125. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +35 -0
  126. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +34 -0
  127. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26101.json +27 -0
  128. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26102.json +27 -0
  129. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26103.json +27 -0
  130. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26104.json +27 -0
  131. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26105.json +27 -0
  132. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26106.json +27 -0
  133. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26107.json +27 -0
  134. package/blueprints/application-onboarding-tour/docs/topics.md +50 -0
  135. package/blueprints/application-onboarding-tour/guide/application-onboarding-tour.md +59 -0
  136. package/blueprints/application-onboarding-tour/probe-packs/application-onboarding-tour.pack.mjs +231 -0
  137. package/blueprints/application-spa/docs/topics.md +11 -2
  138. package/blueprints/delivery-ci-workflows/docs/topics.md +10 -1
  139. package/blueprints/deploy-cloudflare-workers/CHANGELOG.md +69 -0
  140. package/blueprints/deploy-cloudflare-workers/README.md +12 -0
  141. package/blueprints/deploy-cloudflare-workers/blueprint.json +234 -36
  142. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1306-deploy-cloudflare-workers-spa-shape.json +30 -0
  143. package/blueprints/deploy-cloudflare-workers/contributions/probes/assets-manifest-scan.mjs +207 -0
  144. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-013.json +18 -0
  145. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-014.json +18 -0
  146. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12113.json +36 -0
  147. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12114.json +27 -0
  148. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12115.json +27 -0
  149. package/blueprints/deploy-cloudflare-workers/docs/topics.md +11 -2
  150. package/blueprints/deploy-cloudflare-workers/guide/deploy-cloudflare-workers.md +25 -0
  151. package/blueprints/email-smtp-resend/docs/topics.md +10 -1
  152. package/blueprints/jobs-background/CHANGELOG.md +16 -0
  153. package/blueprints/jobs-background/README.md +105 -0
  154. package/blueprints/jobs-background/blueprint.json +149 -0
  155. package/blueprints/jobs-background/contributions/adrs/adr-3101-jobs-background-model.json +27 -0
  156. package/blueprints/jobs-background/contributions/adrs/adr-3102-jobs-background-scheduler-mode.json +25 -0
  157. package/blueprints/jobs-background/contributions/adrs/adr-3103-jobs-background-requires-applied-capabilities.json +25 -0
  158. package/blueprints/jobs-background/contributions/adrs/adr-3104-jobs-background-timeout-floor.json +25 -0
  159. package/blueprints/jobs-background/contributions/probes/apply-time-override.mjs +95 -0
  160. package/blueprints/jobs-background/contributions/probes/apply-time-refusal.mjs +82 -0
  161. package/blueprints/jobs-background/contributions/probes/event-secrecy.mjs +69 -0
  162. package/blueprints/jobs-background/contributions/probes/fake-clock-cron.mjs +65 -0
  163. package/blueprints/jobs-background/contributions/probes/probe-utils.mjs +91 -0
  164. package/blueprints/jobs-background/contributions/probes/retry-and-fail.mjs +65 -0
  165. package/blueprints/jobs-background/contributions/probes/run-apply-time-override.mjs +10 -0
  166. package/blueprints/jobs-background/contributions/probes/run-apply-time-refusal.mjs +11 -0
  167. package/blueprints/jobs-background/contributions/probes/run-event-secrecy.mjs +11 -0
  168. package/blueprints/jobs-background/contributions/probes/run-fake-clock-cron.mjs +11 -0
  169. package/blueprints/jobs-background/contributions/probes/run-retry-and-fail.mjs +11 -0
  170. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-001.json +18 -0
  171. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-002.json +18 -0
  172. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-003.json +18 -0
  173. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-004.json +18 -0
  174. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-005.json +18 -0
  175. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-006.json +18 -0
  176. package/blueprints/jobs-background/contributions/tacs/tac-3101-jobs-background-job-definition.json +50 -0
  177. package/blueprints/jobs-background/contributions/tacs/tac-3102-jobs-background-scheduler.json +50 -0
  178. package/blueprints/jobs-background/contributions/tacs/tac-3103-jobs-background-run-log.json +49 -0
  179. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30101.json +25 -0
  180. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30102.json +25 -0
  181. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30103.json +25 -0
  182. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30104.json +25 -0
  183. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30105.json +25 -0
  184. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30106.json +25 -0
  185. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30107.json +25 -0
  186. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30108.json +25 -0
  187. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30109.json +25 -0
  188. package/blueprints/jobs-background/docs/topics.md +62 -0
  189. package/blueprints/jobs-background/guide/jobs-background.md +147 -0
  190. package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +15 -0
  191. package/blueprints/messaging-queue-cloudflare/README.md +125 -0
  192. package/blueprints/messaging-queue-cloudflare/blueprint.json +67 -0
  193. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3001-messaging-queue-cloudflare-adapter.json +30 -0
  194. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3002-messaging-queue-cloudflare-delivery-semantics.json +25 -0
  195. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3003-messaging-queue-cloudflare-max-attempts-floor.json +25 -0
  196. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3004-messaging-queue-cloudflare-batch-defaults.json +25 -0
  197. package/blueprints/messaging-queue-cloudflare/contributions/probes/event-secrecy.mjs +137 -0
  198. package/blueprints/messaging-queue-cloudflare/contributions/probes/probe-utils.mjs +82 -0
  199. package/blueprints/messaging-queue-cloudflare/contributions/probes/producer-facade-ready.mjs +35 -0
  200. package/blueprints/messaging-queue-cloudflare/contributions/probes/publish-to-delivery.mjs +94 -0
  201. package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +54 -0
  202. package/blueprints/messaging-queue-cloudflare/contributions/probes/retry-and-dlq.mjs +87 -0
  203. package/blueprints/messaging-queue-cloudflare/contributions/probes/run-event-secrecy.mjs +5 -0
  204. package/blueprints/messaging-queue-cloudflare/contributions/probes/run-producer-facade-ready.mjs +11 -0
  205. package/blueprints/messaging-queue-cloudflare/contributions/probes/run-publish-to-delivery.mjs +5 -0
  206. package/blueprints/messaging-queue-cloudflare/contributions/probes/run-real-account-concurrency-smoke.mjs +5 -0
  207. package/blueprints/messaging-queue-cloudflare/contributions/probes/run-retry-and-dlq.mjs +5 -0
  208. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-001.json +18 -0
  209. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-002.json +18 -0
  210. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-003.json +18 -0
  211. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-004.json +18 -0
  212. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-005.json +18 -0
  213. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +18 -0
  214. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3001-messaging-queue-cloudflare-producer-facade.json +56 -0
  215. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3002-messaging-queue-cloudflare-consumer-registration.json +40 -0
  216. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3003-messaging-queue-cloudflare-event-sink.json +39 -0
  217. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29101.json +34 -0
  218. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29102.json +34 -0
  219. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29103.json +25 -0
  220. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29104.json +25 -0
  221. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29105.json +25 -0
  222. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29106.json +25 -0
  223. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29107.json +25 -0
  224. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29108.json +25 -0
  225. package/blueprints/messaging-queue-cloudflare/docs/topics.md +62 -0
  226. package/blueprints/messaging-queue-cloudflare/guide/messaging-queue-cloudflare.md +110 -0
  227. package/blueprints/object-storage-s3/CHANGELOG.md +13 -0
  228. package/blueprints/object-storage-s3/README.md +108 -0
  229. package/blueprints/object-storage-s3/blueprint.json +72 -0
  230. package/blueprints/object-storage-s3/contributions/adrs/adr-2901-object-storage-s3-adapter.json +30 -0
  231. package/blueprints/object-storage-s3/contributions/adrs/adr-2902-object-storage-s3-presigned-ttl-floor.json +25 -0
  232. package/blueprints/object-storage-s3/contributions/adrs/adr-2903-object-storage-s3-multipart-threshold.json +25 -0
  233. package/blueprints/object-storage-s3/contributions/adrs/adr-2904-object-storage-s3-contract.json +25 -0
  234. package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +103 -0
  235. package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +43 -0
  236. package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +84 -0
  237. package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +101 -0
  238. package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +85 -0
  239. package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +84 -0
  240. package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +64 -0
  241. package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +4 -0
  242. package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +10 -0
  243. package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +4 -0
  244. package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +4 -0
  245. package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +7 -0
  246. package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +4 -0
  247. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +18 -0
  248. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +18 -0
  249. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +18 -0
  250. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +18 -0
  251. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +18 -0
  252. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +18 -0
  253. package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +57 -0
  254. package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +36 -0
  255. package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +36 -0
  256. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +34 -0
  257. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +43 -0
  258. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +25 -0
  259. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +34 -0
  260. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +25 -0
  261. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +34 -0
  262. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28107.json +34 -0
  263. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28108.json +34 -0
  264. package/blueprints/object-storage-s3/docs/topics.md +64 -0
  265. package/blueprints/object-storage-s3/guide/object-storage-s3.md +207 -0
  266. package/blueprints/observability-essentials/docs/topics.md +10 -1
  267. package/blueprints/observability-logging/CHANGELOG.md +4 -0
  268. package/blueprints/observability-logging/README.md +3 -0
  269. package/blueprints/observability-logging/blueprint.json +3 -2
  270. package/blueprints/observability-logging/docs/topics.md +9 -0
  271. package/blueprints/observability-probe-endpoints/docs/topics.md +10 -1
  272. package/blueprints/persistence-data-d1/docs/topics.md +10 -1
  273. package/blueprints/persistence-data-postgres/CHANGELOG.md +12 -0
  274. package/blueprints/persistence-data-postgres/README.md +101 -0
  275. package/blueprints/persistence-data-postgres/blueprint.json +80 -0
  276. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +30 -0
  277. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2802-persistence-data-postgres-migration-shape.json +25 -0
  278. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2803-persistence-data-postgres-runner-mode.json +25 -0
  279. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2804-persistence-data-postgres-recovery.json +25 -0
  280. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2805-persistence-data-postgres-connection-pool-posture.json +25 -0
  281. package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +56 -0
  282. package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +75 -0
  283. package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +56 -0
  284. package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +186 -0
  285. package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +76 -0
  286. package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +173 -0
  287. package/blueprints/persistence-data-postgres/contributions/probes/run-facade-round-trip.mjs +10 -0
  288. package/blueprints/persistence-data-postgres/contributions/probes/run-migration-apply.mjs +10 -0
  289. package/blueprints/persistence-data-postgres/contributions/probes/run-pool-posture-smoke.mjs +9 -0
  290. package/blueprints/persistence-data-postgres/contributions/probes/run-prepared-statement-scan.mjs +10 -0
  291. package/blueprints/persistence-data-postgres/contributions/probes/run-recovery-restore-round-trip.mjs +9 -0
  292. package/blueprints/persistence-data-postgres/contributions/probes/run-transaction-atomicity.mjs +10 -0
  293. package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +79 -0
  294. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +18 -0
  295. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +18 -0
  296. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +18 -0
  297. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +18 -0
  298. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +18 -0
  299. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +18 -0
  300. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +18 -0
  301. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +58 -0
  302. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +40 -0
  303. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +35 -0
  304. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +40 -0
  305. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +34 -0
  306. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +25 -0
  307. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +25 -0
  308. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +25 -0
  309. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +25 -0
  310. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +25 -0
  311. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +25 -0
  312. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +25 -0
  313. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +25 -0
  314. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +25 -0
  315. package/blueprints/persistence-data-postgres/docs/topics.md +66 -0
  316. package/blueprints/persistence-data-postgres/guide/persistence-data-postgres.md +172 -0
  317. package/blueprints/persistence-data-sqlite/docs/topics.md +10 -1
  318. package/blueprints/security-auth-clerk/CHANGELOG.md +4 -0
  319. package/blueprints/security-auth-clerk/README.md +3 -0
  320. package/blueprints/security-auth-clerk/blueprint.json +147 -30
  321. package/blueprints/security-auth-clerk/docs/topics.md +10 -1
  322. package/blueprints/security-auth-keycloak/CHANGELOG.md +4 -0
  323. package/blueprints/security-auth-keycloak/README.md +3 -0
  324. package/blueprints/security-auth-keycloak/blueprint.json +182 -37
  325. package/blueprints/security-auth-keycloak/docs/topics.md +10 -1
  326. package/blueprints/security-auth-magic-link/CHANGELOG.md +4 -0
  327. package/blueprints/security-auth-magic-link/README.md +3 -0
  328. package/blueprints/security-auth-magic-link/blueprint.json +159 -33
  329. package/blueprints/security-auth-magic-link/docs/topics.md +10 -1
  330. package/blueprints/security-auth-oauth2/CHANGELOG.md +4 -0
  331. package/blueprints/security-auth-oauth2/README.md +3 -0
  332. package/blueprints/security-auth-oauth2/blueprint.json +158 -32
  333. package/blueprints/security-auth-oauth2/docs/topics.md +10 -1
  334. package/blueprints/security-secrets-management/CHANGELOG.md +11 -0
  335. package/blueprints/security-secrets-management/blueprint.json +2 -1
  336. package/blueprints/security-secrets-management/docs/topics.md +10 -1
  337. package/fixtures/canary-manifest.json +9 -9
  338. package/package.json +1 -1
  339. package/rcf/code-nodes/cn-134.json +13 -0
  340. package/rcf/code-nodes/cn-135.json +12 -0
  341. package/rcf/code-nodes/cn-136.json +13 -0
  342. package/rcf/code-nodes/cn-137.json +13 -0
  343. package/rcf/code-nodes/cn-138.json +12 -0
  344. package/rcf/code-nodes/cn-139.json +12 -0
  345. package/rcf/code-nodes/cn-140.json +13 -0
  346. package/rcf/code-nodes/cn-141.json +13 -0
  347. package/rcf/code-nodes/cn-142.json +12 -0
  348. package/rcf/code-nodes/cn-143.json +13 -0
  349. package/rcf/code-nodes/cn-144.json +13 -0
  350. package/rcf/code-nodes/cn-145.json +12 -0
  351. package/rcf/code-nodes/cn-146.json +12 -0
  352. package/rcf/code-nodes/cn-147.json +13 -0
  353. package/rcf/code-nodes/cn-148.json +13 -0
  354. package/rcf/code-nodes/cn-149.json +12 -0
  355. package/rcf/code-nodes/cn-150.json +13 -0
  356. package/rcf/code-nodes/cn-151.json +13 -0
  357. package/rcf/code-nodes/cn-152.json +12 -0
  358. package/rcf/code-nodes/cn-153.json +12 -0
  359. package/rcf/code-nodes/cn-154.json +13 -0
  360. package/rcf/code-nodes/cn-155.json +14 -0
  361. package/rcf/code-nodes/cn-156.json +13 -0
  362. package/rcf/code-nodes/cn-157.json +13 -0
  363. package/rcf/code-nodes/cn-158.json +12 -0
  364. package/rcf/code-nodes/cn-159.json +13 -0
  365. package/rcf/code-nodes/cn-160.json +12 -0
  366. package/rcf/code-nodes/cn-161.json +12 -0
  367. package/rcf/code-nodes/cn-162.json +13 -0
  368. package/rcf/code-nodes/cn-163.json +12 -0
  369. package/rcf/code-nodes/cn-164.json +13 -0
  370. package/rcf/code-nodes/cn-165.json +12 -0
  371. package/rcf/code-nodes/cn-166.json +12 -0
  372. package/rcf/code-nodes/cn-167.json +12 -0
  373. package/rcf/code-nodes/cn-168.json +12 -0
  374. package/rcf/code-nodes/cn-169.json +12 -0
  375. package/rcf/code-nodes/cn-170.json +12 -0
  376. package/rcf/code-nodes/cn-171.json +12 -0
  377. package/rcf/code-nodes/cn-172.json +12 -0
  378. package/rcf/code-nodes/cn-173.json +12 -0
  379. package/rcf/code-nodes/cn-174.json +12 -0
  380. package/rcf/code-nodes/cn-175.json +13 -0
  381. package/rcf/code-nodes/cn-176.json +12 -0
  382. package/rcf/code-nodes/cn-177.json +12 -0
  383. package/rcf/code-nodes/cn-178.json +12 -0
  384. package/rcf/code-nodes/cn-179.json +12 -0
  385. package/rcf/code-nodes/cn-180.json +13 -0
  386. package/rcf/code-nodes/cn-181.json +12 -0
  387. package/rcf/code-nodes/cn-182.json +13 -0
  388. package/rcf/code-nodes/cn-183.json +12 -0
  389. package/rcf/code-nodes/cn-184.json +13 -0
  390. package/rcf/code-nodes/cn-185.json +12 -0
  391. package/rcf/code-nodes/cn-186.json +12 -0
  392. package/rcf/code-nodes/cn-200.json +14 -0
  393. package/rcf/code-nodes/cn-201.json +13 -0
  394. package/rcf/code-nodes/cn-202.json +14 -0
  395. package/rcf/code-nodes/cn-203.json +14 -0
  396. package/rcf/code-nodes/cn-204.json +13 -0
  397. package/rcf/code-nodes/cn-205.json +14 -0
  398. package/rcf/code-nodes/cn-206.json +14 -0
  399. package/rcf/code-nodes/cn-207.json +13 -0
  400. package/rcf/code-nodes/cn-208.json +14 -0
  401. package/rcf/code-nodes/cn-209.json +14 -0
  402. package/rcf/code-nodes/cn-210.json +13 -0
  403. package/rcf/code-nodes/cn-211.json +12 -0
  404. package/rcf/code-nodes/cn-212.json +12 -0
  405. package/rcf/code-nodes/cn-213.json +12 -0
  406. package/rcf/code-nodes/cn-214.json +15 -0
  407. package/rcf/code-nodes/cn-215.json +13 -0
  408. package/rcf/code-nodes/cn-216.json +14 -0
  409. package/rcf/code-nodes/cn-217.json +13 -0
  410. package/rcf/fbs/fbs-043.json +23 -0
  411. package/rcf/fbs/fbs-044.json +23 -0
  412. package/rcf/fbs/fbs-045.json +23 -0
  413. package/rcf/fbs/fbs-046.json +24 -0
  414. package/rcf/fbs/fbs-047.json +24 -0
  415. package/rcf/fbs/fbs-060.json +22 -0
  416. package/rcf/fbs/fbs-061.json +20 -0
  417. package/rcf/fbs/fbs-062.json +20 -0
  418. package/rcf/fbs/fbs-063.json +22 -0
  419. package/rcf/fbs/fbs-064.json +23 -0
  420. package/rcf/requirements/req-024.json +69 -0
  421. package/rcf/requirements/req-025.json +59 -0
  422. package/rcf/requirements/req-026.json +154 -0
  423. package/rcf/requirements/req-027.json +33 -0
  424. package/rcf/requirements/req-028.json +13 -0
  425. package/rcf/requirements/req-029.json +57 -0
  426. package/rcf/requirements/req-030.json +67 -0
  427. package/rcf/requirements/req-040.json +13 -0
  428. package/rcf/requirements/req-041.json +125 -0
  429. package/rcf/requirements/req-042.json +59 -0
  430. package/rcf/requirements/req-043.json +39 -0
  431. package/rcf/test-suites/ts-053.json +70 -0
  432. package/rcf/test-suites/ts-054.json +70 -0
  433. package/rcf/test-suites/ts-055.json +77 -0
  434. package/rcf/test-suites/ts-056.json +78 -0
  435. package/rcf/test-suites/ts-057.json +78 -0
  436. package/rcf/test-suites/ts-070.json +62 -0
  437. package/rcf/test-suites/ts-071.json +62 -0
  438. package/rcf/test-suites/ts-072.json +62 -0
  439. package/rcf/test-suites/ts-073.json +38 -0
  440. package/rcf/test-suites/ts-074.json +30 -0
  441. package/rcf/test-suites/ts-075.json +38 -0
  442. package/rcf/test-suites/ts-076.json +70 -0
  443. package/rcf/user-stories/us-2401.json +62 -0
  444. package/rcf/user-stories/us-2501.json +58 -0
  445. package/rcf/user-stories/us-2601.json +51 -0
  446. package/rcf/user-stories/us-2701.json +55 -0
  447. package/rcf/user-stories/us-2801.json +55 -0
  448. package/rcf/user-stories/us-2901.json +45 -0
  449. package/rcf/user-stories/us-2902.json +36 -0
  450. package/rcf/user-stories/us-3001.json +45 -0
  451. package/rcf/user-stories/us-4001.json +69 -0
  452. package/rcf/user-stories/us-4101.json +69 -0
  453. package/rcf/user-stories/us-4201.json +69 -0
  454. package/rcf/user-stories/us-4301.json +78 -0
  455. package/releases/releases.yaml +21 -1
  456. package/src/blueprint/apply.js +13 -1
  457. package/src/blueprint/capabilities.js +66 -2
  458. package/src/cli/blueprint.js +15 -1
@@ -0,0 +1,25 @@
1
+ {
2
+ "adrId": "ADR-2803-persistence-data-postgres-runner-mode",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "Migration runner mode: atBoot on long-lived Node, ciStep on Workers-adjacent or container-scheduled targets; elicited",
8
+ "context": "A long-lived Node process can run migrations at boot before opening the first request; a Workers-adjacent or serverless target cannot because the boot happens per invocation and does not amortise the migration cost. A container platform running warm instances behaves like long-lived Node but a fresh-per-request container behaves like Workers.",
9
+ "decision": "The migration runner mode is elicited: atBoot (the facade invokes the runner on process start before opening the first query) or ciStep (the CI pipeline invokes the runner as a deploy step before promoting the artefact). Default atBoot for long-lived Node targets; default ciStep for Workers-adjacent, request-scoped container, or Hyperdrive-fronted (round-6) targets. The applying project answers the elicit at apply time; the sidecar records the answer.",
10
+ "consequences": "Long-lived Node targets get zero-config migrations that run before the first request; the operator sees the migrationsApplied event in the process log and knows the schema advanced. Workers-adjacent targets get a CI-step that runs against the deploy target's own connection before the artefact promotes; the operator sees the runner's stdout in the CI log. A project moving from long-lived Node to Workers-adjacent updates the elicit and re-applies; no code moves. Standards trace clause: generic enterprise practice.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "Always atBoot",
14
+ "summary": "Ship atBoot as the only mode; the operator schedules a boot on the CI runner for ciStep-like behaviour.",
15
+ "reasonNotChosen": "A Workers-adjacent deploy has no long-lived boot event to hang the runner on; the operator would have to build a boot shim just to run migrations, which is the ciStep in disguise. Eliciting the mode is cheaper."
16
+ },
17
+ {
18
+ "name": "Always ciStep",
19
+ "summary": "Ship ciStep as the only mode; a long-lived Node process reads schema_version at boot and refuses to open if it is behind.",
20
+ "reasonNotChosen": "Local development on long-lived Node loses zero-config migrations; every developer has to invoke the CI step by hand. atBoot as the default for long-lived Node keeps the developer flow ergonomic."
21
+ }
22
+ ],
23
+ "createdAt": "2026-09-06T15:47:00.000Z",
24
+ "updatedAt": "2026-09-06T15:47:00.000Z"
25
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "adrId": "ADR-2804-persistence-data-postgres-recovery",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "Two-path recovery: scheduled pg_dump artefact PLUS vendor point-in-time recovery, both required, cadence elicited",
8
+ "context": "A shipped Postgres project has to survive two failure classes: a corrupted or lost cluster (a managed-Postgres outage, a self-managed disk failure, a bad DBA operation) and a data-integrity incident an operator wants to unwind by minutes or hours (a bug that deleted rows, a bad migration a rollback file cannot invert). pg_dump gives a portable off-cluster artefact; vendor PITR (a managed cluster's window, a self-managed cluster's WAL-archive posture) gives fine-grained restore points. Neither alone covers both failure classes.",
9
+ "decision": "The shipped recovery model requires both paths: (a) a scheduled pg_dump runner (TAC-2804) writes an artefact to the elicited destination on an elicited cadence, and (b) the deploy target's own point-in-time recovery is enabled with an elicited PITR window (a managed cluster's retention setting; a self-managed cluster's WAL-archive retention). Neither path is optional; a project that answers off to either fails the ADR's apply-time check. A recovery drill (US-27110) periodically primes a fresh Postgres from the artefact and compares row-count and checksum against the source; the drill's cadence is elicited.",
10
+ "consequences": "The project survives both failure classes: a portable off-cluster artefact for cluster loss and a fine-grained PITR window for data-integrity incidents. Storage cost is two-path (artefact bytes off-cluster plus WAL retention on-cluster); the operator sizes both per RTO/RPO. The drill catches artefact-shape drift (a pg_dump on a new engine version producing a different plain-format shape) before an incident forces a live restore. Standards trace clause: generic enterprise practice.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "pg_dump only",
14
+ "summary": "Ship pg_dump as the sole recovery path; skip vendor PITR.",
15
+ "reasonNotChosen": "A pg_dump artefact taken hourly can lose up to 59 minutes of writes; an operator restoring after a bad migration loses everything committed between the last dump and the incident. PITR bounds that loss to the WAL-shipping cadence."
16
+ },
17
+ {
18
+ "name": "PITR only",
19
+ "summary": "Rely on the deploy target's own PITR window; skip the pg_dump runner.",
20
+ "reasonNotChosen": "PITR does not survive cluster loss: if the managed cluster is gone, the retention window is gone with it. A portable off-cluster artefact is what carries across cluster loss."
21
+ }
22
+ ],
23
+ "createdAt": "2026-09-06T15:47:00.000Z",
24
+ "updatedAt": "2026-09-06T15:47:00.000Z"
25
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "adrId": "ADR-2805-persistence-data-postgres-connection-pool-posture",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "Connection-pool posture per deploy target: long-lived pool on Node, request-scoped pool on container, delegated to Hyperdrive on Workers-adjacent (v1.1.0)",
8
+ "context": "Postgres has real connection cost per open (TCP handshake, TLS negotiation, authentication, role setup). A long-lived Node process wants one pool per process amortising that cost across every request. A request-scoped container platform (a serverless-container target spinning fresh instances per request) cannot hold a long-lived pool because the instance dies at request end; each instance opens a pool for its request budget. A Workers-adjacent target via the round-6 Hyperdrive v1.1.0 adapter delegates the pool entirely to Cloudflare's Hyperdrive-managed pool.",
9
+ "decision": "The pool posture is elicited per deploy target: longLivedNode (default: long-lived pg.Pool for the process lifetime), requestScopedContainer (a pool sized to the request budget, disposed at request end), or hyperdriveManaged (reserved for the round-6 v1.1.0 adapter). The shipped defaults per posture: longLivedNode pool size 10 with idleTimeoutMillis 30000 and connectionTimeoutMillis 5000 (matching pg's own defaults); requestScopedContainer pool size 2 with idleTimeoutMillis 5000 and connectionTimeoutMillis 3000; hyperdriveManaged inherits Hyperdrive's own pool settings and holds no Node-side pool. Every default is overridable by the operator via elicited pool-config fields at apply time.",
10
+ "consequences": "The project gets the pool posture appropriate to its deploy target without a code change: a longLivedNode app on Kubernetes and a longLivedNode app on a self-managed VM share the same shipped default; a requestScopedContainer app on a serverless-container platform gets a small per-request pool; a round-6 Workers app inherits Hyperdrive's pool. The pool-posture-smoke probe drives twenty concurrent queries at pool size 5 and asserts no timeout; the probe does not impose a sizing formula so operator overrides are safe. Standards trace clause: generic enterprise practice.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "One pool posture (longLivedNode) for every target",
14
+ "summary": "Ship the long-lived pool as the only posture; a request-scoped container platform holds the pool for the instance lifetime.",
15
+ "reasonNotChosen": "A fresh-per-request container that holds a long-lived pool re-pays the connection cost on every instance. Sizing the pool for a request-scoped instance is different from sizing it for a long-lived process; conflating them under one default surprises the operator."
16
+ },
17
+ {
18
+ "name": "Delegate every pool to Hyperdrive from v1.0.0",
19
+ "summary": "Ship Hyperdrive as the pool manager for every target.",
20
+ "reasonNotChosen": "Hyperdrive is a Cloudflare-account-bound service; forcing every project to bind to Cloudflare before applying the blueprint conflicts with the local-first posture (round-5 spec ruling 5, Baz decision 8). Round 6 lands Hyperdrive as an elicit for the operator who wants it."
21
+ }
22
+ ],
23
+ "createdAt": "2026-09-06T15:47:00.000Z",
24
+ "updatedAt": "2026-09-06T15:47:00.000Z"
25
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Facade round-trip probe.
3
+ *
4
+ * Opens the fixture's facade against a running postgres:17-alpine
5
+ * container, drives a put-and-get through the named domain verbs,
6
+ * asserts facadeReady fires on the injected event sink and the
7
+ * round-trip returns the row written.
8
+ *
9
+ * Anchors AC-27101-1 (facade opens on boot and facadeReady fires with
10
+ * the database name).
11
+ *
12
+ * Cleans up: TRUNCATE users on exit; closes the pool.
13
+ */
14
+
15
+ import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
16
+
17
+ export default async function runProbe() {
18
+ const events = [];
19
+ const store = createStore({
20
+ connectionUrl: connectionUrlFromEnv(),
21
+ onEvent: (e) => events.push(e),
22
+ });
23
+ const results = [];
24
+ try {
25
+ await store.ready();
26
+ // Ensure a clean users table for this probe run
27
+ const pool = store.getPool();
28
+ await pool.query('CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE, created_at TIMESTAMPTZ NOT NULL DEFAULT now())');
29
+ await pool.query('TRUNCATE users');
30
+ const facadeReadyFired = events.some((e) => e.event === 'facadeReady');
31
+ const facadeReadyDbName = facadeReadyFired ? events.find((e) => e.event === 'facadeReady').databaseName : null;
32
+ results.push({
33
+ anchorAcId: 'AC-27101-1',
34
+ verdict: facadeReadyFired && facadeReadyDbName === 'rcf_test' ? 'pass' : 'fail',
35
+ detail: facadeReadyFired
36
+ ? `facadeReady fired with databaseName=${facadeReadyDbName}`
37
+ : 'facadeReady did not fire before first query',
38
+ });
39
+ const id = await store.createUser('probe-facade-round-trip', 'facade-round-trip@rcf.test');
40
+ const row = await store.getUserById(id);
41
+ const roundTripPass = row && row.id === id && row.name === 'probe-facade-round-trip';
42
+ results.push({
43
+ anchorAcId: 'AC-27101-1',
44
+ verdict: roundTripPass ? 'pass' : 'fail',
45
+ detail: roundTripPass
46
+ ? `round-trip put id=${id} and got name=${row.name}`
47
+ : `round-trip failed: id=${id}, row=${JSON.stringify(row)}`,
48
+ });
49
+ } finally {
50
+ try {
51
+ await store.getPool().query('TRUNCATE users');
52
+ } catch { /* ignore */ }
53
+ await store.close();
54
+ }
55
+ return results;
56
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Migration apply probe.
3
+ *
4
+ * Drops any prior schema (users, schema_version) from the fixture's
5
+ * Postgres, invokes the fixture's migration runner, and asserts every
6
+ * migration applied inside its own transaction, migrationsApplied fires
7
+ * with the filename list, and the schema_version bookkeeping table
8
+ * records three rows.
9
+ *
10
+ * Anchors AC-27102-1 (three forward-only .sql migrations apply one file
11
+ * one transaction; migrationsApplied fires with the filename list).
12
+ *
13
+ * Cleans up: leaves the applied schema for downstream probes.
14
+ */
15
+
16
+ import { applyAll } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/migrate.mjs';
17
+ import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
18
+
19
+ async function resetSchema(url) {
20
+ const store = createStore({ connectionUrl: url });
21
+ try {
22
+ await store.ready();
23
+ const pool = store.getPool();
24
+ await pool.query('DROP TABLE IF EXISTS users CASCADE');
25
+ await pool.query('DROP TABLE IF EXISTS schema_version CASCADE');
26
+ } finally {
27
+ await store.close();
28
+ }
29
+ }
30
+
31
+ export default async function runProbe() {
32
+ const url = connectionUrlFromEnv();
33
+ await resetSchema(url);
34
+ const events = [];
35
+ const { applied } = await applyAll({
36
+ connectionUrl: url,
37
+ onEvent: (e) => events.push(e),
38
+ });
39
+ const results = [];
40
+ const expected = ['001_create_users.sql', '002_add_email_unique.sql', '003_add_created_at.sql'];
41
+ const listsEqual = applied.length === expected.length
42
+ && expected.every((f, i) => applied[i] === f);
43
+ results.push({
44
+ anchorAcId: 'AC-27102-1',
45
+ verdict: listsEqual ? 'pass' : 'fail',
46
+ detail: `applied=${JSON.stringify(applied)} expected=${JSON.stringify(expected)}`,
47
+ });
48
+ const migratedEvent = events.find((e) => e.event === 'migrationsApplied');
49
+ const eventFiredCorrectly = migratedEvent
50
+ && Array.isArray(migratedEvent.applied)
51
+ && migratedEvent.applied.length === expected.length;
52
+ results.push({
53
+ anchorAcId: 'AC-27102-1',
54
+ verdict: eventFiredCorrectly ? 'pass' : 'fail',
55
+ detail: eventFiredCorrectly
56
+ ? `migrationsApplied fired with applied=${JSON.stringify(migratedEvent.applied)}`
57
+ : `migrationsApplied event missing or wrong shape; events=${JSON.stringify(events)}`,
58
+ });
59
+ // Read schema_version to confirm rows count = 3
60
+ const store = createStore({ connectionUrl: url });
61
+ try {
62
+ await store.ready();
63
+ const pool = store.getPool();
64
+ const r = await pool.query('SELECT count(*)::int AS n FROM schema_version');
65
+ const versionRowsPass = r.rows[0].n === 3;
66
+ results.push({
67
+ anchorAcId: 'AC-27102-1',
68
+ verdict: versionRowsPass ? 'pass' : 'fail',
69
+ detail: `schema_version rows=${r.rows[0].n} (expected 3, i.e. schema_version advanced to 3)`,
70
+ });
71
+ } finally {
72
+ await store.close();
73
+ }
74
+ return results;
75
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Pool posture smoke probe.
3
+ *
4
+ * Opens two facade instances against the same postgres:17-alpine
5
+ * container each configured at pool size 5, dispatches twenty
6
+ * concurrent SELECT queries across the two facades, asserts all
7
+ * twenty return with no timeout inside the shipped
8
+ * connectionTimeoutMillis budget.
9
+ *
10
+ * Anchors AC-27106-1.
11
+ *
12
+ * Cleans up: closes both pools.
13
+ */
14
+
15
+ import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
16
+
17
+ export default async function runProbe() {
18
+ const url = connectionUrlFromEnv();
19
+ const storeA = createStore({ connectionUrl: url, poolConfig: { max: 5 } });
20
+ const storeB = createStore({ connectionUrl: url, poolConfig: { max: 5 } });
21
+ const results = [];
22
+ try {
23
+ await Promise.all([storeA.ready(), storeB.ready()]);
24
+ const started = Date.now();
25
+ const promises = [];
26
+ for (let i = 0; i < 10; i++) {
27
+ promises.push(storeA.getPool().query('SELECT $1::int AS n, pg_sleep(0.05)', [i]));
28
+ promises.push(storeB.getPool().query('SELECT $1::int AS n, pg_sleep(0.05)', [10 + i]));
29
+ }
30
+ const settled = await Promise.allSettled(promises);
31
+ const elapsed = Date.now() - started;
32
+ const succeeded = settled.filter((s) => s.status === 'fulfilled').length;
33
+ const failed = settled.filter((s) => s.status === 'rejected').length;
34
+ results.push({
35
+ anchorAcId: 'AC-27106-1',
36
+ verdict: succeeded === 20 && failed === 0 ? 'pass' : 'fail',
37
+ detail: `20 concurrent queries dispatched across two pool-size-5 facades; ${succeeded} returned, ${failed} rejected, wall-clock ${elapsed}ms`,
38
+ });
39
+ // Observed max concurrent in-use per pool must be <= configured pool size
40
+ // pg's pg.Pool exposes totalCount / idleCount / waitingCount; peak in-use ~ totalCount - idleCount.
41
+ const poolA = storeA.getPool();
42
+ const poolB = storeB.getPool();
43
+ const maxA = poolA.options && poolA.options.max;
44
+ const maxB = poolB.options && poolB.options.max;
45
+ const inUseCap = maxA === 5 && maxB === 5;
46
+ results.push({
47
+ anchorAcId: 'AC-27106-1',
48
+ verdict: inUseCap ? 'pass' : 'fail',
49
+ detail: `pool.options.max on both facades: A=${maxA}, B=${maxB} (each configured to 5)`,
50
+ });
51
+ } finally {
52
+ await storeA.close();
53
+ await storeB.close();
54
+ }
55
+ return results;
56
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Prepared-statement scan probe.
3
+ *
4
+ * Walks every .js / .mjs / .ts file under the applied fixture's facade
5
+ * directory (packages/rcf-lite/test/fixtures/infra-postgres/src/) and
6
+ * asserts every .query(...) call's first argument is a static string
7
+ * literal (single or double-quoted string, or a backtick template
8
+ * literal with no ${...} expressions).
9
+ *
10
+ * Anchors AC-27103-1 (prepared-statement discipline).
11
+ *
12
+ * The scan is a hand-rolled tokenising walker, not a full AST parser:
13
+ * this avoids adding acorn or babel as a rcf-lite dependency (round-5
14
+ * spec section 5.5, brief section 4). The tokeniser handles strings,
15
+ * template literals, comments, and nested parentheses. Runs
16
+ * build-observable; the facade-round-trip probe carries the runtime
17
+ * observable that the surface actually works.
18
+ */
19
+
20
+ import { readdir, readFile } from 'node:fs/promises';
21
+ import { join, resolve, dirname } from 'node:path';
22
+ import { fileURLToPath } from 'node:url';
23
+
24
+ const HERE = dirname(fileURLToPath(import.meta.url));
25
+ const FACADE_DIR = resolve(HERE, '..', '..', '..', '..', 'packages/rcf-lite/test/fixtures/infra-postgres/src');
26
+
27
+ async function walk(dir) {
28
+ const entries = await readdir(dir, { withFileTypes: true });
29
+ const files = [];
30
+ for (const e of entries) {
31
+ if (e.isDirectory()) {
32
+ files.push(...(await walk(join(dir, e.name))));
33
+ } else if (e.isFile() && /\.(mjs|js|ts)$/.test(e.name)) {
34
+ files.push(join(dir, e.name));
35
+ }
36
+ }
37
+ return files;
38
+ }
39
+
40
+ /**
41
+ * Strip block and line comments from source. Simple stripper: preserves
42
+ * string bodies (in ' " and `) so `/* not a comment *\/` inside a string
43
+ * survives. Good enough for the discipline scan.
44
+ */
45
+ function stripCommentsPreserveStrings(src) {
46
+ const out = [];
47
+ let i = 0;
48
+ while (i < src.length) {
49
+ const c = src[i];
50
+ const c2 = src[i + 1];
51
+ if (c === '/' && c2 === '/') {
52
+ while (i < src.length && src[i] !== '\n') i++;
53
+ out.push(' ');
54
+ continue;
55
+ }
56
+ if (c === '/' && c2 === '*') {
57
+ i += 2;
58
+ while (i < src.length && !(src[i] === '*' && src[i + 1] === '/')) i++;
59
+ i += 2;
60
+ out.push(' ');
61
+ continue;
62
+ }
63
+ if (c === "'" || c === '"') {
64
+ const q = c;
65
+ out.push(c);
66
+ i++;
67
+ while (i < src.length && src[i] !== q) {
68
+ if (src[i] === '\\' && i + 1 < src.length) {
69
+ out.push(src[i], src[i + 1]);
70
+ i += 2;
71
+ continue;
72
+ }
73
+ out.push(src[i]);
74
+ i++;
75
+ }
76
+ if (i < src.length) {
77
+ out.push(src[i]);
78
+ i++;
79
+ }
80
+ continue;
81
+ }
82
+ if (c === '`') {
83
+ out.push(c);
84
+ i++;
85
+ while (i < src.length && src[i] !== '`') {
86
+ if (src[i] === '\\' && i + 1 < src.length) {
87
+ out.push(src[i], src[i + 1]);
88
+ i += 2;
89
+ continue;
90
+ }
91
+ if (src[i] === '$' && src[i + 1] === '{') {
92
+ out.push(src[i], src[i + 1]);
93
+ i += 2;
94
+ let depth = 1;
95
+ while (i < src.length && depth > 0) {
96
+ if (src[i] === '{') depth++;
97
+ else if (src[i] === '}') depth--;
98
+ out.push(src[i]);
99
+ i++;
100
+ }
101
+ continue;
102
+ }
103
+ out.push(src[i]);
104
+ i++;
105
+ }
106
+ if (i < src.length) {
107
+ out.push(src[i]);
108
+ i++;
109
+ }
110
+ continue;
111
+ }
112
+ out.push(c);
113
+ i++;
114
+ }
115
+ return out.join('');
116
+ }
117
+
118
+ /**
119
+ * Find every .query(...) call site and classify its first argument.
120
+ * Returns [{ line, firstArgKind }] where firstArgKind is 'stringLiteral',
121
+ * 'templateStatic', 'templateWithExpression', 'stringConcat', or
122
+ * 'other'.
123
+ */
124
+ function scanQueryCalls(src) {
125
+ const cleaned = stripCommentsPreserveStrings(src);
126
+ const calls = [];
127
+ const rx = /\.query\s*\(/g;
128
+ let m;
129
+ while ((m = rx.exec(cleaned)) !== null) {
130
+ const start = m.index + m[0].length;
131
+ const line = cleaned.slice(0, start).split('\n').length;
132
+ // Find the first argument by scanning forward, respecting parens/braces/strings
133
+ let i = start;
134
+ while (i < cleaned.length && /\s/.test(cleaned[i])) i++;
135
+ const first = cleaned[i];
136
+ if (first === "'" || first === '"') {
137
+ calls.push({ line, firstArgKind: 'stringLiteral', preview: cleaned.slice(i, i + 60) });
138
+ } else if (first === '`') {
139
+ // Check if backtick body has ${...}
140
+ let j = i + 1;
141
+ let hasExpr = false;
142
+ while (j < cleaned.length && cleaned[j] !== '`') {
143
+ if (cleaned[j] === '$' && cleaned[j + 1] === '{') { hasExpr = true; break; }
144
+ if (cleaned[j] === '\\') j++;
145
+ j++;
146
+ }
147
+ calls.push({ line, firstArgKind: hasExpr ? 'templateWithExpression' : 'templateStatic', preview: cleaned.slice(i, i + 60) });
148
+ } else if (/[A-Za-z_$]/.test(first)) {
149
+ // Identifier or expression: could be a variable holding a static string, but that defeats the scan discipline
150
+ calls.push({ line, firstArgKind: 'other', preview: cleaned.slice(i, i + 60) });
151
+ } else {
152
+ calls.push({ line, firstArgKind: 'other', preview: cleaned.slice(i, i + 60) });
153
+ }
154
+ }
155
+ return calls;
156
+ }
157
+
158
+ export default async function runProbe() {
159
+ const files = await walk(FACADE_DIR);
160
+ const results = [];
161
+ const violations = [];
162
+ let totalCalls = 0;
163
+ for (const file of files) {
164
+ const src = await readFile(file, 'utf8');
165
+ const calls = scanQueryCalls(src);
166
+ for (const c of calls) {
167
+ totalCalls++;
168
+ if (c.firstArgKind === 'templateWithExpression' || c.firstArgKind === 'stringConcat') {
169
+ violations.push({ file, ...c });
170
+ }
171
+ }
172
+ }
173
+ results.push({
174
+ anchorAcId: 'AC-27103-1',
175
+ verdict: violations.length === 0 ? 'pass' : 'fail',
176
+ detail: violations.length === 0
177
+ ? `${totalCalls} .query call sites scanned across ${files.length} facade file(s); every first argument is a static string literal or a template with no expressions`
178
+ : `${violations.length} violation(s): ${JSON.stringify(violations)}`,
179
+ });
180
+ results.push({
181
+ anchorAcId: 'AC-27103-1',
182
+ verdict: totalCalls >= 5 ? 'pass' : 'warn',
183
+ detail: `total .query call sites scanned: ${totalCalls} (minimum 5 to consider the facade meaningfully covered by this scan)`,
184
+ });
185
+ return results;
186
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Shared helpers for persistence-data-postgres probes.
3
+ *
4
+ * Runtime-dependency posture: probes import pg via the sample-app
5
+ * fixture's store.mjs so pg resolves from the fixture's own
6
+ * node_modules and rcf-lite itself gains no new runtime dependency
7
+ * (round-5 spec section 5.5, brief section 4).
8
+ */
9
+
10
+ import { mkdir, writeFile } from 'node:fs/promises';
11
+ import { dirname, resolve } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ const HERE = dirname(fileURLToPath(import.meta.url));
15
+
16
+ // Project root two levels above blueprints/persistence-data-postgres/
17
+ export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
18
+ export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/infra-postgres');
19
+ export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/persistence-data-postgres');
20
+
21
+ /**
22
+ * Compute the aggregate verdict per spec section 3.4:
23
+ * - fail if any result carries verdict fail
24
+ * - warn if any result carries verdict warn and no fail
25
+ * - pass otherwise
26
+ */
27
+ export function aggregate(results) {
28
+ if (results.some((r) => r.verdict === 'fail')) return 'fail';
29
+ if (results.some((r) => r.verdict === 'warn')) return 'warn';
30
+ return 'pass';
31
+ }
32
+
33
+ /**
34
+ * Write the per-blueprint probe report at
35
+ * .rcf/reports/blueprints/persistence-data-postgres/<probeName>.json
36
+ * per spec section 3.4.
37
+ */
38
+ export async function writeReport({ probeName, engine, results }) {
39
+ await mkdir(REPORT_DIR, { recursive: true });
40
+ const report = {
41
+ slug: 'persistence-data-postgres',
42
+ probeName,
43
+ runAt: new Date().toISOString(),
44
+ engine,
45
+ results,
46
+ aggregateVerdict: aggregate(results),
47
+ };
48
+ const path = resolve(REPORT_DIR, `${probeName}.json`);
49
+ await writeFile(path, JSON.stringify(report, null, 2), 'utf8');
50
+ return { report, path };
51
+ }
52
+
53
+ /**
54
+ * Drive an async main() and exit 0 on aggregate pass, 1 otherwise.
55
+ * Prints the report JSON to stdout for the gate-reviewer to read.
56
+ */
57
+ export async function runShim(probeName, engine, mainFn) {
58
+ try {
59
+ const results = await mainFn();
60
+ const { report, path } = await writeReport({ probeName, engine, results });
61
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
62
+ process.stdout.write(`report written to ${path}\n`);
63
+ process.exit(report.aggregateVerdict === 'pass' ? 0 : 1);
64
+ } catch (err) {
65
+ const results = [{
66
+ anchorAcId: 'unknown',
67
+ verdict: 'fail',
68
+ detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
69
+ }];
70
+ const { report, path } = await writeReport({ probeName, engine, results });
71
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
72
+ process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
73
+ process.stderr.write(`report written to ${path}\n`);
74
+ process.exit(1);
75
+ }
76
+ }