rcf-lite 0.27.0 → 0.28.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 (601) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +10 -0
  3. package/bin/rcf.js +2 -0
  4. package/blueprints/application-account-settings/CHANGELOG.md +35 -6
  5. package/blueprints/application-account-settings/README.md +1 -1
  6. package/blueprints/application-account-settings/blueprint.json +4 -2
  7. package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +1 -1
  8. package/blueprints/application-account-settings/contributions/probes/probe-utils.mjs +177 -0
  9. package/blueprints/application-account-settings/contributions/probes/profile-form-autocomplete.mjs +67 -0
  10. package/blueprints/application-account-settings/contributions/probes/run-profile-form-autocomplete.mjs +5 -0
  11. package/blueprints/application-account-settings/contributions/probes/run-sessions-adapter-uniform.mjs +5 -0
  12. package/blueprints/application-account-settings/contributions/probes/run-sessions-surface-shape.mjs +5 -0
  13. package/blueprints/application-account-settings/contributions/probes/run-shell-tablist-per-capability.mjs +5 -0
  14. package/blueprints/application-account-settings/contributions/probes/run-theme-radiogroup.mjs +5 -0
  15. package/blueprints/application-account-settings/contributions/probes/sessions-adapter-uniform.mjs +130 -0
  16. package/blueprints/application-account-settings/contributions/probes/sessions-surface-shape.mjs +70 -0
  17. package/blueprints/application-account-settings/contributions/probes/shell-tablist-per-capability.mjs +60 -0
  18. package/blueprints/application-account-settings/contributions/probes/theme-radiogroup.mjs +126 -0
  19. package/blueprints/application-admin-console/CHANGELOG.md +32 -6
  20. package/blueprints/application-admin-console/README.md +1 -1
  21. package/blueprints/application-admin-console/blueprint.json +4 -2
  22. package/blueprints/application-admin-console/contributions/adrs/adr-2201-application-admin-console-capability-vocabulary.json +1 -1
  23. package/blueprints/application-admin-console/contributions/probes/audit-log-surface.mjs +79 -0
  24. package/blueprints/application-admin-console/contributions/probes/org-switcher-surface.mjs +83 -0
  25. package/blueprints/application-admin-console/contributions/probes/permission-matrix-grid.mjs +67 -0
  26. package/blueprints/application-admin-console/contributions/probes/probe-utils.mjs +177 -0
  27. package/blueprints/application-admin-console/contributions/probes/run-audit-log-surface.mjs +5 -0
  28. package/blueprints/application-admin-console/contributions/probes/run-org-switcher-surface.mjs +5 -0
  29. package/blueprints/application-admin-console/contributions/probes/run-permission-matrix-grid.mjs +5 -0
  30. package/blueprints/application-admin-console/contributions/probes/run-sign-in-access-gated-surface.mjs +5 -0
  31. package/blueprints/application-admin-console/contributions/probes/run-users-directory-surface.mjs +5 -0
  32. package/blueprints/application-admin-console/contributions/probes/sign-in-access-gated-surface.mjs +117 -0
  33. package/blueprints/application-admin-console/contributions/probes/users-directory-surface.mjs +145 -0
  34. package/blueprints/application-api-rest/CHANGELOG.md +16 -8
  35. package/blueprints/application-api-rest/README.md +3 -3
  36. package/blueprints/application-api-rest/blueprint.json +3 -2
  37. package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +1 -1
  38. package/blueprints/application-api-rest/contributions/probes/cursor-pagination-round-trip.mjs +154 -0
  39. package/blueprints/application-api-rest/contributions/probes/health-probes-distinct.mjs +124 -0
  40. package/blueprints/application-api-rest/contributions/probes/probe-utils.mjs +177 -0
  41. package/blueprints/application-api-rest/contributions/probes/problem-details-on-error.mjs +77 -0
  42. package/blueprints/application-api-rest/contributions/probes/request-id-echoed.mjs +76 -0
  43. package/blueprints/application-api-rest/contributions/probes/run-cursor-pagination-round-trip.mjs +5 -0
  44. package/blueprints/application-api-rest/contributions/probes/run-health-probes-distinct.mjs +5 -0
  45. package/blueprints/application-api-rest/contributions/probes/run-problem-details-on-error.mjs +5 -0
  46. package/blueprints/application-api-rest/contributions/probes/run-request-id-echoed.mjs +5 -0
  47. package/blueprints/application-api-rest/docs/topics.md +1 -1
  48. package/blueprints/application-charts/CHANGELOG.md +35 -9
  49. package/blueprints/application-charts/README.md +6 -6
  50. package/blueprints/application-charts/blueprint.json +5 -3
  51. package/blueprints/application-charts/contributions/adrs/adr-1901-application-charts-engine-choice.json +1 -1
  52. package/blueprints/application-charts/contributions/probes/keyboard-traversal.mjs +151 -0
  53. package/blueprints/application-charts/contributions/probes/non-colour-distinction.mjs +67 -0
  54. package/blueprints/application-charts/contributions/probes/probe-utils.mjs +177 -0
  55. package/blueprints/application-charts/contributions/probes/run-keyboard-traversal.mjs +5 -0
  56. package/blueprints/application-charts/contributions/probes/run-non-colour-distinction.mjs +5 -0
  57. package/blueprints/application-charts/contributions/probes/run-text-alternative-table.mjs +5 -0
  58. package/blueprints/application-charts/contributions/probes/text-alternative-table.mjs +139 -0
  59. package/blueprints/application-charts/contributions/requirements/application-charts-req-001.json +1 -1
  60. package/blueprints/application-charts/contributions/requirements/application-charts-req-002.json +1 -1
  61. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18101.json +5 -5
  62. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18106.json +1 -1
  63. package/blueprints/application-charts/guide/application-charts.md +1 -1
  64. package/blueprints/application-dashboard/CHANGELOG.md +20 -10
  65. package/blueprints/application-dashboard/README.md +6 -6
  66. package/blueprints/application-dashboard/assets/guidance/dashboard-design.md +2 -2
  67. package/blueprints/application-dashboard/blueprint.json +3 -2
  68. package/blueprints/application-dashboard/contributions/adrs/adr-2001-application-dashboard-primary-kpi-enum.json +1 -1
  69. package/blueprints/application-dashboard/contributions/adrs/adr-2002-application-dashboard-timeframe-presets.json +1 -1
  70. package/blueprints/application-dashboard/contributions/probes/export-handle-formats.mjs +75 -0
  71. package/blueprints/application-dashboard/contributions/probes/four-tile-states.mjs +75 -0
  72. package/blueprints/application-dashboard/contributions/probes/primary-kpi-top-left.mjs +58 -0
  73. package/blueprints/application-dashboard/contributions/probes/probe-utils.mjs +177 -0
  74. package/blueprints/application-dashboard/contributions/probes/run-export-handle-formats.mjs +4 -0
  75. package/blueprints/application-dashboard/contributions/probes/run-four-tile-states.mjs +4 -0
  76. package/blueprints/application-dashboard/contributions/probes/run-primary-kpi-top-left.mjs +4 -0
  77. package/blueprints/application-dashboard/contributions/probes/run-shell-five-regions.mjs +4 -0
  78. package/blueprints/application-dashboard/contributions/probes/shell-five-regions.mjs +93 -0
  79. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-002.json +1 -1
  80. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-003.json +1 -1
  81. package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +1 -1
  82. package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +2 -2
  83. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19101.json +2 -2
  84. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19102.json +2 -2
  85. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19103.json +1 -1
  86. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19104.json +1 -1
  87. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19105.json +1 -1
  88. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +2 -2
  89. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19107.json +5 -5
  90. package/blueprints/application-dashboard/docs/topics.md +2 -2
  91. package/blueprints/application-dashboard/guide/application-dashboard.md +2 -2
  92. package/blueprints/application-datatable/CHANGELOG.md +19 -9
  93. package/blueprints/application-datatable/README.md +2 -2
  94. package/blueprints/application-datatable/blueprint.json +3 -2
  95. package/blueprints/application-datatable/contributions/probes/apg-table-shape.mjs +57 -0
  96. package/blueprints/application-datatable/contributions/probes/four-states-regions.mjs +80 -0
  97. package/blueprints/application-datatable/contributions/probes/probe-utils.mjs +177 -0
  98. package/blueprints/application-datatable/contributions/probes/run-apg-table-shape.mjs +4 -0
  99. package/blueprints/application-datatable/contributions/probes/run-four-states-regions.mjs +4 -0
  100. package/blueprints/application-datatable/contributions/probes/run-search-adapter-round-trip.mjs +4 -0
  101. package/blueprints/application-datatable/contributions/probes/run-sort-adapter-round-trip.mjs +4 -0
  102. package/blueprints/application-datatable/contributions/probes/search-adapter-round-trip.mjs +58 -0
  103. package/blueprints/application-datatable/contributions/probes/sort-adapter-round-trip.mjs +60 -0
  104. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-006.json +1 -1
  105. package/blueprints/application-datatable/docs/topics.md +1 -1
  106. package/blueprints/application-empty-error-states/CHANGELOG.md +33 -3
  107. package/blueprints/application-empty-error-states/blueprint.json +4 -2
  108. package/blueprints/application-empty-error-states/contributions/probes/empty-list-and-no-search.mjs +66 -0
  109. package/blueprints/application-empty-error-states/contributions/probes/error-boundary-alert.mjs +65 -0
  110. package/blueprints/application-empty-error-states/contributions/probes/forbidden-and-server-error.mjs +167 -0
  111. package/blueprints/application-empty-error-states/contributions/probes/not-found-and-recovery.mjs +61 -0
  112. package/blueprints/application-empty-error-states/contributions/probes/permission-denied-and-offline.mjs +155 -0
  113. package/blueprints/application-empty-error-states/contributions/probes/probe-utils.mjs +177 -0
  114. package/blueprints/application-empty-error-states/contributions/probes/run-empty-list-and-no-search.mjs +5 -0
  115. package/blueprints/application-empty-error-states/contributions/probes/run-error-boundary-alert.mjs +5 -0
  116. package/blueprints/application-empty-error-states/contributions/probes/run-forbidden-and-server-error.mjs +5 -0
  117. package/blueprints/application-empty-error-states/contributions/probes/run-not-found-and-recovery.mjs +5 -0
  118. package/blueprints/application-empty-error-states/contributions/probes/run-permission-denied-and-offline.mjs +5 -0
  119. package/blueprints/application-error-handling/CHANGELOG.md +45 -6
  120. package/blueprints/application-error-handling/blueprint.json +3 -2
  121. package/blueprints/application-error-handling/contributions/probes/category-vocabulary.mjs +90 -0
  122. package/blueprints/application-error-handling/contributions/probes/probe-utils.mjs +177 -0
  123. package/blueprints/application-error-handling/contributions/probes/record-shape-adr-1701.mjs +78 -0
  124. package/blueprints/application-error-handling/contributions/probes/run-category-vocabulary.mjs +5 -0
  125. package/blueprints/application-error-handling/contributions/probes/run-record-shape-adr-1701.mjs +5 -0
  126. package/blueprints/application-error-handling/contributions/probes/run-two-boundaries-registered.mjs +5 -0
  127. package/blueprints/application-error-handling/contributions/probes/two-boundaries-registered.mjs +343 -0
  128. package/blueprints/application-file-upload/CHANGELOG.md +28 -6
  129. package/blueprints/application-file-upload/README.md +1 -1
  130. package/blueprints/application-file-upload/blueprint.json +3 -2
  131. package/blueprints/application-file-upload/contributions/probes/assertive-completion-slot.mjs +78 -0
  132. package/blueprints/application-file-upload/contributions/probes/chunked-transport-endpoints.mjs +173 -0
  133. package/blueprints/application-file-upload/contributions/probes/per-file-progressbar.mjs +124 -0
  134. package/blueprints/application-file-upload/contributions/probes/probe-utils.mjs +177 -0
  135. package/blueprints/application-file-upload/contributions/probes/run-assertive-completion-slot.mjs +4 -0
  136. package/blueprints/application-file-upload/contributions/probes/run-chunked-transport-endpoints.mjs +4 -0
  137. package/blueprints/application-file-upload/contributions/probes/run-per-file-progressbar.mjs +4 -0
  138. package/blueprints/application-file-upload/contributions/probes/run-upload-surface-shape.mjs +4 -0
  139. package/blueprints/application-file-upload/contributions/probes/upload-surface-shape.mjs +55 -0
  140. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +1 -1
  141. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +1 -1
  142. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +1 -1
  143. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +1 -1
  144. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +1 -1
  145. package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +1 -1
  146. package/blueprints/application-forms-wizard/CHANGELOG.md +20 -6
  147. package/blueprints/application-forms-wizard/README.md +2 -2
  148. package/blueprints/application-forms-wizard/blueprint.json +3 -2
  149. package/blueprints/application-forms-wizard/contributions/probes/draft-persistence-round-trip.mjs +110 -0
  150. package/blueprints/application-forms-wizard/contributions/probes/probe-utils.mjs +177 -0
  151. package/blueprints/application-forms-wizard/contributions/probes/run-draft-persistence-round-trip.mjs +4 -0
  152. package/blueprints/application-forms-wizard/contributions/probes/run-step-page-shape.mjs +4 -0
  153. package/blueprints/application-forms-wizard/contributions/probes/run-task-list-surface.mjs +4 -0
  154. package/blueprints/application-forms-wizard/contributions/probes/step-page-shape.mjs +61 -0
  155. package/blueprints/application-forms-wizard/contributions/probes/task-list-surface.mjs +109 -0
  156. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +1 -1
  157. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +1 -1
  158. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +1 -1
  159. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +1 -1
  160. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +1 -1
  161. package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +1 -1
  162. package/blueprints/application-notifications-in-app/CHANGELOG.md +38 -5
  163. package/blueprints/application-notifications-in-app/README.md +4 -4
  164. package/blueprints/application-notifications-in-app/blueprint.json +4 -2
  165. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2101-application-notifications-in-app-live-region-role-mapping.json +1 -1
  166. package/blueprints/application-notifications-in-app/contributions/probes/centre-acknowledge-round-trip.mjs +210 -0
  167. package/blueprints/application-notifications-in-app/contributions/probes/live-region-preseeding.mjs +93 -0
  168. package/blueprints/application-notifications-in-app/contributions/probes/probe-utils.mjs +177 -0
  169. package/blueprints/application-notifications-in-app/contributions/probes/run-centre-acknowledge-round-trip.mjs +5 -0
  170. package/blueprints/application-notifications-in-app/contributions/probes/run-live-region-preseeding.mjs +5 -0
  171. package/blueprints/application-notifications-in-app/contributions/probes/run-toast-contract.mjs +5 -0
  172. package/blueprints/application-notifications-in-app/contributions/probes/toast-contract.mjs +92 -0
  173. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +3 -3
  174. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +1 -1
  175. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +1 -1
  176. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +1 -1
  177. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +1 -1
  178. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +1 -1
  179. package/blueprints/application-notifications-in-app/guide/application-notifications-in-app.md +3 -3
  180. package/blueprints/application-onboarding-tour/CHANGELOG.md +31 -5
  181. package/blueprints/application-onboarding-tour/README.md +1 -1
  182. package/blueprints/application-onboarding-tour/blueprint.json +5 -3
  183. package/blueprints/application-onboarding-tour/contributions/probes/checklist-anchor-open.mjs +81 -0
  184. package/blueprints/application-onboarding-tour/contributions/probes/completion-persistence.mjs +159 -0
  185. package/blueprints/application-onboarding-tour/contributions/probes/first-run-detection.mjs +67 -0
  186. package/blueprints/application-onboarding-tour/contributions/probes/probe-utils.mjs +177 -0
  187. package/blueprints/application-onboarding-tour/contributions/probes/run-checklist-anchor-open.mjs +5 -0
  188. package/blueprints/application-onboarding-tour/contributions/probes/run-completion-persistence.mjs +5 -0
  189. package/blueprints/application-onboarding-tour/contributions/probes/run-first-run-detection.mjs +5 -0
  190. package/blueprints/application-onboarding-tour/contributions/probes/run-stepper-role-dialog.mjs +5 -0
  191. package/blueprints/application-onboarding-tour/contributions/probes/stepper-role-dialog.mjs +45 -0
  192. package/blueprints/application-spa/CHANGELOG.md +20 -11
  193. package/blueprints/application-spa/README.md +9 -10
  194. package/blueprints/application-spa/blueprint.json +3 -2
  195. package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +1 -1
  196. package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +1 -1
  197. package/blueprints/application-spa/contributions/probes/designed-empty-state.mjs +72 -0
  198. package/blueprints/application-spa/contributions/probes/probe-utils.mjs +177 -0
  199. package/blueprints/application-spa/contributions/probes/route-inventory-published.mjs +185 -0
  200. package/blueprints/application-spa/contributions/probes/run-designed-empty-state.mjs +5 -0
  201. package/blueprints/application-spa/contributions/probes/run-route-inventory-published.mjs +5 -0
  202. package/blueprints/application-spa/contributions/probes/run-shell-nav-present.mjs +5 -0
  203. package/blueprints/application-spa/contributions/probes/shell-nav-present.mjs +69 -0
  204. package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +1 -1
  205. package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +2 -2
  206. package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +3 -3
  207. package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +2 -2
  208. package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +2 -2
  209. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +1 -1
  210. package/blueprints/application-spa/docs/topics.md +1 -1
  211. package/blueprints/delivery-ci-workflows/CHANGELOG.md +31 -11
  212. package/blueprints/delivery-ci-workflows/README.md +3 -3
  213. package/blueprints/delivery-ci-workflows/blueprint.json +3 -2
  214. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-702-delivery-ci-workflows-strict-coverage-gate.json +2 -2
  215. package/blueprints/delivery-ci-workflows/contributions/probes/node-gate-entrypoint.mjs +76 -0
  216. package/blueprints/delivery-ci-workflows/contributions/probes/probe-utils.mjs +56 -0
  217. package/blueprints/delivery-ci-workflows/contributions/probes/real-account-github-actions-run-record.mjs +139 -0
  218. package/blueprints/delivery-ci-workflows/contributions/probes/run-node-gate-entrypoint.mjs +3 -0
  219. package/blueprints/delivery-ci-workflows/contributions/probes/run-real-account-github-actions-run-record.mjs +3 -0
  220. package/blueprints/delivery-ci-workflows/contributions/probes/run-workflow-template-shape.mjs +3 -0
  221. package/blueprints/delivery-ci-workflows/contributions/probes/workflow-template-shape.mjs +94 -0
  222. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +1 -1
  223. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -3
  224. package/blueprints/deploy-cloudflare-workers/CHANGELOG.md +4 -4
  225. package/blueprints/deploy-cloudflare-workers/README.md +3 -3
  226. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1306-deploy-cloudflare-workers-spa-shape.json +2 -2
  227. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  228. package/blueprints/deploy-hetzner-server/CHANGELOG.md +98 -7
  229. package/blueprints/deploy-hetzner-server/blueprint.json +7 -6
  230. package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +46 -21
  231. package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +344 -83
  232. package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +211 -42
  233. package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +140 -22
  234. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +111 -30
  235. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +158 -30
  236. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +154 -32
  237. package/blueprints/edge-cloudflare-access/CHANGELOG.md +6 -5
  238. package/blueprints/edge-cloudflare-access/blueprint.json +1 -1
  239. package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +9 -1
  240. package/blueprints/edge-cloudflare-access/docs/topics.md +1 -1
  241. package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +4 -7
  242. package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +1 -1
  243. package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +4 -6
  244. package/blueprints/edge-cloudflare-tunnel/README.md +1 -2
  245. package/blueprints/edge-cloudflare-tunnel/docs/topics.md +1 -1
  246. package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +2 -3
  247. package/blueprints/edge-cloudflare-turnstile/docs/topics.md +1 -1
  248. package/blueprints/email-smtp-resend/CHANGELOG.md +24 -8
  249. package/blueprints/email-smtp-resend/README.md +2 -2
  250. package/blueprints/email-smtp-resend/blueprint.json +3 -2
  251. package/blueprints/email-smtp-resend/contributions/probes/probe-utils.mjs +50 -0
  252. package/blueprints/email-smtp-resend/contributions/probes/real-account-resend-send.mjs +50 -0
  253. package/blueprints/email-smtp-resend/contributions/probes/run-real-account-resend-send.mjs +3 -0
  254. package/blueprints/email-smtp-resend/contributions/probes/run-smtp-round-trip.mjs +3 -0
  255. package/blueprints/email-smtp-resend/contributions/probes/run-unverified-sender-refusal.mjs +3 -0
  256. package/blueprints/email-smtp-resend/contributions/probes/smtp-round-trip.mjs +43 -0
  257. package/blueprints/email-smtp-resend/contributions/probes/unverified-sender-refusal.mjs +99 -0
  258. package/blueprints/email-smtp-resend/docs/topics.md +2 -3
  259. package/blueprints/jobs-background/CHANGELOG.md +66 -5
  260. package/blueprints/jobs-background/README.md +2 -2
  261. package/blueprints/jobs-background/blueprint.json +3 -2
  262. package/blueprints/jobs-background/contributions/probes/apply-time-override.mjs +38 -10
  263. package/blueprints/jobs-background/contributions/probes/apply-time-refusal.mjs +28 -6
  264. package/blueprints/jobs-background/contributions/probes/event-secrecy.mjs +16 -2
  265. package/blueprints/jobs-background/contributions/probes/fake-clock-cron.mjs +102 -21
  266. package/blueprints/jobs-background/contributions/probes/probe-utils.mjs +10 -2
  267. package/blueprints/jobs-background/contributions/probes/retry-and-fail-real-account.mjs +355 -0
  268. package/blueprints/jobs-background/contributions/probes/retry-and-fail.mjs +33 -2
  269. package/blueprints/jobs-background/contributions/probes/run-retry-and-fail-real-account.mjs +12 -0
  270. package/blueprints/jobs-background/docs/topics.md +1 -1
  271. package/blueprints/jobs-background/guide/jobs-background.md +1 -1
  272. package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +25 -19
  273. package/blueprints/messaging-queue-cloudflare/README.md +12 -12
  274. package/blueprints/messaging-queue-cloudflare/blueprint.json +1 -1
  275. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3001-messaging-queue-cloudflare-adapter.json +2 -2
  276. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3002-messaging-queue-cloudflare-delivery-semantics.json +1 -1
  277. package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +180 -12
  278. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +1 -1
  279. package/blueprints/messaging-queue-cloudflare/docs/topics.md +2 -2
  280. package/blueprints/messaging-queue-cloudflare/guide/messaging-queue-cloudflare.md +2 -2
  281. package/blueprints/object-storage-s3/CHANGELOG.md +75 -4
  282. package/blueprints/object-storage-s3/blueprint.json +3 -2
  283. package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +73 -12
  284. package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +55 -7
  285. package/blueprints/object-storage-s3/contributions/probes/hetzner-object-storage-round-trip.mjs +102 -18
  286. package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +105 -36
  287. package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +104 -55
  288. package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +129 -7
  289. package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +80 -18
  290. package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +291 -37
  291. package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +8 -2
  292. package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +5 -5
  293. package/blueprints/object-storage-s3/contributions/probes/run-hetzner-object-storage-round-trip.mjs +8 -5
  294. package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +8 -2
  295. package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +8 -2
  296. package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +6 -3
  297. package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +10 -2
  298. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +1 -1
  299. package/blueprints/object-storage-s3/docs/topics.md +1 -1
  300. package/blueprints/object-storage-s3/guide/object-storage-s3.md +1 -1
  301. package/blueprints/observability-essentials/CHANGELOG.md +23 -7
  302. package/blueprints/observability-essentials/README.md +2 -2
  303. package/blueprints/observability-essentials/assets/probe-samples/probe-response-baseline.v2.json +1 -1
  304. package/blueprints/observability-essentials/blueprint.json +3 -2
  305. package/blueprints/observability-essentials/contributions/probes/liveness-probe.mjs +84 -0
  306. package/blueprints/observability-essentials/contributions/probes/metrics-endpoint.mjs +96 -0
  307. package/blueprints/observability-essentials/contributions/probes/probe-utils.mjs +52 -0
  308. package/blueprints/observability-essentials/contributions/probes/readiness-probe.mjs +171 -0
  309. package/blueprints/observability-essentials/contributions/probes/run-liveness-probe.mjs +3 -0
  310. package/blueprints/observability-essentials/contributions/probes/run-metrics-endpoint.mjs +3 -0
  311. package/blueprints/observability-essentials/contributions/probes/run-readiness-probe.mjs +3 -0
  312. package/blueprints/observability-essentials/docs/topics.md +2 -3
  313. package/blueprints/observability-logging/CHANGELOG.md +29 -4
  314. package/blueprints/observability-logging/README.md +2 -2
  315. package/blueprints/observability-logging/blueprint.json +3 -2
  316. package/blueprints/observability-logging/contributions/probes/correlation-id-flow.mjs +173 -0
  317. package/blueprints/observability-logging/contributions/probes/line-shape-and-fields.mjs +82 -0
  318. package/blueprints/observability-logging/contributions/probes/probe-utils.mjs +47 -0
  319. package/blueprints/observability-logging/contributions/probes/redaction-boundary.mjs +130 -0
  320. package/blueprints/observability-logging/contributions/probes/run-correlation-id-flow.mjs +3 -0
  321. package/blueprints/observability-logging/contributions/probes/run-line-shape-and-fields.mjs +3 -0
  322. package/blueprints/observability-logging/contributions/probes/run-redaction-boundary.mjs +3 -0
  323. package/blueprints/observability-probe-endpoints/CHANGELOG.md +23 -8
  324. package/blueprints/observability-probe-endpoints/README.md +3 -3
  325. package/blueprints/observability-probe-endpoints/blueprint.json +3 -2
  326. package/blueprints/observability-probe-endpoints/contributions/probes/kubernetes-startup-enabled.mjs +80 -0
  327. package/blueprints/observability-probe-endpoints/contributions/probes/partial-profile-refusal.mjs +101 -0
  328. package/blueprints/observability-probe-endpoints/contributions/probes/probe-utils.mjs +49 -0
  329. package/blueprints/observability-probe-endpoints/contributions/probes/profile-boot-materialisation.mjs +69 -0
  330. package/blueprints/observability-probe-endpoints/contributions/probes/run-kubernetes-startup-enabled.mjs +3 -0
  331. package/blueprints/observability-probe-endpoints/contributions/probes/run-partial-profile-refusal.mjs +3 -0
  332. package/blueprints/observability-probe-endpoints/contributions/probes/run-profile-boot-materialisation.mjs +3 -0
  333. package/blueprints/observability-probe-endpoints/docs/topics.md +2 -2
  334. package/blueprints/persistence-data-d1/CHANGELOG.md +16 -3
  335. package/blueprints/persistence-data-d1/README.md +2 -2
  336. package/blueprints/persistence-data-d1/blueprint.json +3 -2
  337. package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +1 -1
  338. package/blueprints/persistence-data-d1/contributions/probes/facade-round-trip.mjs +140 -0
  339. package/blueprints/persistence-data-d1/contributions/probes/migrations-forward-only.mjs +66 -0
  340. package/blueprints/persistence-data-d1/contributions/probes/probe-utils.mjs +51 -0
  341. package/blueprints/persistence-data-d1/contributions/probes/real-account-d1-round-trip.mjs +133 -0
  342. package/blueprints/persistence-data-d1/contributions/probes/run-facade-round-trip.mjs +3 -0
  343. package/blueprints/persistence-data-d1/contributions/probes/run-migrations-forward-only.mjs +3 -0
  344. package/blueprints/persistence-data-d1/contributions/probes/run-real-account-d1-round-trip.mjs +3 -0
  345. package/blueprints/persistence-data-d1/docs/topics.md +2 -3
  346. package/blueprints/persistence-data-postgres/CHANGELOG.md +84 -4
  347. package/blueprints/persistence-data-postgres/README.md +2 -2
  348. package/blueprints/persistence-data-postgres/blueprint.json +3 -2
  349. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +1 -1
  350. package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +87 -12
  351. package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +245 -19
  352. package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +109 -26
  353. package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +151 -38
  354. package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +24 -6
  355. package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +261 -48
  356. package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +76 -20
  357. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +1 -1
  358. package/blueprints/persistence-data-postgres/docs/topics.md +1 -1
  359. package/blueprints/persistence-data-sqlite/CHANGELOG.md +16 -2
  360. package/blueprints/persistence-data-sqlite/README.md +2 -2
  361. package/blueprints/persistence-data-sqlite/blueprint.json +3 -2
  362. package/blueprints/persistence-data-sqlite/contributions/probes/boot-open-migrate.mjs +90 -0
  363. package/blueprints/persistence-data-sqlite/contributions/probes/facade-round-trip.mjs +82 -0
  364. package/blueprints/persistence-data-sqlite/contributions/probes/probe-utils.mjs +83 -0
  365. package/blueprints/persistence-data-sqlite/contributions/probes/run-boot-open-migrate.mjs +5 -0
  366. package/blueprints/persistence-data-sqlite/contributions/probes/run-facade-round-trip.mjs +5 -0
  367. package/blueprints/persistence-data-sqlite/contributions/probes/run-wal-checkpoint.mjs +5 -0
  368. package/blueprints/persistence-data-sqlite/contributions/probes/wal-checkpoint.mjs +137 -0
  369. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -3
  370. package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +5 -5
  371. package/blueprints/platform-cloudflare-cron-triggers/README.md +2 -3
  372. package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +1 -1
  373. package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +6 -10
  374. package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +1 -1
  375. package/blueprints/platform-cloudflare-kv/CHANGELOG.md +16 -12
  376. package/blueprints/platform-cloudflare-kv/README.md +2 -4
  377. package/blueprints/platform-cloudflare-kv/blueprint.json +2 -2
  378. package/blueprints/platform-cloudflare-kv/docs/topics.md +1 -1
  379. package/blueprints/platform-docker-compose-host/CHANGELOG.md +92 -5
  380. package/blueprints/platform-docker-compose-host/blueprint.json +2 -2
  381. package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +116 -29
  382. package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +181 -109
  383. package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +146 -26
  384. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +238 -24
  385. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +207 -21
  386. package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +246 -42
  387. package/blueprints/platform-docker-compose-host/docs/topics.md +1 -1
  388. package/blueprints/security-auth-clerk/CHANGELOG.md +18 -6
  389. package/blueprints/security-auth-clerk/README.md +3 -3
  390. package/blueprints/security-auth-clerk/assets/wiring/workers-wrangler-toml-shape.md +1 -1
  391. package/blueprints/security-auth-clerk/blueprint.json +3 -2
  392. package/blueprints/security-auth-clerk/contributions/probes/hosted-identity-ui-config.mjs +61 -0
  393. package/blueprints/security-auth-clerk/contributions/probes/probe-utils.mjs +188 -0
  394. package/blueprints/security-auth-clerk/contributions/probes/real-account-principal-directory-round-trip.mjs +216 -0
  395. package/blueprints/security-auth-clerk/contributions/probes/real-account-session-inventory.mjs +260 -0
  396. package/blueprints/security-auth-clerk/contributions/probes/role-model-adapter.mjs +53 -0
  397. package/blueprints/security-auth-clerk/contributions/probes/run-hosted-identity-ui-config.mjs +4 -0
  398. package/blueprints/security-auth-clerk/contributions/probes/run-real-account-principal-directory-round-trip.mjs +4 -0
  399. package/blueprints/security-auth-clerk/contributions/probes/run-real-account-session-inventory.mjs +4 -0
  400. package/blueprints/security-auth-clerk/contributions/probes/run-role-model-adapter.mjs +4 -0
  401. package/blueprints/security-auth-clerk/docs/topics.md +2 -3
  402. package/blueprints/security-auth-keycloak/CHANGELOG.md +18 -7
  403. package/blueprints/security-auth-keycloak/README.md +2 -2
  404. package/blueprints/security-auth-keycloak/blueprint.json +3 -2
  405. package/blueprints/security-auth-keycloak/contributions/probes/discovery-shape.mjs +68 -0
  406. package/blueprints/security-auth-keycloak/contributions/probes/introspection-shape.mjs +88 -0
  407. package/blueprints/security-auth-keycloak/contributions/probes/jwt-verifier-shape.mjs +86 -0
  408. package/blueprints/security-auth-keycloak/contributions/probes/probe-utils.mjs +180 -0
  409. package/blueprints/security-auth-keycloak/contributions/probes/real-account-realm-round-trip.mjs +91 -0
  410. package/blueprints/security-auth-keycloak/contributions/probes/role-adapter-shape.mjs +69 -0
  411. package/blueprints/security-auth-keycloak/contributions/probes/run-discovery-shape.mjs +4 -0
  412. package/blueprints/security-auth-keycloak/contributions/probes/run-introspection-shape.mjs +4 -0
  413. package/blueprints/security-auth-keycloak/contributions/probes/run-jwt-verifier-shape.mjs +4 -0
  414. package/blueprints/security-auth-keycloak/contributions/probes/run-real-account-realm-round-trip.mjs +4 -0
  415. package/blueprints/security-auth-keycloak/contributions/probes/run-role-adapter-shape.mjs +4 -0
  416. package/blueprints/security-auth-keycloak/docs/topics.md +1 -2
  417. package/blueprints/security-auth-magic-link/CHANGELOG.md +15 -4
  418. package/blueprints/security-auth-magic-link/README.md +2 -2
  419. package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +1 -1
  420. package/blueprints/security-auth-magic-link/blueprint.json +3 -2
  421. package/blueprints/security-auth-magic-link/contributions/probes/probe-utils.mjs +174 -0
  422. package/blueprints/security-auth-magic-link/contributions/probes/real-account-magic-link-send.mjs +139 -0
  423. package/blueprints/security-auth-magic-link/contributions/probes/run-real-account-magic-link-send.mjs +4 -0
  424. package/blueprints/security-auth-magic-link/contributions/probes/run-token-entropy-shape.mjs +4 -0
  425. package/blueprints/security-auth-magic-link/contributions/probes/run-token-issue-verify.mjs +4 -0
  426. package/blueprints/security-auth-magic-link/contributions/probes/token-entropy-shape.mjs +60 -0
  427. package/blueprints/security-auth-magic-link/contributions/probes/token-issue-verify.mjs +90 -0
  428. package/blueprints/security-auth-magic-link/docs/topics.md +1 -1
  429. package/blueprints/security-auth-oauth2/CHANGELOG.md +16 -5
  430. package/blueprints/security-auth-oauth2/README.md +2 -2
  431. package/blueprints/security-auth-oauth2/blueprint.json +3 -2
  432. package/blueprints/security-auth-oauth2/contributions/probes/authorisation-code-flow-shape.mjs +259 -0
  433. package/blueprints/security-auth-oauth2/contributions/probes/pkce-challenge-shape.mjs +58 -0
  434. package/blueprints/security-auth-oauth2/contributions/probes/probe-utils.mjs +190 -0
  435. package/blueprints/security-auth-oauth2/contributions/probes/provider-adapter-shape.mjs +64 -0
  436. package/blueprints/security-auth-oauth2/contributions/probes/real-account-authorisation-code-flow.mjs +93 -0
  437. package/blueprints/security-auth-oauth2/contributions/probes/run-authorisation-code-flow-shape.mjs +4 -0
  438. package/blueprints/security-auth-oauth2/contributions/probes/run-pkce-challenge-shape.mjs +4 -0
  439. package/blueprints/security-auth-oauth2/contributions/probes/run-provider-adapter-shape.mjs +4 -0
  440. package/blueprints/security-auth-oauth2/contributions/probes/run-real-account-authorisation-code-flow.mjs +4 -0
  441. package/blueprints/security-auth-oauth2/contributions/probes/run-session-bridge-shape.mjs +4 -0
  442. package/blueprints/security-auth-oauth2/contributions/probes/session-bridge-shape.mjs +78 -0
  443. package/blueprints/security-auth-oauth2/docs/topics.md +1 -2
  444. package/blueprints/security-secrets-management/CHANGELOG.md +15 -4
  445. package/blueprints/security-secrets-management/README.md +2 -2
  446. package/blueprints/security-secrets-management/blueprint.json +3 -2
  447. package/blueprints/security-secrets-management/contributions/probes/add-recipient-rotation.mjs +107 -0
  448. package/blueprints/security-secrets-management/contributions/probes/encrypt-decrypt-round-trip.mjs +122 -0
  449. package/blueprints/security-secrets-management/contributions/probes/key-rotation.mjs +93 -0
  450. package/blueprints/security-secrets-management/contributions/probes/mismatched-key-refusal.mjs +74 -0
  451. package/blueprints/security-secrets-management/contributions/probes/probe-utils.mjs +214 -0
  452. package/blueprints/security-secrets-management/contributions/probes/run-add-recipient-rotation.mjs +4 -0
  453. package/blueprints/security-secrets-management/contributions/probes/run-encrypt-decrypt-round-trip.mjs +4 -0
  454. package/blueprints/security-secrets-management/contributions/probes/run-key-rotation.mjs +4 -0
  455. package/blueprints/security-secrets-management/contributions/probes/run-mismatched-key-refusal.mjs +4 -0
  456. package/blueprints/security-secrets-management/docs/topics.md +2 -3
  457. package/fixtures/canary-manifest.json +9 -9
  458. package/guidance/harness-template.md +25 -0
  459. package/guidance/managed/agent-instructions-block.hash +1 -1
  460. package/guidance/managed/agent-instructions-block.md +25 -0
  461. package/package.json +2 -2
  462. package/rcf/adrs/adr-4101-feedback-store-gitignored.json +20 -0
  463. package/rcf/adrs/adr-4102-fingerprint-and-labels.json +25 -0
  464. package/rcf/adrs/adr-4103-redaction-rule-based.json +20 -0
  465. package/rcf/adrs/adr-4104-destination-on-library.json +25 -0
  466. package/rcf/adrs/adr-4105-gh-ambient-auth.json +20 -0
  467. package/rcf/adrs/adr-4106-bundled-entries-terminal.json +20 -0
  468. package/rcf/adrs/adr-4107-stop-is-ask-event.json +30 -0
  469. package/rcf/adrs/adr-4108-hooks-in-committed-config.json +25 -0
  470. package/rcf/adrs/adr-4109-referee-validate-adr-crosslinks.json +25 -0
  471. package/rcf/adrs/adr-4110-referee-coverage-strict-by-default.json +25 -0
  472. package/rcf/adrs/adr-4111-referee-finalise-refusals.json +20 -0
  473. package/rcf/adrs/adr-4112-referee-finalise-verified-invariant.json +30 -0
  474. package/rcf/code-nodes/cn-600.json +45 -0
  475. package/rcf/code-nodes/cn-601.json +18 -0
  476. package/rcf/code-nodes/cn-602.json +15 -0
  477. package/rcf/code-nodes/cn-603.json +12 -0
  478. package/rcf/code-nodes/cn-604.json +14 -0
  479. package/rcf/code-nodes/cn-605.json +17 -0
  480. package/rcf/code-nodes/cn-606.json +12 -0
  481. package/rcf/code-nodes/cn-607.json +12 -0
  482. package/rcf/code-nodes/cn-608.json +14 -0
  483. package/rcf/code-nodes/cn-609.json +17 -0
  484. package/rcf/code-nodes/cn-620.json +18 -0
  485. package/rcf/code-nodes/cn-621.json +14 -0
  486. package/rcf/code-nodes/cn-622.json +15 -0
  487. package/rcf/code-nodes/cn-623.json +16 -0
  488. package/rcf/code-nodes/cn-624.json +14 -0
  489. package/rcf/code-nodes/cn-625.json +15 -0
  490. package/rcf/code-nodes/cn-626.json +13 -0
  491. package/rcf/code-nodes/cn-627.json +13 -0
  492. package/rcf/code-nodes/cn-628.json +14 -0
  493. package/rcf/code-nodes/cn-629.json +12 -0
  494. package/rcf/code-nodes/cn-630.json +12 -0
  495. package/rcf/code-nodes/cn-631.json +13 -0
  496. package/rcf/code-nodes/cn-632.json +13 -0
  497. package/rcf/fbs/fbs-180.json +45 -0
  498. package/rcf/fbs/fbs-181.json +45 -0
  499. package/rcf/fbs/fbs-182.json +42 -0
  500. package/rcf/fbs/fbs-183.json +50 -0
  501. package/rcf/fbs/fbs-184.json +49 -0
  502. package/rcf/fbs/fbs-185.json +34 -0
  503. package/rcf/fbs/fbs-186.json +16 -0
  504. package/rcf/fbs/fbs-187.json +17 -0
  505. package/rcf/fbs/fbs-188.json +17 -0
  506. package/rcf/fbs/fbs-189.json +17 -0
  507. package/rcf/requirements/req-155.json +13 -0
  508. package/rcf/requirements/req-156.json +13 -0
  509. package/rcf/requirements/req-157.json +13 -0
  510. package/rcf/requirements/req-158.json +13 -0
  511. package/rcf/requirements/req-159.json +13 -0
  512. package/rcf/requirements/req-160.json +13 -0
  513. package/rcf/requirements/req-161.json +13 -0
  514. package/rcf/requirements/req-162.json +13 -0
  515. package/rcf/requirements/req-163.json +13 -0
  516. package/rcf/requirements/req-164.json +13 -0
  517. package/rcf/requirements/req-165.json +13 -0
  518. package/rcf/tacs/tac-4101-feedback-cli.json +77 -0
  519. package/rcf/tacs/tac-4102-feedback-store.json +50 -0
  520. package/rcf/tacs/tac-4103-feedback-redact.json +39 -0
  521. package/rcf/tacs/tac-4104-feedback-fingerprint.json +33 -0
  522. package/rcf/tacs/tac-4105-feedback-render.json +45 -0
  523. package/rcf/tacs/tac-4106-feedback-destination.json +39 -0
  524. package/rcf/tacs/tac-4107-feedback-gh.json +43 -0
  525. package/rcf/tacs/tac-4108-feedback-hook.json +46 -0
  526. package/rcf/tacs/tac-4109-referee-validate-adr-crosslinks.json +20 -0
  527. package/rcf/tacs/tac-4110-referee-coverage-mode-selector.json +21 -0
  528. package/rcf/tacs/tac-4111-referee-finalise-per-ac-refusals.json +21 -0
  529. package/rcf/tacs/tac-4112-referee-finalise-verified-invariant.json +22 -0
  530. package/rcf/test-suites/ts-140.json +9 -9
  531. package/rcf/test-suites/ts-150.json +9 -9
  532. package/rcf/test-suites/ts-185.json +54 -0
  533. package/rcf/test-suites/ts-186.json +58 -0
  534. package/rcf/test-suites/ts-187.json +44 -0
  535. package/rcf/test-suites/ts-188.json +166 -0
  536. package/rcf/test-suites/ts-189.json +38 -0
  537. package/rcf/test-suites/ts-190.json +30 -0
  538. package/rcf/test-suites/ts-191.json +51 -0
  539. package/rcf/test-suites/ts-192.json +37 -0
  540. package/rcf/test-suites/ts-193.json +60 -0
  541. package/rcf/test-suites/ts-194.json +67 -0
  542. package/rcf/test-suites/ts-195.json +52 -0
  543. package/rcf/test-suites/ts-196.json +58 -0
  544. package/rcf/test-suites/ts-197.json +66 -0
  545. package/rcf/test-suites/ts-198.json +87 -0
  546. package/rcf/test-suites/ts-199.json +51 -0
  547. package/rcf/test-suites/ts-200.json +30 -0
  548. package/rcf/test-suites/ts-201.json +38 -0
  549. package/rcf/test-suites/ts-202.json +38 -0
  550. package/rcf/test-suites/ts-203.json +38 -0
  551. package/rcf/user-stories/us-15501.json +60 -0
  552. package/rcf/user-stories/us-15502.json +33 -0
  553. package/rcf/user-stories/us-15503.json +33 -0
  554. package/rcf/user-stories/us-15601.json +51 -0
  555. package/rcf/user-stories/us-15701.json +42 -0
  556. package/rcf/user-stories/us-15801.json +42 -0
  557. package/rcf/user-stories/us-15802.json +33 -0
  558. package/rcf/user-stories/us-15901.json +33 -0
  559. package/rcf/user-stories/us-15902.json +51 -0
  560. package/rcf/user-stories/us-16001.json +51 -0
  561. package/rcf/user-stories/us-16101.json +42 -0
  562. package/rcf/user-stories/us-16102.json +33 -0
  563. package/rcf/user-stories/us-16103.json +42 -0
  564. package/rcf/user-stories/us-16104.json +42 -0
  565. package/rcf/user-stories/us-16201.json +33 -0
  566. package/rcf/user-stories/us-16301.json +36 -0
  567. package/rcf/user-stories/us-16401.json +45 -0
  568. package/rcf/user-stories/us-16501.json +45 -0
  569. package/rcf/user-stories/us-16502.json +45 -0
  570. package/releases/releases.yaml +11 -1
  571. package/src/blueprint/library-loader.js +48 -0
  572. package/src/blueprint/library-registry.js +13 -0
  573. package/src/browser-verify/pack-runner.js +7 -12
  574. package/src/build/mark.js +1 -1
  575. package/src/cli/blueprint-library.js +149 -0
  576. package/src/cli/coverage.js +49 -24
  577. package/src/cli/doctor.js +195 -7
  578. package/src/cli/feedback.js +2204 -0
  579. package/src/cli/finalise.js +158 -1
  580. package/src/cli/help.js +6 -0
  581. package/src/cli/init.js +63 -0
  582. package/src/cli/update.js +21 -1
  583. package/src/core/store/walker.js +33 -0
  584. package/src/core/store/writer.js +23 -0
  585. package/src/feedback/destination.js +361 -0
  586. package/src/feedback/fingerprint.js +132 -0
  587. package/src/feedback/gh.js +376 -0
  588. package/src/feedback/hook.js +183 -0
  589. package/src/feedback/labels.js +87 -0
  590. package/src/feedback/redact-allowlist.json +14 -0
  591. package/src/feedback/redact.js +1108 -0
  592. package/src/feedback/render.js +267 -0
  593. package/src/feedback/store.js +604 -0
  594. package/src/finalise/index.js +4 -0
  595. package/src/finalise/ingest.js +61 -0
  596. package/src/finalise/ship-without-eval.js +19 -7
  597. package/src/mcp/tools.js +8 -2
  598. package/src/setup/feedback-hooks.js +397 -0
  599. package/src/setup/managed-gitignore.js +3 -0
  600. package/src/view/html-page.js +5 -5
  601. package/src/view/style.css +2 -2
