rcf-lite 0.20.0 → 0.22.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 (532) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/blueprints/application-account-settings/CHANGELOG.md +12 -0
  3. package/blueprints/application-account-settings/README.md +114 -0
  4. package/blueprints/application-account-settings/blueprint.json +234 -0
  5. package/blueprints/application-account-settings/contributions/adrs/adr-2601-application-account-settings-capability-vocabulary.json +20 -0
  6. package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +20 -0
  7. package/blueprints/application-account-settings/contributions/adrs/adr-2603-application-account-settings-theme-persistence.json +20 -0
  8. package/blueprints/application-account-settings/contributions/adrs/adr-2604-application-account-settings-reauth-window.json +20 -0
  9. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +18 -0
  10. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +18 -0
  11. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +18 -0
  12. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +18 -0
  13. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +18 -0
  14. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +18 -0
  15. package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +41 -0
  16. package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +28 -0
  17. package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +35 -0
  18. package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +40 -0
  19. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25101.json +34 -0
  20. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25102.json +27 -0
  21. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25103.json +27 -0
  22. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25104.json +27 -0
  23. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +33 -0
  24. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +27 -0
  25. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25107.json +27 -0
  26. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25108.json +27 -0
  27. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25109.json +33 -0
  28. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25110.json +27 -0
  29. package/blueprints/application-account-settings/docs/topics.md +48 -0
  30. package/blueprints/application-account-settings/guide/application-account-settings.md +30 -0
  31. package/blueprints/application-account-settings/probe-packs/application-account-settings.pack.mjs +246 -0
  32. package/blueprints/application-admin-console/CHANGELOG.md +11 -0
  33. package/blueprints/application-admin-console/README.md +98 -0
  34. package/blueprints/application-admin-console/blueprint.json +226 -0
  35. package/blueprints/application-admin-console/contributions/adrs/adr-2201-application-admin-console-capability-vocabulary.json +25 -0
  36. package/blueprints/application-admin-console/contributions/adrs/adr-2202-application-admin-console-baseline-roles.json +25 -0
  37. package/blueprints/application-admin-console/contributions/adrs/adr-2203-application-admin-console-invite-transport.json +20 -0
  38. package/blueprints/application-admin-console/contributions/adrs/adr-2204-application-admin-console-audit-retention.json +20 -0
  39. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-001.json +18 -0
  40. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-002.json +18 -0
  41. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-003.json +18 -0
  42. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-004.json +18 -0
  43. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-005.json +18 -0
  44. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-006.json +18 -0
  45. package/blueprints/application-admin-console/contributions/tacs/tac-2201-application-admin-console-shell.json +40 -0
  46. package/blueprints/application-admin-console/contributions/tacs/tac-2202-application-admin-console-capability-discovery.json +44 -0
  47. package/blueprints/application-admin-console/contributions/tacs/tac-2203-application-admin-console-permission-matrix.json +34 -0
  48. package/blueprints/application-admin-console/contributions/tacs/tac-2204-application-admin-console-audit-view.json +40 -0
  49. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21101.json +34 -0
  50. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21102.json +34 -0
  51. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21103.json +34 -0
  52. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21104.json +28 -0
  53. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21105.json +34 -0
  54. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21106.json +27 -0
  55. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21107.json +27 -0
  56. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21108.json +27 -0
  57. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21109.json +33 -0
  58. package/blueprints/application-admin-console/docs/topics.md +42 -0
  59. package/blueprints/application-admin-console/guide/application-admin-console.md +29 -0
  60. package/blueprints/application-admin-console/probe-packs/application-admin-console.pack.mjs +182 -0
  61. package/blueprints/application-api-rest/docs/topics.md +13 -1
  62. package/blueprints/application-charts/CHANGELOG.md +12 -0
  63. package/blueprints/application-charts/README.md +73 -0
  64. package/blueprints/application-charts/blueprint.json +26 -0
  65. package/blueprints/application-charts/contributions/adrs/adr-1901-application-charts-engine-choice.json +25 -0
  66. package/blueprints/application-charts/contributions/adrs/adr-1902-application-charts-accessible-palette.json +25 -0
  67. package/blueprints/application-charts/contributions/adrs/adr-1903-application-charts-motion.json +25 -0
  68. package/blueprints/application-charts/contributions/requirements/application-charts-req-001.json +15 -0
  69. package/blueprints/application-charts/contributions/requirements/application-charts-req-002.json +15 -0
  70. package/blueprints/application-charts/contributions/requirements/application-charts-req-003.json +15 -0
  71. package/blueprints/application-charts/contributions/requirements/application-charts-req-004.json +15 -0
  72. package/blueprints/application-charts/contributions/tacs/tac-1901-application-charts-render-shell.json +42 -0
  73. package/blueprints/application-charts/contributions/tacs/tac-1902-application-charts-keyboard-traversal.json +40 -0
  74. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18101.json +35 -0
  75. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18102.json +35 -0
  76. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18103.json +35 -0
  77. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18104.json +35 -0
  78. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18105.json +35 -0
  79. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18106.json +35 -0
  80. package/blueprints/application-charts/docs/topics.md +44 -0
  81. package/blueprints/application-charts/guide/application-charts.md +44 -0
  82. package/blueprints/application-charts/probe-packs/application-charts.pack.mjs +191 -0
  83. package/blueprints/application-dashboard/CHANGELOG.md +10 -0
  84. package/blueprints/application-dashboard/README.md +102 -0
  85. package/blueprints/application-dashboard/assets/guidance/dashboard-design.md +124 -0
  86. package/blueprints/application-dashboard/blueprint.json +29 -0
  87. package/blueprints/application-dashboard/contributions/adrs/adr-2001-application-dashboard-primary-kpi-enum.json +25 -0
  88. package/blueprints/application-dashboard/contributions/adrs/adr-2002-application-dashboard-timeframe-presets.json +25 -0
  89. package/blueprints/application-dashboard/contributions/adrs/adr-2003-application-dashboard-export-formats.json +25 -0
  90. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-001.json +15 -0
  91. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-002.json +15 -0
  92. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-003.json +15 -0
  93. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-004.json +15 -0
  94. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-005.json +15 -0
  95. package/blueprints/application-dashboard/contributions/tacs/tac-2001-application-dashboard-tile-grid.json +47 -0
  96. package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +41 -0
  97. package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +35 -0
  98. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19101.json +35 -0
  99. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19102.json +35 -0
  100. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19103.json +35 -0
  101. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19104.json +35 -0
  102. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19105.json +35 -0
  103. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +35 -0
  104. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19107.json +35 -0
  105. package/blueprints/application-dashboard/docs/topics.md +50 -0
  106. package/blueprints/application-dashboard/guide/application-dashboard.md +48 -0
  107. package/blueprints/application-dashboard/probe-packs/application-dashboard.pack.mjs +231 -0
  108. package/blueprints/application-datatable/CHANGELOG.md +8 -0
  109. package/blueprints/application-datatable/README.md +43 -0
  110. package/blueprints/application-datatable/blueprint.json +33 -0
  111. package/blueprints/application-datatable/contributions/adrs/adr-1801-application-datatable-pattern-choice.json +25 -0
  112. package/blueprints/application-datatable/contributions/adrs/adr-1802-application-datatable-url-state.json +20 -0
  113. package/blueprints/application-datatable/contributions/adrs/adr-1803-application-datatable-page-size.json +20 -0
  114. package/blueprints/application-datatable/contributions/adrs/adr-1804-application-datatable-selection-persistence.json +20 -0
  115. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-001.json +15 -0
  116. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-002.json +15 -0
  117. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-003.json +15 -0
  118. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-004.json +15 -0
  119. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-005.json +15 -0
  120. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-006.json +15 -0
  121. package/blueprints/application-datatable/contributions/tacs/tac-1801-application-datatable-shell.json +50 -0
  122. package/blueprints/application-datatable/contributions/tacs/tac-1802-application-datatable-query-adapter.json +39 -0
  123. package/blueprints/application-datatable/contributions/tacs/tac-1803-application-datatable-selection-model.json +28 -0
  124. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17101.json +44 -0
  125. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17102.json +44 -0
  126. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17103.json +44 -0
  127. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17104.json +44 -0
  128. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17105.json +44 -0
  129. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17106.json +44 -0
  130. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17107.json +44 -0
  131. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17108.json +44 -0
  132. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17109.json +44 -0
  133. package/blueprints/application-datatable/docs/topics.md +42 -0
  134. package/blueprints/application-datatable/guide/application-datatable.md +38 -0
  135. package/blueprints/application-datatable/probe-packs/application-datatable.pack.mjs +240 -0
  136. package/blueprints/application-empty-error-states/CHANGELOG.md +9 -0
  137. package/blueprints/application-empty-error-states/README.md +88 -0
  138. package/blueprints/application-empty-error-states/blueprint.json +119 -0
  139. package/blueprints/application-empty-error-states/contributions/adrs/adr-2301-application-empty-error-states-status-contract.json +25 -0
  140. package/blueprints/application-empty-error-states/contributions/adrs/adr-2302-application-empty-error-states-stack-trace-visibility.json +25 -0
  141. package/blueprints/application-empty-error-states/contributions/adrs/adr-2303-application-empty-error-states-offline-strategy.json +25 -0
  142. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +18 -0
  143. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +18 -0
  144. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +18 -0
  145. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +18 -0
  146. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +18 -0
  147. package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +46 -0
  148. package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +36 -0
  149. package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +40 -0
  150. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22101.json +29 -0
  151. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22102.json +29 -0
  152. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22103.json +29 -0
  153. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22104.json +29 -0
  154. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22105.json +29 -0
  155. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22106.json +29 -0
  156. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22107.json +29 -0
  157. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22108.json +29 -0
  158. package/blueprints/application-empty-error-states/docs/topics.md +53 -0
  159. package/blueprints/application-empty-error-states/guide/application-empty-error-states.md +50 -0
  160. package/blueprints/application-empty-error-states/probe-packs/application-empty-error-states.pack.mjs +284 -0
  161. package/blueprints/application-error-handling/docs/topics.md +12 -0
  162. package/blueprints/application-file-upload/CHANGELOG.md +9 -0
  163. package/blueprints/application-file-upload/README.md +85 -0
  164. package/blueprints/application-file-upload/blueprint.json +114 -0
  165. package/blueprints/application-file-upload/contributions/adrs/adr-2401-application-file-upload-transport.json +25 -0
  166. package/blueprints/application-file-upload/contributions/adrs/adr-2402-application-file-upload-accepted-set.json +25 -0
  167. package/blueprints/application-file-upload/contributions/adrs/adr-2403-application-file-upload-virus-scan.json +25 -0
  168. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +18 -0
  169. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +18 -0
  170. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +18 -0
  171. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +18 -0
  172. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +18 -0
  173. package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +46 -0
  174. package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +47 -0
  175. package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +46 -0
  176. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23101.json +28 -0
  177. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +28 -0
  178. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23103.json +29 -0
  179. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23104.json +28 -0
  180. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +29 -0
  181. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23106.json +28 -0
  182. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23107.json +28 -0
  183. package/blueprints/application-file-upload/docs/topics.md +58 -0
  184. package/blueprints/application-file-upload/guide/application-file-upload.md +48 -0
  185. package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +238 -0
  186. package/blueprints/application-forms-wizard/CHANGELOG.md +9 -0
  187. package/blueprints/application-forms-wizard/README.md +102 -0
  188. package/blueprints/application-forms-wizard/blueprint.json +120 -0
  189. package/blueprints/application-forms-wizard/contributions/adrs/adr-2501-application-forms-wizard-navigation.json +25 -0
  190. package/blueprints/application-forms-wizard/contributions/adrs/adr-2502-application-forms-wizard-save-and-return.json +25 -0
  191. package/blueprints/application-forms-wizard/contributions/adrs/adr-2503-application-forms-wizard-step-indicator.json +25 -0
  192. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +18 -0
  193. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +18 -0
  194. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +18 -0
  195. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +18 -0
  196. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +18 -0
  197. package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +46 -0
  198. package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +40 -0
  199. package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +40 -0
  200. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +28 -0
  201. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24102.json +29 -0
  202. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24103.json +28 -0
  203. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24104.json +29 -0
  204. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24105.json +28 -0
  205. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24106.json +28 -0
  206. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24107.json +28 -0
  207. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24108.json +29 -0
  208. package/blueprints/application-forms-wizard/docs/topics.md +49 -0
  209. package/blueprints/application-forms-wizard/guide/application-forms-wizard.md +48 -0
  210. package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +233 -0
  211. package/blueprints/application-notifications-in-app/CHANGELOG.md +9 -0
  212. package/blueprints/application-notifications-in-app/README.md +80 -0
  213. package/blueprints/application-notifications-in-app/blueprint.json +30 -0
  214. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2101-application-notifications-in-app-live-region-role-mapping.json +25 -0
  215. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2102-application-notifications-in-app-toast-timeout-floor.json +25 -0
  216. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2103-application-notifications-in-app-retention-window.json +25 -0
  217. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-001.json +15 -0
  218. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-002.json +15 -0
  219. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-003.json +15 -0
  220. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-004.json +15 -0
  221. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-005.json +15 -0
  222. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +46 -0
  223. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +52 -0
  224. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2103-application-notifications-in-app-preferences.json +40 -0
  225. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +35 -0
  226. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +35 -0
  227. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +35 -0
  228. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20104.json +35 -0
  229. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +35 -0
  230. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20106.json +26 -0
  231. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20107.json +26 -0
  232. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20108.json +26 -0
  233. package/blueprints/application-notifications-in-app/docs/topics.md +46 -0
  234. package/blueprints/application-notifications-in-app/guide/application-notifications-in-app.md +47 -0
  235. package/blueprints/application-notifications-in-app/probe-packs/application-notifications-in-app.pack.mjs +328 -0
  236. package/blueprints/application-onboarding-tour/CHANGELOG.md +12 -0
  237. package/blueprints/application-onboarding-tour/README.md +77 -0
  238. package/blueprints/application-onboarding-tour/blueprint.json +164 -0
  239. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2701-application-onboarding-tour-dismissal-policy.json +20 -0
  240. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2702-application-onboarding-tour-completion-store-shape.json +20 -0
  241. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2703-application-onboarding-tour-checklist-anchor.json +20 -0
  242. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +18 -0
  243. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +18 -0
  244. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +18 -0
  245. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +18 -0
  246. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +41 -0
  247. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +35 -0
  248. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +34 -0
  249. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26101.json +27 -0
  250. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26102.json +27 -0
  251. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26103.json +27 -0
  252. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26104.json +27 -0
  253. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26105.json +27 -0
  254. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26106.json +27 -0
  255. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26107.json +27 -0
  256. package/blueprints/application-onboarding-tour/docs/topics.md +48 -0
  257. package/blueprints/application-onboarding-tour/guide/application-onboarding-tour.md +59 -0
  258. package/blueprints/application-onboarding-tour/probe-packs/application-onboarding-tour.pack.mjs +231 -0
  259. package/blueprints/application-spa/docs/topics.md +13 -1
  260. package/blueprints/delivery-ci-workflows/docs/topics.md +13 -1
  261. package/blueprints/deploy-cloudflare-workers/docs/topics.md +13 -1
  262. package/blueprints/email-smtp-resend/docs/topics.md +13 -1
  263. package/blueprints/object-storage-s3/CHANGELOG.md +13 -0
  264. package/blueprints/object-storage-s3/README.md +108 -0
  265. package/blueprints/object-storage-s3/blueprint.json +72 -0
  266. package/blueprints/object-storage-s3/contributions/adrs/adr-2901-object-storage-s3-adapter.json +30 -0
  267. package/blueprints/object-storage-s3/contributions/adrs/adr-2902-object-storage-s3-presigned-ttl-floor.json +25 -0
  268. package/blueprints/object-storage-s3/contributions/adrs/adr-2903-object-storage-s3-multipart-threshold.json +25 -0
  269. package/blueprints/object-storage-s3/contributions/adrs/adr-2904-object-storage-s3-contract.json +25 -0
  270. package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +103 -0
  271. package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +43 -0
  272. package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +84 -0
  273. package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +101 -0
  274. package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +85 -0
  275. package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +84 -0
  276. package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +64 -0
  277. package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +4 -0
  278. package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +10 -0
  279. package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +4 -0
  280. package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +4 -0
  281. package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +7 -0
  282. package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +4 -0
  283. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +18 -0
  284. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +18 -0
  285. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +18 -0
  286. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +18 -0
  287. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +18 -0
  288. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +18 -0
  289. package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +57 -0
  290. package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +36 -0
  291. package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +36 -0
  292. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +34 -0
  293. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +43 -0
  294. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +25 -0
  295. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +34 -0
  296. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +25 -0
  297. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +34 -0
  298. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28107.json +34 -0
  299. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28108.json +34 -0
  300. package/blueprints/object-storage-s3/docs/topics.md +62 -0
  301. package/blueprints/object-storage-s3/guide/object-storage-s3.md +207 -0
  302. package/blueprints/observability-essentials/docs/topics.md +13 -1
  303. package/blueprints/observability-logging/CHANGELOG.md +9 -0
  304. package/blueprints/observability-logging/README.md +4 -1
  305. package/blueprints/observability-logging/blueprint.json +114 -21
  306. package/blueprints/observability-logging/docs/topics.md +12 -0
  307. package/blueprints/observability-probe-endpoints/docs/topics.md +13 -1
  308. package/blueprints/persistence-data-d1/docs/topics.md +13 -1
  309. package/blueprints/persistence-data-postgres/CHANGELOG.md +12 -0
  310. package/blueprints/persistence-data-postgres/README.md +101 -0
  311. package/blueprints/persistence-data-postgres/blueprint.json +80 -0
  312. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +30 -0
  313. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2802-persistence-data-postgres-migration-shape.json +25 -0
  314. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2803-persistence-data-postgres-runner-mode.json +25 -0
  315. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2804-persistence-data-postgres-recovery.json +25 -0
  316. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2805-persistence-data-postgres-connection-pool-posture.json +25 -0
  317. package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +56 -0
  318. package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +75 -0
  319. package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +56 -0
  320. package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +186 -0
  321. package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +76 -0
  322. package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +173 -0
  323. package/blueprints/persistence-data-postgres/contributions/probes/run-facade-round-trip.mjs +10 -0
  324. package/blueprints/persistence-data-postgres/contributions/probes/run-migration-apply.mjs +10 -0
  325. package/blueprints/persistence-data-postgres/contributions/probes/run-pool-posture-smoke.mjs +9 -0
  326. package/blueprints/persistence-data-postgres/contributions/probes/run-prepared-statement-scan.mjs +10 -0
  327. package/blueprints/persistence-data-postgres/contributions/probes/run-recovery-restore-round-trip.mjs +9 -0
  328. package/blueprints/persistence-data-postgres/contributions/probes/run-transaction-atomicity.mjs +10 -0
  329. package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +79 -0
  330. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +18 -0
  331. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +18 -0
  332. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +18 -0
  333. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +18 -0
  334. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +18 -0
  335. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +18 -0
  336. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +18 -0
  337. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +58 -0
  338. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +40 -0
  339. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +35 -0
  340. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +40 -0
  341. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +34 -0
  342. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +25 -0
  343. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +25 -0
  344. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +25 -0
  345. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +25 -0
  346. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +25 -0
  347. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +25 -0
  348. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +25 -0
  349. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +25 -0
  350. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +25 -0
  351. package/blueprints/persistence-data-postgres/docs/topics.md +64 -0
  352. package/blueprints/persistence-data-postgres/guide/persistence-data-postgres.md +172 -0
  353. package/blueprints/persistence-data-sqlite/docs/topics.md +13 -1
  354. package/blueprints/security-auth-clerk/CHANGELOG.md +9 -0
  355. package/blueprints/security-auth-clerk/README.md +3 -0
  356. package/blueprints/security-auth-clerk/blueprint.json +147 -29
  357. package/blueprints/security-auth-clerk/docs/topics.md +13 -1
  358. package/blueprints/security-auth-keycloak/CHANGELOG.md +9 -0
  359. package/blueprints/security-auth-keycloak/README.md +3 -0
  360. package/blueprints/security-auth-keycloak/blueprint.json +182 -36
  361. package/blueprints/security-auth-keycloak/docs/topics.md +13 -1
  362. package/blueprints/security-auth-magic-link/CHANGELOG.md +9 -0
  363. package/blueprints/security-auth-magic-link/README.md +3 -0
  364. package/blueprints/security-auth-magic-link/blueprint.json +159 -32
  365. package/blueprints/security-auth-magic-link/docs/topics.md +13 -1
  366. package/blueprints/security-auth-oauth2/CHANGELOG.md +9 -0
  367. package/blueprints/security-auth-oauth2/README.md +3 -0
  368. package/blueprints/security-auth-oauth2/blueprint.json +158 -31
  369. package/blueprints/security-auth-oauth2/docs/topics.md +13 -1
  370. package/blueprints/security-secrets-management/CHANGELOG.md +11 -0
  371. package/blueprints/security-secrets-management/blueprint.json +2 -1
  372. package/blueprints/security-secrets-management/docs/topics.md +13 -1
  373. package/fixtures/canary-manifest.json +9 -9
  374. package/package.json +2 -2
  375. package/rcf/code-nodes/cn-106.json +13 -0
  376. package/rcf/code-nodes/cn-107.json +14 -0
  377. package/rcf/code-nodes/cn-108.json +13 -0
  378. package/rcf/code-nodes/cn-109.json +12 -0
  379. package/rcf/code-nodes/cn-110.json +12 -0
  380. package/rcf/code-nodes/cn-111.json +14 -0
  381. package/rcf/code-nodes/cn-112.json +14 -0
  382. package/rcf/code-nodes/cn-113.json +12 -0
  383. package/rcf/code-nodes/cn-114.json +13 -0
  384. package/rcf/code-nodes/cn-115.json +13 -0
  385. package/rcf/code-nodes/cn-116.json +12 -0
  386. package/rcf/code-nodes/cn-117.json +13 -0
  387. package/rcf/code-nodes/cn-118.json +13 -0
  388. package/rcf/code-nodes/cn-119.json +13 -0
  389. package/rcf/code-nodes/cn-120.json +13 -0
  390. package/rcf/code-nodes/cn-121.json +12 -0
  391. package/rcf/code-nodes/cn-122.json +12 -0
  392. package/rcf/code-nodes/cn-123.json +13 -0
  393. package/rcf/code-nodes/cn-124.json +13 -0
  394. package/rcf/code-nodes/cn-125.json +13 -0
  395. package/rcf/code-nodes/cn-126.json +13 -0
  396. package/rcf/code-nodes/cn-127.json +12 -0
  397. package/rcf/code-nodes/cn-128.json +14 -0
  398. package/rcf/code-nodes/cn-129.json +14 -0
  399. package/rcf/code-nodes/cn-130.json +14 -0
  400. package/rcf/code-nodes/cn-131.json +15 -0
  401. package/rcf/code-nodes/cn-132.json +12 -0
  402. package/rcf/code-nodes/cn-133.json +13 -0
  403. package/rcf/code-nodes/cn-134.json +13 -0
  404. package/rcf/code-nodes/cn-135.json +12 -0
  405. package/rcf/code-nodes/cn-136.json +13 -0
  406. package/rcf/code-nodes/cn-137.json +13 -0
  407. package/rcf/code-nodes/cn-138.json +12 -0
  408. package/rcf/code-nodes/cn-139.json +12 -0
  409. package/rcf/code-nodes/cn-140.json +13 -0
  410. package/rcf/code-nodes/cn-141.json +13 -0
  411. package/rcf/code-nodes/cn-142.json +12 -0
  412. package/rcf/code-nodes/cn-143.json +13 -0
  413. package/rcf/code-nodes/cn-144.json +13 -0
  414. package/rcf/code-nodes/cn-145.json +12 -0
  415. package/rcf/code-nodes/cn-146.json +12 -0
  416. package/rcf/code-nodes/cn-147.json +13 -0
  417. package/rcf/code-nodes/cn-148.json +13 -0
  418. package/rcf/code-nodes/cn-149.json +12 -0
  419. package/rcf/code-nodes/cn-150.json +13 -0
  420. package/rcf/code-nodes/cn-151.json +13 -0
  421. package/rcf/code-nodes/cn-152.json +12 -0
  422. package/rcf/code-nodes/cn-153.json +12 -0
  423. package/rcf/code-nodes/cn-154.json +13 -0
  424. package/rcf/code-nodes/cn-155.json +14 -0
  425. package/rcf/code-nodes/cn-156.json +13 -0
  426. package/rcf/code-nodes/cn-157.json +13 -0
  427. package/rcf/code-nodes/cn-158.json +12 -0
  428. package/rcf/code-nodes/cn-159.json +13 -0
  429. package/rcf/code-nodes/cn-160.json +12 -0
  430. package/rcf/code-nodes/cn-161.json +12 -0
  431. package/rcf/code-nodes/cn-162.json +13 -0
  432. package/rcf/code-nodes/cn-163.json +12 -0
  433. package/rcf/code-nodes/cn-164.json +13 -0
  434. package/rcf/code-nodes/cn-165.json +12 -0
  435. package/rcf/code-nodes/cn-166.json +12 -0
  436. package/rcf/code-nodes/cn-167.json +12 -0
  437. package/rcf/code-nodes/cn-168.json +12 -0
  438. package/rcf/code-nodes/cn-169.json +12 -0
  439. package/rcf/code-nodes/cn-170.json +12 -0
  440. package/rcf/code-nodes/cn-171.json +12 -0
  441. package/rcf/code-nodes/cn-172.json +12 -0
  442. package/rcf/code-nodes/cn-173.json +12 -0
  443. package/rcf/code-nodes/cn-174.json +12 -0
  444. package/rcf/code-nodes/cn-175.json +13 -0
  445. package/rcf/code-nodes/cn-176.json +12 -0
  446. package/rcf/code-nodes/cn-177.json +12 -0
  447. package/rcf/code-nodes/cn-178.json +12 -0
  448. package/rcf/code-nodes/cn-179.json +12 -0
  449. package/rcf/code-nodes/cn-180.json +13 -0
  450. package/rcf/code-nodes/cn-181.json +12 -0
  451. package/rcf/code-nodes/cn-182.json +13 -0
  452. package/rcf/code-nodes/cn-183.json +12 -0
  453. package/rcf/code-nodes/cn-184.json +13 -0
  454. package/rcf/code-nodes/cn-185.json +12 -0
  455. package/rcf/code-nodes/cn-186.json +12 -0
  456. package/rcf/code-nodes/cn-200.json +14 -0
  457. package/rcf/code-nodes/cn-201.json +13 -0
  458. package/rcf/code-nodes/cn-202.json +14 -0
  459. package/rcf/code-nodes/cn-203.json +14 -0
  460. package/rcf/code-nodes/cn-204.json +13 -0
  461. package/rcf/code-nodes/cn-205.json +14 -0
  462. package/rcf/fbs/fbs-036.json +22 -0
  463. package/rcf/fbs/fbs-037.json +19 -0
  464. package/rcf/fbs/fbs-038.json +19 -0
  465. package/rcf/fbs/fbs-039.json +21 -0
  466. package/rcf/fbs/fbs-040.json +20 -0
  467. package/rcf/fbs/fbs-041.json +13 -0
  468. package/rcf/fbs/fbs-042.json +13 -0
  469. package/rcf/fbs/fbs-043.json +23 -0
  470. package/rcf/fbs/fbs-044.json +23 -0
  471. package/rcf/fbs/fbs-045.json +23 -0
  472. package/rcf/fbs/fbs-046.json +24 -0
  473. package/rcf/fbs/fbs-047.json +24 -0
  474. package/rcf/fbs/fbs-060.json +22 -0
  475. package/rcf/fbs/fbs-061.json +20 -0
  476. package/rcf/requirements/req-017.json +18 -0
  477. package/rcf/requirements/req-018.json +18 -0
  478. package/rcf/requirements/req-019.json +38 -0
  479. package/rcf/requirements/req-020.json +13 -0
  480. package/rcf/requirements/req-021.json +13 -0
  481. package/rcf/requirements/req-022.json +13 -0
  482. package/rcf/requirements/req-023.json +14 -0
  483. package/rcf/requirements/req-024.json +69 -0
  484. package/rcf/requirements/req-025.json +59 -0
  485. package/rcf/requirements/req-026.json +154 -0
  486. package/rcf/requirements/req-027.json +33 -0
  487. package/rcf/requirements/req-028.json +13 -0
  488. package/rcf/requirements/req-040.json +13 -0
  489. package/rcf/requirements/req-041.json +125 -0
  490. package/rcf/test-suites/ts-046.json +78 -0
  491. package/rcf/test-suites/ts-047.json +54 -0
  492. package/rcf/test-suites/ts-048.json +54 -0
  493. package/rcf/test-suites/ts-049.json +70 -0
  494. package/rcf/test-suites/ts-050.json +69 -0
  495. package/rcf/test-suites/ts-051.json +22 -0
  496. package/rcf/test-suites/ts-052.json +20 -0
  497. package/rcf/test-suites/ts-053.json +70 -0
  498. package/rcf/test-suites/ts-054.json +70 -0
  499. package/rcf/test-suites/ts-055.json +77 -0
  500. package/rcf/test-suites/ts-056.json +78 -0
  501. package/rcf/test-suites/ts-057.json +78 -0
  502. package/rcf/test-suites/ts-070.json +62 -0
  503. package/rcf/test-suites/ts-071.json +62 -0
  504. package/rcf/user-stories/us-1701.json +56 -0
  505. package/rcf/user-stories/us-1801.json +40 -0
  506. package/rcf/user-stories/us-1901.json +40 -0
  507. package/rcf/user-stories/us-2001.json +50 -0
  508. package/rcf/user-stories/us-2101.json +45 -0
  509. package/rcf/user-stories/us-2201.json +60 -0
  510. package/rcf/user-stories/us-2301.json +51 -0
  511. package/rcf/user-stories/us-2401.json +62 -0
  512. package/rcf/user-stories/us-2501.json +58 -0
  513. package/rcf/user-stories/us-2601.json +51 -0
  514. package/rcf/user-stories/us-2701.json +55 -0
  515. package/rcf/user-stories/us-2801.json +55 -0
  516. package/rcf/user-stories/us-4001.json +69 -0
  517. package/rcf/user-stories/us-4101.json +69 -0
  518. package/releases/releases.yaml +21 -1
  519. package/src/blueprint/apply.js +107 -1
  520. package/src/blueprint/capabilities.js +357 -0
  521. package/src/blueprint/loader.js +247 -0
  522. package/src/browser-verify/boot.js +180 -0
  523. package/src/browser-verify/index.js +13 -0
  524. package/src/browser-verify/manifest-writer.js +31 -6
  525. package/src/browser-verify/pack-browser.js +294 -0
  526. package/src/browser-verify/pack-loader.js +176 -0
  527. package/src/browser-verify/pack-runner.js +193 -0
  528. package/src/browser-verify/pack-schema.js +155 -0
  529. package/src/browser-verify/runner.js +24 -1
  530. package/src/cli/blueprint.js +99 -0
  531. package/src/cli/browser-verify.js +147 -7
  532. package/src/core/errors/index.js +7 -0