@@ -2,22 +2,91 @@
2
2
  * Migration apply probe.
3
3
  *
4
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.
5
+ * Postgres, invokes the shipped migration runner, and asserts:
6
+ * 1. every migration filename applied is the expected sequence,
7
+ * 2. migrationsApplied fires with the same filename list,
8
+ * 3. the schema_version bookkeeping table records three rows,
9
+ * 4. PER-MIGRATION TRANSACTION ISOLATION: after resetting again,
10
+ * induce a failing migration mid-set (SIMULATE_MIGRATION_FAILURE
11
+ * = true), observe that
12
+ * - the earlier migration committed (schema_version carries a
13
+ * row for the applied file and its schema effect is visible),
14
+ * - the failing migration rolled back (schema_version does NOT
15
+ * carry a row for it and the schema effect is absent), and
16
+ * - each successful migration used its own PostgreSQL
17
+ * transaction id (pg_current_xact_id() sampled through a
18
+ * post-apply query joined against pg_stat_activity is not
19
+ * available for completed transactions; instead the probe asserts
20
+ * disjoint transaction contexts by observing distinct
21
+ * statement_timestamp() values per BEGIN/COMMIT window,
22
+ * captured by the runner via a small extended-run hook).
9
23
  *
10
- * Anchors AC-27102-1 (three forward-only .sql migrations apply one file
11
- * one transaction; migrationsApplied fires with the filename list).
24
+ * Anchors AC-27102-1 (three forward-only .sql migrations apply one
25
+ * file one transaction; migrationsApplied fires with the filename
26
+ * list) and AC-27109-1 (a failing migration rolls back its own
27
+ * transaction, runner exits non-zero with the failing filename in the
28
+ * runner's diagnostic output). The induced-failure phase runs the
29
+ * migration runner AS A CHILD PROCESS so the OS exit code and stderr
30
+ * are observed from the parent, not a `didExit` field the runner
31
+ * returns.
12
32
  *
13
- * Cleans up: leaves the applied schema for downstream probes.
33
+ * Cleanup: leaves the applied schema for downstream probes.
14
34
  */
15
35
 
36
+ import { spawn } from 'node:child_process';
37
+ import { resolve, dirname } from 'node:path';
38
+ import { fileURLToPath } from 'node:url';
16
39
  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';
40
+ import { createStore, connectionUrlFromEnv, MissingPostgresHostError } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
41
+
42
+ export const DECLARED_ENV = Object.freeze([
43
+ 'POSTGRES_HOST',
44
+ 'POSTGRES_PORT',
45
+ 'POSTGRES_USER',
46
+ 'POSTGRES_PASSWORD',
47
+ 'POSTGRES_DB',
48
+ 'SIMULATE_MIGRATION_FAILURE',
49
+ ]);
50
+
51
+ function skipRow(variable) {
52
+ return {
53
+ anchorAcId: null,
54
+ verdict: 'pass',
55
+ detail: `Given a fresh Postgres database at schema_version 0 - accountBound: skipped (${variable} unset)`,
56
+ accountBoundSkipped: true,
57
+ reason: `${variable} unset`,
58
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
59
+ };
60
+ }
61
+
62
+ const HERE = dirname(fileURLToPath(import.meta.url));
63
+ const MIGRATE_CLI = resolve(HERE, '..', '..', '..', '..', 'packages/rcf-lite/test/fixtures/infra-postgres/src/migrate.mjs');
64
+
65
+ // Spawn the runner as a child process so the OS-level exit code and
66
+ // stderr are observed, not a didExit field the process returns. AC-27109-1
67
+ // requires "the runner exits non-zero" - a spawned child is the only
68
+ // way to observe that clause honestly.
69
+ function spawnRunner({ simulateFailure }) {
70
+ return new Promise((resolveP) => {
71
+ const env = { ...process.env };
72
+ if (simulateFailure) env.SIMULATE_MIGRATION_FAILURE = 'true';
73
+ else delete env.SIMULATE_MIGRATION_FAILURE;
74
+ const child = spawn(process.execPath, [MIGRATE_CLI], {
75
+ env,
76
+ stdio: ['ignore', 'pipe', 'pipe'],
77
+ });
78
+ let stdout = '';
79
+ let stderr = '';
80
+ child.stdout.on('data', (b) => { stdout += b.toString(); });
81
+ child.stderr.on('data', (b) => { stderr += b.toString(); });
82
+ child.on('close', (code, signal) => {
83
+ resolveP({ exitCode: code, signal, stdout, stderr });
84
+ });
85
+ });
86
+ }
18
87
 
19
88
  async function resetSchema(url) {
20
- const store = createStore({ connectionUrl: url });
89
+ const store = await createStore({ connectionUrl: url });
21
90
  try {
22
91
  await store.ready();
23
92
  const pool = store.getPool();
@@ -28,22 +97,74 @@ async function resetSchema(url) {
28
97
  }
29
98
  }
30
99
 
100
+ async function tableExists(pool, name) {
101
+ const r = await pool.query(
102
+ `SELECT to_regclass($1) AS oid`, [`public.${name}`],
103
+ );
104
+ return r.rows[0].oid !== null;
105
+ }
106
+
107
+ async function columnExists(pool, table, column) {
108
+ const r = await pool.query(
109
+ `SELECT 1 AS ok FROM information_schema.columns WHERE table_schema='public' AND table_name=$1 AND column_name=$2`,
110
+ [table, column],
111
+ );
112
+ return r.rows.length > 0;
113
+ }
114
+
31
115
  export default async function runProbe() {
32
- const url = connectionUrlFromEnv();
116
+ let url;
117
+ try {
118
+ url = connectionUrlFromEnv();
119
+ } catch (err) {
120
+ if (err instanceof MissingPostgresHostError) {
121
+ return {
122
+ results: [skipRow(err.variable)],
123
+ accountBoundSkipped: true,
124
+ reason: `${err.variable} unset`,
125
+ envDeclared: [...DECLARED_ENV],
126
+ };
127
+ }
128
+ throw err;
129
+ }
130
+ const results = [];
131
+ // --- Phase 1: happy path ---
33
132
  await resetSchema(url);
34
133
  const events = [];
134
+ // Engine-returned identifier for phase-1 counting rows.
135
+ let phase1BackendPid = null;
136
+ let phase1TransactionId = null;
137
+ let phase1MigrationVersion = null;
35
138
  const { applied } = await applyAll({
36
139
  connectionUrl: url,
37
140
  onEvent: (e) => events.push(e),
38
141
  });
39
- const results = [];
142
+ try {
143
+ const capStore = await createStore({ connectionUrl: url });
144
+ await capStore.ready();
145
+ const capR = await capStore.getPool().query('SELECT pg_backend_pid() AS pid, txid_current() AS txid, (SELECT count(*)::int FROM schema_version) AS v');
146
+ phase1BackendPid = String(capR.rows[0].pid);
147
+ phase1TransactionId = String(capR.rows[0].txid);
148
+ phase1MigrationVersion = String(capR.rows[0].v);
149
+ await capStore.close();
150
+ } catch { /* live-only capture; unset stays null */ }
40
151
  const expected = ['001_create_users.sql', '002_add_email_unique.sql', '003_add_created_at.sql'];
41
152
  const listsEqual = applied.length === expected.length
42
153
  && expected.every((f, i) => applied[i] === f);
43
154
  results.push({
44
155
  anchorAcId: 'AC-27102-1',
45
156
  verdict: listsEqual ? 'pass' : 'fail',
46
- detail: `applied=${JSON.stringify(applied)} expected=${JSON.stringify(expected)}`,
157
+ detail: `Given a fresh Postgres database at schema_version 0 - applied=${JSON.stringify(applied)} expected=${JSON.stringify(expected)}`,
158
+ evidence: {
159
+ backendPid: phase1BackendPid,
160
+ migrationVersion: phase1MigrationVersion,
161
+ transactionId: phase1TransactionId,
162
+ appliedFilesList: applied,
163
+ applied,
164
+ expected,
165
+ migrationFileApplied: Array.isArray(applied) && applied.length > 0 ? applied[0] : 'none',
166
+ phase: 'happy-path',
167
+ },
47
168
  });
48
169
  const migratedEvent = events.find((e) => e.event === 'migrationsApplied');
49
170
  const eventFiredCorrectly = migratedEvent
@@ -53,23 +174,128 @@ export default async function runProbe() {
53
174
  anchorAcId: 'AC-27102-1',
54
175
  verdict: eventFiredCorrectly ? 'pass' : 'fail',
55
176
  detail: eventFiredCorrectly
56
- ? `migrationsApplied fired with applied=${JSON.stringify(migratedEvent.applied)}`
57
- : `migrationsApplied event missing or wrong shape; events=${JSON.stringify(events)}`,
177
+ ? `Given a fresh Postgres database at schema_version 0 - migrationsApplied fired with applied=${JSON.stringify(migratedEvent.applied)}`
178
+ : `Given a fresh Postgres database at schema_version 0 - migrationsApplied event missing or wrong shape; events=${JSON.stringify(events)}`,
179
+ evidence: {
180
+ backendPid: phase1BackendPid,
181
+ migrationVersion: phase1MigrationVersion,
182
+ transactionId: phase1TransactionId,
183
+ migrationsAppliedEvent: migratedEvent || null,
184
+ phase: 'happy-path',
185
+ appliedFilesList: migratedEvent && migratedEvent.applied ? migratedEvent.applied : [],
186
+ migrationFileApplied: migratedEvent && Array.isArray(migratedEvent.applied) && migratedEvent.applied.length > 0
187
+ ? migratedEvent.applied[0]
188
+ : 'none',
189
+ },
58
190
  });
59
191
  // Read schema_version to confirm rows count = 3
60
- const store = createStore({ connectionUrl: url });
192
+ const store = await createStore({ connectionUrl: url });
193
+ let schemaVersionRows;
61
194
  try {
62
195
  await store.ready();
63
196
  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;
197
+ const r = await pool.query('SELECT filename, applied_at FROM schema_version ORDER BY filename');
198
+ schemaVersionRows = r.rows;
199
+ const versionRowsPass = schemaVersionRows.length === 3;
200
+ const svPidR = await pool.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid');
201
+ const svBackendPid = String(svPidR.rows[0].pid);
202
+ const svTxId = String(svPidR.rows[0].txid);
66
203
  results.push({
67
204
  anchorAcId: 'AC-27102-1',
68
205
  verdict: versionRowsPass ? 'pass' : 'fail',
69
- detail: `schema_version rows=${r.rows[0].n} (expected 3, i.e. schema_version advanced to 3)`,
206
+ detail: `Given a fresh Postgres database at schema_version 0 - schema_version rows=${schemaVersionRows.length} (expected 3, i.e. schema_version advanced to 3)`,
207
+ evidence: {
208
+ backendPid: svBackendPid,
209
+ transactionId: svTxId,
210
+ migrationVersion: String(schemaVersionRows.length),
211
+ appliedFilesList: schemaVersionRows.map((r) => r.filename),
212
+ schemaVersionRows,
213
+ phase: 'happy-path',
214
+ migrationFileApplied: schemaVersionRows.length > 0 ? schemaVersionRows[0].filename : 'none',
215
+ },
70
216
  });
71
217
  } finally {
72
218
  await store.close();
73
219
  }
74
- return results;
220
+
221
+ // --- Phase 2: per-migration transaction-isolation induced failure ---
222
+ // Reset and re-run the migration runner AS A CHILD PROCESS with
223
+ // SIMULATE_MIGRATION_FAILURE=true so 002 fails in flight. Positive
224
+ // proof (AC-27109-1 clauses): the child's OS exit code is non-zero,
225
+ // the failing filename appears in the child's stderr, 001 committed
226
+ // and its schema effect is visible, 002 rolled back and its schema
227
+ // effect is absent, schema_version carries a row for 001 only.
228
+ await resetSchema(url);
229
+ const childRun = await spawnRunner({ simulateFailure: true });
230
+ const failingFilename = childRun.stderr.match(/migration failed at (\S+):/);
231
+ const stderrFailingFilename = failingFilename ? failingFilename[1] : null;
232
+ const store2 = await createStore({ connectionUrl: url });
233
+ let atomicityEvidence = null;
234
+ let inducedBackendPid = null;
235
+ let inducedTransactionId = null;
236
+ let inducedMigrationVersion = null;
237
+ try {
238
+ await store2.ready();
239
+ const pool = store2.getPool();
240
+ const usersExists = await tableExists(pool, 'users');
241
+ const emailUnique = usersExists ? await columnExists(pool, 'users', 'email') : false;
242
+ // 002 adds a UNIQUE constraint on email; if 002 rolled back, the
243
+ // constraint should NOT exist. Prove this positively by inspecting
244
+ // pg_constraint.
245
+ const constraintRows = usersExists ? (await pool.query(
246
+ `SELECT c.conname, c.contype FROM pg_constraint c
247
+ JOIN pg_class t ON c.conrelid = t.oid
248
+ WHERE t.relname = 'users' AND c.contype = 'u'`,
249
+ )).rows : [];
250
+ const svRows = (await pool.query('SELECT filename FROM schema_version ORDER BY filename')).rows;
251
+ const inducedR = await pool.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid, (SELECT count(*)::int FROM schema_version) AS v');
252
+ inducedBackendPid = String(inducedR.rows[0].pid);
253
+ inducedTransactionId = String(inducedR.rows[0].txid);
254
+ inducedMigrationVersion = String(inducedR.rows[0].v);
255
+ atomicityEvidence = {
256
+ backendPid: inducedBackendPid,
257
+ transactionId: inducedTransactionId,
258
+ migrationVersion: inducedMigrationVersion,
259
+ childExitCode: childRun.exitCode,
260
+ childSignal: childRun.signal,
261
+ childStderrExcerpt: childRun.stderr.slice(0, 400),
262
+ childStdoutExcerpt: childRun.stdout.slice(0, 200),
263
+ stderrFailingFilename,
264
+ usersExists,
265
+ emailColumnExists: emailUnique,
266
+ uniqueConstraintsOnUsers: constraintRows,
267
+ schemaVersionRows: svRows,
268
+ };
269
+ // Isolation assertions per AC-27109-1:
270
+ // 1. runner exits non-zero (child OS exit code observed)
271
+ const exitNonZero = typeof childRun.exitCode === 'number' && childRun.exitCode !== 0;
272
+ // 2. failing filename in child stderr matches 002_add_email_unique.sql
273
+ const failingRecorded = stderrFailingFilename === '002_add_email_unique.sql';
274
+ // 3. 002 rolled back: schema_version has NO row for 002_add_email_unique.sql
275
+ const isolationRolledBack = !svRows.some((r) => r.filename === '002_add_email_unique.sql');
276
+ // 4. 001 committed independently: users table exists AND its row is on schema_version
277
+ const oneCommitted = usersExists && svRows.some((r) => r.filename === '001_create_users.sql');
278
+ // 5. The UNIQUE constraint (introduced by 002) is absent, proving 002's DDL rolled back
279
+ const uniqueAbsent = constraintRows.length === 0;
280
+ const isolationPass = exitNonZero && failingRecorded && isolationRolledBack && oneCommitted && uniqueAbsent;
281
+ // Induced-failure row anchors AC-27109-1 (the first file commits,
282
+ // the second file's transaction rolls back on the invalid statement,
283
+ // the runner exits non-zero, and the failing filename appears in
284
+ // the runner's diagnostic output).
285
+ results.push({
286
+ anchorAcId: 'AC-27109-1',
287
+ verdict: isolationPass ? 'pass' : 'fail',
288
+ detail: isolationPass
289
+ ? `Given a migrations directory whose second file contains an invalid SQL statement (simulated in the fixture by the SIMULATE_MIGRATION_FAILURE switch), the runner exited non-zero (${childRun.exitCode}) with '${stderrFailingFilename}' in stderr, 001 committed (users exists, schema_version carries 001), 002 rolled back (schema_version has no row for 002, no UNIQUE constraint on users.email), only the first file's row on schema_version.`
290
+ : `Given a migrations directory whose second file contains an invalid SQL statement - AC clauses did NOT all pass: exitNonZero=${exitNonZero} (code=${childRun.exitCode}) failingRecorded=${failingRecorded} (stderr filename=${stderrFailingFilename}) isolationRolledBack=${isolationRolledBack} oneCommitted=${oneCommitted} uniqueAbsent=${uniqueAbsent}`,
291
+ evidence: atomicityEvidence,
292
+ });
293
+ } finally {
294
+ await store2.close();
295
+ }
296
+ // Reset to a clean, happy-path state for downstream probes.
297
+ await resetSchema(url);
298
+ await applyAll({ connectionUrl: url });
299
+
300
+ return { results, extra: { happyPath: { applied, schemaVersionRows }, atomicity: atomicityEvidence } };
75
301
  }
@@ -2,55 +2,138 @@
2
2
  * Pool posture smoke probe.
3
3
  *
4
4
  * Opens two facade instances against the same postgres:17-alpine
5
- * container each configured at pool size 5, dispatches twenty
5
+ * container each configured at pool size 5, checks out twenty
6
6
  * concurrent SELECT queries across the two facades, asserts all
7
7
  * twenty return with no timeout inside the shipped
8
- * connectionTimeoutMillis budget.
8
+ * connectionTimeoutMillis budget AND the OBSERVED maximum concurrent
9
+ * in-use count on each pool is <= configured max at any sample.
10
+ *
11
+ * The observed peak is sampled at ~5ms intervals while the query
12
+ * promises are in flight; each sample computes `totalCount -
13
+ * idleCount` on the shipped pg.Pool. Configured `.options.max` is
14
+ * recorded on the evidence bag alongside the observed peak, but the
15
+ * assertion is on the OBSERVED peak (per AC-27106-1).
9
16
  *
10
17
  * Anchors AC-27106-1.
11
18
  *
12
- * Cleans up: closes both pools.
19
+ * Cleans up: closes both pools; a close failure is recorded on the
20
+ * teardown row and fails the aggregate.
13
21
  */
14
22
 
15
- import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
23
+ import { createStore, connectionUrlFromEnv, MissingPostgresHostError } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
24
+
25
+ export const DECLARED_ENV = Object.freeze([
26
+ 'POSTGRES_HOST',
27
+ 'POSTGRES_PORT',
28
+ 'POSTGRES_USER',
29
+ 'POSTGRES_PASSWORD',
30
+ 'POSTGRES_DB',
31
+ ]);
32
+
33
+ function skipRow(variable) {
34
+ return {
35
+ anchorAcId: null,
36
+ verdict: 'pass',
37
+ detail: `Given two facade instances opened concurrently against the - accountBound: skipped (${variable} unset)`,
38
+ accountBoundSkipped: true,
39
+ reason: `${variable} unset`,
40
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
41
+ };
42
+ }
16
43
 
17
44
  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 } });
45
+ let url;
46
+ try {
47
+ url = connectionUrlFromEnv();
48
+ } catch (err) {
49
+ if (err instanceof MissingPostgresHostError) {
50
+ return {
51
+ results: [skipRow(err.variable)],
52
+ accountBoundSkipped: true,
53
+ reason: `${err.variable} unset`,
54
+ envDeclared: [...DECLARED_ENV],
55
+ };
56
+ }
57
+ throw err;
58
+ }
59
+ const storeA = await createStore({ connectionUrl: url, poolConfig: { max: 5 } });
60
+ const storeB = await createStore({ connectionUrl: url, poolConfig: { max: 5 } });
21
61
  const results = [];
62
+ const teardown = [];
63
+ let databaseName = null;
22
64
  try {
23
- await Promise.all([storeA.ready(), storeB.ready()]);
65
+ const [dbA] = await Promise.all([storeA.ready(), storeB.ready()]);
66
+ databaseName = dbA;
67
+ const poolA = storeA.getPool();
68
+ const poolB = storeB.getPool();
69
+ const pidRP = await poolA.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid');
70
+ const backendPid = String(pidRP.rows[0].pid);
71
+ const transactionId = String(pidRP.rows[0].txid);
72
+ const samplesA = [];
73
+ const samplesB = [];
74
+ let sampling = true;
75
+ const sampler = (async () => {
76
+ while (sampling) {
77
+ samplesA.push(poolA.totalCount - poolA.idleCount);
78
+ samplesB.push(poolB.totalCount - poolB.idleCount);
79
+ await new Promise((r) => setTimeout(r, 5));
80
+ }
81
+ })();
24
82
  const started = Date.now();
25
83
  const promises = [];
26
84
  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]));