@@ -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
+ }
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Recovery restore round-trip probe.
3
+ *
4
+ * Seeds the running postgres:17-alpine fixture with a small rowset,
5
+ * runs pg_dump via `docker exec` against the source container (pg_dump
6
+ * ships inside the postgres:17-alpine image; on a shipped project the
7
+ * fixture's src/recovery.mjs drives pg_dump on PATH per TAC-2804),
8
+ * brings up a second postgres:17-alpine container on a spare port,
9
+ * pipes the artefact through psql into the second container, and
10
+ * asserts row-count and checksum equality between source and restored
11
+ * databases.
12
+ *
13
+ * Anchors AC-27105-1 (recovery exported, restore round-trips the row
14
+ * set).
15
+ *
16
+ * Cleans up: TRUNCATE users on source; stops the restore container and
17
+ * removes its volume; deletes the artefact file.
18
+ */
19
+
20
+ import { spawn, execFile } from 'node:child_process';
21
+ import { promisify } from 'node:util';
22
+ import { mkdir, writeFile, unlink, rm } from 'node:fs/promises';
23
+ import { dirname, relative, resolve } from 'node:path';
24
+ import { fileURLToPath } from 'node:url';
25
+ import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
26
+
27
+ const execFileAsync = promisify(execFile);
28
+ const HERE = dirname(fileURLToPath(import.meta.url));
29
+ const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
30
+ const ARTEFACT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/persistence-data-postgres/recovery');
31
+ const ARTEFACT = resolve(ARTEFACT_DIR, 'backup.sql');
32
+ const ARTEFACT_REL = relative(PROJECT_ROOT, ARTEFACT);
33
+ const SOURCE_CONTAINER = 'infra-postgres-postgres-1';
34
+ const RESTORE_CONTAINER = 'infra-postgres-restore';
35
+ const RESTORE_PORT = '55432';
36
+
37
+ async function dockerExec(container, cmd, opts = {}) {
38
+ return execFileAsync('docker', ['exec', container, ...cmd], { maxBuffer: 64 * 1024 * 1024, ...opts });
39
+ }
40
+
41
+ /**
42
+ * Pipe an in-process buffer into docker exec's stdin. execFile does not
43
+ * accept stdin buffers, so use spawn.
44
+ */
45
+ async function dockerExecStdin(container, cmd, stdinBuffer) {
46
+ return new Promise((resolve2, reject) => {
47
+ const child = spawn('docker', ['exec', '-i', container, ...cmd]);
48
+ const chunks = [];
49
+ const errChunks = [];
50
+ child.stdout.on('data', (d) => chunks.push(d));
51
+ child.stderr.on('data', (d) => errChunks.push(d));
52
+ child.on('error', reject);
53
+ child.on('exit', (code) => {
54
+ if (code === 0) return resolve2({ stdout: Buffer.concat(chunks).toString('utf8'), stderr: Buffer.concat(errChunks).toString('utf8') });
55
+ reject(new Error(`docker exec exit ${code}: ${Buffer.concat(errChunks).toString('utf8')}`));
56
+ });
57
+ child.stdin.write(stdinBuffer);
58
+ child.stdin.end();
59
+ });
60
+ }
61
+
62
+ async function waitHealthy(container, maxSeconds = 30) {
63
+ for (let i = 0; i < maxSeconds; i++) {
64
+ try {
65
+ const r = await execFileAsync('docker', ['inspect', '--format', '{{.State.Health.Status}}', container]);
66
+ const status = r.stdout.trim();
67
+ if (status === 'healthy') return;
68
+ } catch { /* container not up yet */ }
69
+ await new Promise((r) => setTimeout(r, 1000));
70
+ }
71
+ throw new Error(`container ${container} did not become healthy within ${maxSeconds}s`);
72
+ }
73
+
74
+ async function bringUpRestore() {
75
+ // Remove any prior instance
76
+ await execFileAsync('docker', ['rm', '-f', RESTORE_CONTAINER]).catch(() => {});
77
+ await execFileAsync('docker', [
78
+ 'run', '-d',
79
+ '--name', RESTORE_CONTAINER,
80
+ '-e', 'POSTGRES_USER=rcf',
81
+ '-e', 'POSTGRES_PASSWORD=rcf-dev-only',
82
+ '-e', 'POSTGRES_DB=rcf_test',
83
+ '-p', `${RESTORE_PORT}:5432`,
84
+ '--health-cmd', 'pg_isready -U rcf -d rcf_test',
85
+ '--health-interval', '2s',
86
+ '--health-retries', '20',
87
+ 'postgres:17-alpine',
88
+ ]);
89
+ await waitHealthy(RESTORE_CONTAINER, 30);
90
+ }
91
+
92
+ async function tearDownRestore() {
93
+ await execFileAsync('docker', ['rm', '-f', '-v', RESTORE_CONTAINER]).catch(() => {});
94
+ }
95
+
96
+ export default async function runProbe() {
97
+ const events = [];
98
+ const store = createStore({
99
+ connectionUrl: connectionUrlFromEnv(),
100
+ onEvent: (e) => events.push(e),
101
+ });
102
+ const results = [];
103
+ try {
104
+ await store.ready();
105
+ const pool = store.getPool();
106
+
107
+ // Seed a known rowset on the source
108
+ 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())');
109
+ await pool.query('TRUNCATE users RESTART IDENTITY');
110
+ const seed = [
111
+ ['alice', 'alice@rcf.test'],
112
+ ['bob', 'bob@rcf.test'],
113
+ ['carol', 'carol@rcf.test'],
114
+ ['dan', 'dan@rcf.test'],
115
+ ['eve', 'eve@rcf.test'],
116
+ ];
117
+ for (const [name, email] of seed) {
118
+ await pool.query('INSERT INTO users(name, email) VALUES ($1, $2)', [name, email]);
119
+ }
120
+
121
+ // Compute source row-count and checksum (md5 over concatenated name|email ordered by id)
122
+ const srcCount = (await pool.query('SELECT count(*)::int AS n FROM users')).rows[0].n;
123
+ const srcCk = (await pool.query('SELECT md5(string_agg(name || $1 || email, $2 ORDER BY id))::text AS ck FROM users', ['|', ','])).rows[0].ck;
124
+
125
+ // pg_dump inside the source container to stdout, capture as artefact
126
+ await mkdir(ARTEFACT_DIR, { recursive: true });
127
+ const dump = await dockerExec(SOURCE_CONTAINER, ['pg_dump', '-U', 'rcf', '-d', 'rcf_test', '--no-owner', '--no-acl', '--format=plain']);
128
+ await writeFile(ARTEFACT, dump.stdout, 'utf8');
129
+ const bytes = Buffer.byteLength(dump.stdout, 'utf8');
130
+
131
+ // Bring up restore container
132
+ await bringUpRestore();
133
+
134
+ // Pipe artefact into psql on restore
135
+ await dockerExecStdin(RESTORE_CONTAINER, ['psql', '-U', 'rcf', '-d', 'rcf_test', '-v', 'ON_ERROR_STOP=1'], Buffer.from(dump.stdout, 'utf8'));
136
+
137
+ // Read row-count and checksum on restored
138
+ const dstStore = createStore({ connectionUrl: `postgres://rcf:${encodeURIComponent('rcf-dev-only')}@localhost:${RESTORE_PORT}/rcf_test` });
139
+ let dstCount = -1;
140
+ let dstCk = 'unset';
141
+ try {
142
+ await dstStore.ready();
143
+ const dstPool = dstStore.getPool();
144
+ dstCount = (await dstPool.query('SELECT count(*)::int AS n FROM users')).rows[0].n;
145
+ dstCk = (await dstPool.query('SELECT md5(string_agg(name || $1 || email, $2 ORDER BY id))::text AS ck FROM users', ['|', ','])).rows[0].ck;
146
+ } finally {
147
+ await dstStore.close();
148
+ }
149
+
150
+ results.push({
151
+ anchorAcId: 'AC-27105-1',
152
+ verdict: bytes > 0 ? 'pass' : 'fail',
153
+ detail: `pg_dump artefact written to ${ARTEFACT_REL} (${bytes} bytes)`,
154
+ });
155
+ results.push({
156
+ anchorAcId: 'AC-27105-1',
157
+ verdict: srcCount === dstCount ? 'pass' : 'fail',
158
+ detail: `row-count source=${srcCount} restored=${dstCount}`,
159
+ });
160
+ results.push({
161
+ anchorAcId: 'AC-27105-1',
162
+ verdict: srcCk === dstCk && srcCk != null ? 'pass' : 'fail',
163
+ detail: `checksum source=${srcCk} restored=${dstCk}`,
164
+ });
165
+ } finally {
166
+ // Cleanup: truncate source, tear down restore, delete artefact
167
+ try { await store.getPool().query('TRUNCATE users RESTART IDENTITY'); } catch { /* ignore */ }
168
+ await store.close();
169
+ await tearDownRestore();
170
+ await rm(ARTEFACT_DIR, { recursive: true, force: true }).catch(() => {});
171
+ }
172
+ return results;
173
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shim: run facade-round-trip against the sample-app fixture and write
3
+ * the per-blueprint report at .rcf/reports/blueprints/persistence-data-postgres/facade-round-trip.json.
4
+ */
5
+
6
+ import runProbe from './facade-round-trip.mjs';
7
+ import { runShim } from './probe-utils.mjs';
8
+
9
+ const engine = { kind: 'postgres', image: 'postgres:17-alpine', healthy: true };
10
+ runShim('facade-round-trip', engine, runProbe);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shim: run migration-apply against the sample-app fixture and write
3
+ * the per-blueprint report at .rcf/reports/blueprints/persistence-data-postgres/migration-apply.json.
4
+ */
5
+
6
+ import runProbe from './migration-apply.mjs';
7
+ import { runShim } from './probe-utils.mjs';
8
+
9
+ const engine = { kind: 'postgres', image: 'postgres:17-alpine', healthy: true };
10
+ runShim('migration-apply', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shim: run pool-posture-smoke.
3
+ */
4
+
5
+ import runProbe from './pool-posture-smoke.mjs';
6
+ import { runShim } from './probe-utils.mjs';
7
+
8
+ const engine = { kind: 'postgres', image: 'postgres:17-alpine', healthy: true };
9
+ runShim('pool-posture-smoke', engine, runProbe);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shim: run prepared-statement-scan against the fixture facade
3
+ * directory and write the report.
4
+ */
5
+
6
+ import runProbe from './prepared-statement-scan.mjs';
7
+ import { runShim } from './probe-utils.mjs';
8
+
9
+ const engine = { kind: 'source-scan', target: 'infra-postgres/src', healthy: true };
10
+ runShim('prepared-statement-scan', engine, runProbe);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shim: run recovery-restore-round-trip.
3
+ */
4
+
5
+ import runProbe from './recovery-restore-round-trip.mjs';
6
+ import { runShim } from './probe-utils.mjs';
7
+
8
+ const engine = { kind: 'postgres', image: 'postgres:17-alpine', healthy: true };
9
+ runShim('recovery-restore-round-trip', engine, runProbe);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shim: run transaction-atomicity against the sample-app fixture and
3
+ * write the per-blueprint report.
4
+ */
5
+
6
+ import runProbe from './transaction-atomicity.mjs';
7
+ import { runShim } from './probe-utils.mjs';
8
+
9
+ const engine = { kind: 'postgres', image: 'postgres:17-alpine', healthy: true };
10
+ runShim('transaction-atomicity', engine, runProbe);
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Transaction atomicity probe.
3
+ *
4
+ * Opens the fixture facade's transaction helper against the running
5
+ * postgres:17-alpine container, issues two INSERTs where the second
6
+ * violates the UNIQUE constraint on email, asserts:
7
+ * - the transaction rolls back
8
+ * - transactionRolledBack event fires with statementIndex 1
9
+ * - the first row does not persist after rollback
10
+ *
11
+ * Anchors AC-27104-1.
12
+ *
13
+ * Cleans up: TRUNCATE users on exit; closes the pool.
14
+ */
15
+
16
+ import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
17
+
18
+ export default async function runProbe() {
19
+ const events = [];
20
+ const store = createStore({
21
+ connectionUrl: connectionUrlFromEnv(),
22
+ onEvent: (e) => events.push(e),
23
+ });
24
+ const results = [];
25
+ try {
26
+ await store.ready();
27
+ const pool = store.getPool();
28
+ // Ensure schema and empty state
29
+ 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())');
30
+ await pool.query('TRUNCATE users');
31
+
32
+ const email = 'transaction-atomicity@rcf.test';
33
+ let caught = null;
34
+ try {
35
+ await store.withTransaction(async (tx) => {
36
+ await tx.query('INSERT INTO users(name, email) VALUES ($1, $2)', ['first-user', email]);
37
+ // Same email violates UNIQUE constraint on the second insert
38
+ await tx.query('INSERT INTO users(name, email) VALUES ($1, $2)', ['second-user', email]);
39
+ });
40
+ } catch (err) {
41
+ caught = err;
42
+ }
43
+
44
+ const errorThrown = caught !== null;
45
+ results.push({
46
+ anchorAcId: 'AC-27104-1',
47
+ verdict: errorThrown ? 'pass' : 'fail',
48
+ detail: errorThrown
49
+ ? `withTransaction re-threw underlying error code=${caught.code}`
50
+ : 'withTransaction did not throw on the constraint violation',
51
+ });
52
+
53
+ const rolledBackEvent = events.find((e) => e.event === 'transactionRolledBack');
54
+ const indexIsOne = rolledBackEvent && rolledBackEvent.statementIndex === 1;
55
+ results.push({
56
+ anchorAcId: 'AC-27104-1',
57
+ verdict: indexIsOne ? 'pass' : 'fail',
58
+ detail: rolledBackEvent
59
+ ? `transactionRolledBack fired with statementIndex=${rolledBackEvent.statementIndex} code=${rolledBackEvent.code}`
60
+ : `transactionRolledBack did not fire; events=${JSON.stringify(events)}`,
61
+ });
62
+
63
+ const count = await store.countUsers();
64
+ const noRowsPersist = count === 0;
65
+ results.push({
66
+ anchorAcId: 'AC-27104-1',
67
+ verdict: noRowsPersist ? 'pass' : 'fail',
68
+ detail: noRowsPersist
69
+ ? 'users table empty after rollback (no partial commit landed)'
70
+ : `users table carries ${count} row(s) after rollback (partial commit leaked)`,
71
+ });
72
+ } finally {
73
+ try {
74
+ await store.getPool().query('TRUNCATE users');
75
+ } catch { /* ignore */ }
76
+ await store.close();
77
+ }
78
+ return results;
79
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-001",
3
+ "prdId": "PRD-001",
4
+ "title": "One facade module is the sole reader of the pg client and opens on boot",
5
+ "description": "The application accesses Postgres through a single facade module in the project's source tree that is the ONLY module in the tree that imports and reads the pg (node-postgres) client. Every other module that touches persistence imports the facade and calls its named domain verbs; no other module holds the raw pg client, a pg.Pool reference, or a pg.PoolClient reference. On process boot, the facade opens a pg.Pool against the elicited connection URL and, once the first successful ready-check completes, emits a facadeReady lifecycle event carrying the database name. The connection URL is elicited (project-config file by default; a security-secrets-management-applied project passes a secretRef).",
6
+ "category": "functional",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "A single facade is what turns the raw pg driver surface into an application-side surface with domain-shaped verbs. Multiple call sites reaching into the driver directly produces a codebase where the shape of the store, the parameter-binding discipline, the event-emission discipline, and the pool posture are all diffused across the tree. One facade means one place to test, one place to swap (the round-6 Hyperdrive adapter slots in here without a facade re-shape), and one place where the persistence code paths are discoverable.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:01-facade"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-002",
3
+ "prdId": "PRD-001",
4
+ "title": "Schema evolution ships as numbered forward-only .sql migrations applied one file one transaction",
5
+ "description": "Schema evolution is expressed as a directory of numbered .sql migration files under the elicited migrations directory (default ./migrations/). Each filename begins with a monotonically increasing integer that is unique across the directory; the file body is engine-native SQL. An in-tree migration runner applies each file inside its own transaction (BEGIN, run the file body, COMMIT on success or ROLLBACK on error); the runner tracks applied filenames in a schema_version bookkeeping table it maintains inside the same database. There are no down migrations. Which runner tool the project reaches for is elicited (a node-pg-migrate wrap, a sqitch invocation, a flyway process, or a bespoke Node runner over pg); the discipline is what is fixed here, not the tool.",
6
+ "category": "technical",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "Numbered forward-only migrations are the general-enterprise-practice shape for schema evolution over Postgres. One file one transaction gives the runner a clean rollback surface on any statement failure; the schema_version table gives the project a single source of truth on what has been applied to the deployed database. Refusing to bless one migration tool keeps the shelf out of the maintenance stance of a tool it does not build; the runner mode is elicited so a long-lived Node process may run migrations at boot while a Workers-adjacent deployment runs them as a CI step.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:02-migration-runner"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-003",
3
+ "prdId": "PRD-001",
4
+ "title": "Prepared-statement discipline: every pg.query first argument is a static string literal with $N parameters",
5
+ "description": "Every call to pg.query (whether via the pool, a client, or a transaction helper) inside the facade module passes a static string literal as its first argument and supplies parameters as an array of values that the driver binds to $1, $2, ... $N placeholders in the string, per the node-postgres parameterised-queries contract at https://node-postgres.com/features/queries. No call site inside the facade passes a template literal with an interpolated expression as the first argument; no call site builds a query string via string concatenation or template-literal interpolation with consumer-supplied values. A call site that violates the discipline refuses at author-side review; the prepared-statement-scan probe surfaces the violation at gate time via a source-tree AST scan (per the persistence-data-d1 pattern).",
6
+ "category": "technical",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "Static string literals with $N parameters is what stops SQL injection at the driver boundary. The pg client's parameter-binding surface is safe; string concatenation with consumer-supplied values is not. The discipline is testable at build time by an AST scan without a running database, which is the shape a shelf blueprint can prove without shipping a test file (mechanism-reach principle, blueprint-authoring section 7); the runtime facade-round-trip probe carries the runtime observable that the surface works end to end.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:03-prepared-statements"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-004",
3
+ "prdId": "PRD-001",
4
+ "title": "Transactional atomicity: multi-statement writes through a transaction helper roll back on any error",
5
+ "description": "Multi-statement writes that require atomicity are issued through the facade's transaction helper, which wraps client.query('BEGIN') around a callback, awaits the callback's statements (each issued through pg.query with the prepared-statement discipline in REQ-003), and issues client.query('COMMIT') on the callback's successful completion. If any statement inside the callback throws (including a constraint violation the driver surfaces as an error), the helper issues client.query('ROLLBACK'), releases the client back to the pool, and emits a transactionRolledBack lifecycle event carrying the failing statement's zero-based index inside the callback. The helper does not swallow the underlying error; it re-throws after the rollback so the caller observes the failure and the facade's own error boundary constructs the internal error record.",
6
+ "category": "functional",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "Postgres MVCC gives transactions a clean rollback surface; the helper's job is to make the rollback observable and to guarantee no partial commit lands on the shipped database. The zero-based statement index on the event is what lets the calling code (or a log line, or an error boundary) name which statement failed inside a batch of five without a stack-trace decode.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:04-transaction-helper"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-005",
3
+ "prdId": "PRD-001",
4
+ "title": "Two-path recovery: scheduled pg_dump artefact PLUS vendor point-in-time recovery, both elicited, both required",
5
+ "description": "The recovery model is two-path and both paths are required at v1.0.0: (a) a scheduled export runner drives pg_dump via child_process.execFile against the elicited connection URL, writes the artefact to the elicited destination (a filesystem path, an S3 URL, an operator-owned path), and emits a backupExported lifecycle event carrying the artefact path and a completion timestamp; (b) the deploy target's own point-in-time recovery is enabled and its cadence and retention window are elicited (a managed Postgres cluster's PITR window, a self-managed cluster's WAL-archive posture). Neither path is optional. A fresh Postgres primed from a pg_dump artefact reads the rows committed at or before the artefact's completion timestamp; a fresh Postgres restored to a PITR point reads the rows committed at or before that point.",
6
+ "category": "functional",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "pg_dump gives a portable artefact the operator can move off the deploy target; PITR gives the fine-grained restore point pg_dump cannot. Neither alone covers the two failure classes a shipped Postgres project has to survive: a corrupted managed cluster (PITR helps only if the corruption pre-dates the retention floor; a pg_dump artefact off-cluster survives cluster loss) and a data-integrity incident an operator wants to unwind by minutes (PITR restore point; a nightly pg_dump loses too much). Two paths, both required, is the general-enterprise-practice shape.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:05-recovery"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-006",
3
+ "prdId": "PRD-001",
4
+ "title": "Connection-pool posture per deploy target: long-lived pool on Node, request-scoped isolation on container",
5
+ "description": "The facade opens a long-lived pg.Pool for the lifetime of the Node process on a long-lived-Node deploy target (a monolithic Node server, a container platform holding warm instances). On a request-scoped container platform (a serverless-container target that spins fresh instances per request, a Workers-adjacent target via the round-6 Hyperdrive adapter at ADR-2801), the facade opens a pool sized to the request budget and disposes it at request end, or delegates the pool to the round-6 Hyperdrive-managed connection pool without holding a Node-side long-lived pool. Pool size, idle timeout, and query timeout are elicited defaults that the operator overrides per target; the shipped defaults are pool size 10, idleTimeoutMillis 30000, connectionTimeoutMillis 5000, per the node-postgres pool defaults. The pool-posture-smoke probe drives twenty concurrent queries at pool size 5 and asserts all return with no timeout; the probe does not impose a sizing formula.",
6
+ "category": "technical",
7
+ "domain": "persistence",
8
+ "priority": "must",
9
+ "rationale": "Postgres has real connection cost per open, and the pool is what amortises it. A long-lived Node process wants one pool per process; a request-scoped container platform wants a pool per request (or delegated to Hyperdrive when the round-6 adapter lands). The shipped defaults are the pg driver's own defaults; the elicit surface lets an operator move them per target without moving any AC on this blueprint.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:06-pool-posture"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "reqId": "persistence-data-postgres-REQ-007",
3
+ "prdId": "PRD-001",
4
+ "title": "Advisory-lock helper (optional): session or transaction level per the Postgres explicit-locking reference, elicited default off",
5
+ "description": "The facade exposes an optional advisory-lock helper that wraps pg_advisory_lock and pg_advisory_unlock for session-level locks, and pg_advisory_xact_lock for transaction-level locks. The helper takes an integer lock key, acquires the lock, runs a callback, and releases the lock via the paired unlock verb on the session-level shape (transaction-level locks release automatically at COMMIT or ROLLBACK per https://www.postgresql.org/docs/current/explicit-locking.html). Whether the helper ships in the applied surface is elicited (advisoryLockHelper: off, session, or transaction); default off per the ratified Q1 answer on the round-5 spec section 10. The elicited value is recorded on the applied sidecar so a later validation pass can flag surfaces that never activated the option.",
6
+ "category": "functional",
7
+ "domain": "persistence",
8
+ "priority": "should",
9
+ "rationale": "Cross-process coordination on a shared Postgres (a migration coordinator, a lock-per-tenant workflow, a one-writer-per-partition pattern) is served cleanly by advisory locks; the alternative (a bespoke locks table) reinvents what the engine already gives. Shipping the helper in v1.0.0 pins the semantics before a project depends on a workaround; defaulting off keeps the applied surface small for projects that do not need it. The session-vs-transaction distinction is load-bearing: session-level locks survive rolled-back transactions per the explicit-locking reference, and pinning the choice in the ADR is what avoids the reader-side confusion.",
10
+ "tags": [
11
+ "blueprint:persistence-data-postgres",
12
+ "category:07-advisory-lock"
13
+ ],
14
+ "version": "1.0.0",
15
+ "status": "approved",
16
+ "createdAt": "2026-09-06T15:47:00.000Z",
17
+ "updatedAt": "2026-09-06T15:47:00.000Z"
18
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "tacId": "TAC-2801-persistence-data-postgres-facade",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Postgres store facade",
8
+ "purpose": "The single project-side module that imports the pg driver, exposes narrow named domain verbs to consumer code, issues every query as a static string literal with $N parameters, and emits structured lifecycle events to the injected event sink. Consumers never destructure the pg driver outside this module; the facade is the one place the vendor surface lives. The driver reference is opaque at this boundary so the round-6 Hyperdrive v1.1.0 adapter (ADR-2801) can swap the client without a facade re-shape.",
9
+ "responsibilities": [
10
+ "Open a pg.Pool on boot against the elicited connection URL; hold no other reference to the pg vendor surface; export no symbol that leaks the raw pool or client (AC-27101-1, AC-27101-2).",
11
+ "Expose named domain verbs (getUserById, createUser, listUsers, ...) as named exports with typed parameters; refuse a general-purpose raw-SQL passthrough on the public surface (AC-27101-1, AC-27103-1).",
12
+ "Issue every read and write through pg.query with a static string literal as the first argument and parameters as an array bound to $1, $2, ... $N per the node-postgres parameterised-queries contract (AC-27103-1).",
13
+ "Expose the transaction helper (TAC-2803) as a named verb; consumers pass a callback, the helper wraps BEGIN and COMMIT, ROLLBACK on error, and fires transactionRolledBack on the sink with the failing statement index (AC-27104-1).",
14
+ "Emit facadeReady exactly once per facade instance on the injected event sink with the database name; serialise pre-ready consumer queries behind the pool's ready-check (AC-27101-1, AC-27108-1).",
15
+ "Expose the optional advisory-lock helper only when the elicited answer is session or transaction; the surface is absent when the answer is off (AC-27107-1)."
16
+ ],
17
+ "internalStructure": "One module exporting a createStore({ connectionUrl, onEvent, poolConfig, advisoryLockHelper }) factory returning a Store whose methods are the named CRUD verbs plus withTransaction and (optionally) withAdvisoryLock. The pg import lives at the top of this module; the factory captures a pg.Pool and the injected sink and hands back closures. Consumers destructure the verbs they need at their top level and hold the facade reference for the process lifetime (or, on a request-scoped container platform, for the request lifetime).",
18
+ "interfaces": [
19
+ {
20
+ "name": "createStore",
21
+ "kind": "factory",
22
+ "description": "createStore({ connectionUrl, onEvent, poolConfig, advisoryLockHelper }) -> Store. The sole entry point every consumer calls. Opens a pg.Pool against connectionUrl; wires the sink; hands back a Store whose methods are the named CRUD verbs plus withTransaction and (optionally) withAdvisoryLock."
23
+ },
24
+ {
25
+ "name": "onEvent",
26
+ "kind": "callback",
27
+ "description": "Structured-event sink invoked with { event, ts, ... } for facadeReady, migrationsApplied, transactionRolledBack, backupExported, recoveryDrillPassed, queryFailed events. Never invoked with domain-row values."
28
+ },
29
+ {
30
+ "name": "store.verbs",
31
+ "kind": "read-write-api",
32
+ "description": "The named domain CRUD verbs the facade exposes. Each verb has typed parameters; no verb accepts a raw SQL string or a general query object from consumer code."
33
+ }
34
+ ],
35
+ "dependencies": [
36
+ {
37
+ "name": "Migration runner",
38
+ "kind": "tac",
39
+ "tacId": "TAC-2802-persistence-data-postgres-migration-runner",
40
+ "description": "The runner the facade or the CI step invokes to apply forward-only migrations before the facade opens its first query."
41
+ },
42
+ {
43
+ "name": "Transaction helper",
44
+ "kind": "tac",
45
+ "tacId": "TAC-2803-persistence-data-postgres-transaction-helper",
46
+ "description": "The helper wrapping BEGIN and COMMIT around a consumer callback; exposed as store.withTransaction."
47
+ },
48
+ {
49
+ "name": "Recovery runner",
50
+ "kind": "tac",
51
+ "tacId": "TAC-2804-persistence-data-postgres-recovery-runner",
52
+ "description": "Shares the facade's event sink for backupExported and recoveryDrillPassed events; invoked from the ops or CI surface, not from request code."
53
+ }
54
+ ],
55
+ "tradeoffs": "The facade holds a long-lived pool on Node targets and a request-scoped pool on container targets; the round-6 Hyperdrive adapter (ADR-2801) delegates the pool entirely to the Hyperdrive-managed pool. That flexibility costs a per-target pool decision the operator makes via ADR-2805; the facade's outward interface stays unchanged across all three postures.",
56
+ "createdAt": "2026-09-06T15:47:00.000Z",
57
+ "updatedAt": "2026-09-06T15:47:00.000Z"
58
+ }