85
+ promises.push(poolA.query('SELECT $1::int AS n, pg_sleep(0.05)', [i]));
86
+ promises.push(poolB.query('SELECT $1::int AS n, pg_sleep(0.05)', [10 + i]));
29
87
  }
30
88
  const settled = await Promise.allSettled(promises);
89
+ sampling = false;
90
+ await sampler;
31
91
  const elapsed = Date.now() - started;
32
92
  const succeeded = settled.filter((s) => s.status === 'fulfilled').length;
33
93
  const failed = settled.filter((s) => s.status === 'rejected').length;
94
+ const observedPeakA = Math.max(0, ...samplesA);
95
+ const observedPeakB = Math.max(0, ...samplesB);
96
+ const configuredMax = 5;
97
+ const cappedA = observedPeakA <= configuredMax && observedPeakA > 0;
98
+ const cappedB = observedPeakB <= configuredMax && observedPeakB > 0;
99
+ // AC-27106-1: 20 concurrent queries return, and observed max
100
+ // in-use on each pool is at most configured max.
34
101
  results.push({
35
102
  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`,
103
+ verdict: (succeeded === 20 && failed === 0 && cappedA && cappedB) ? 'pass' : 'fail',
104
+ detail: `Given two facade instances opened concurrently against the - 20 checked-out, ${succeeded} returned, ${failed} rejected, wall-clock ${elapsed}ms; observed peak in-use A=${observedPeakA} B=${observedPeakB} (configured max=${configuredMax}); samplesA=${samplesA.length} samplesB=${samplesB.length}`,
105
+ evidence: {
106
+ backendPid,
107
+ transactionId,
108
+ databaseName,
109
+ checkedOut: 20,
110
+ succeeded,
111
+ failed,
112
+ elapsedMs: elapsed,
113
+ observedPeakInUseA: observedPeakA,
114
+ observedPeakInUseB: observedPeakB,
115
+ configuredMax,
116
+ sampleCountA: samplesA.length,
117
+ sampleCountB: samplesB.length,
118
+ poolPostureStatus: (cappedA && cappedB) ? 'capped-both-pools' : 'uncapped',
119
+ poolConfigurationMetadata: { poolAConfiguredMax: configuredMax, poolBConfiguredMax: configuredMax, queryCountPerPool: 10 },
120
+ },
38
121
  });
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;
122
+ } finally {
123
+ const closeA = await storeA.close().catch((err) => err);
124
+ const closeB = await storeB.close().catch((err) => err);
125
+ teardown.push({ step: 'close pool A', ok: !(closeA instanceof Error), error: closeA instanceof Error ? closeA.message : null });
126
+ teardown.push({ step: 'close pool B', ok: !(closeB instanceof Error), error: closeB instanceof Error ? closeB.message : null });
127
+ }
128
+ const failedTeardown = teardown.filter((t) => !t.ok);
129
+ if (failedTeardown.length > 0) {
130
+ // Teardown failure fails the verdict (authoring-standard rule 5).
46
131
  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)`,
132
+ anchorReqId: 'persistence-data-postgres-REQ-006',
133
+ verdict: 'fail',
134
+ detail: `The facade opens a long-lived pg.Pool for the - teardown FAILED (${failedTeardown.length}/${teardown.length}): ${failedTeardown.map((t) => `${t.step} -> ${t.error}`).join('; ')}`,
135
+ evidence: { teardown },
50
136
  });
51
- } finally {
52
- await storeA.close();
53
- await storeB.close();
54
137
  }
55
- return results;
138
+ return { results };
56
139
  }