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
@@ -1,28 +1,58 @@
1
1
  /**
2
2
  * Recovery restore round-trip probe.
3
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.
4
+ * Drives the shipped fixture recovery runner (src/recovery.mjs
5
+ * exportDatabase, TAC-2804) to produce the dump artefact and asserts
6
+ * the runner emits `backupExported` per AC-27105-1. Because pg_dump is
7
+ * not on the host PATH in every CI runner, the probe supplies the
8
+ * runPgDump override on `exportDatabase` that shells out to
9
+ * `docker exec <sourceContainer> pg_dump ...`. The shipped runner is
10
+ * still the code path under test; only the pg_dump invocation is
11
+ * container-hosted.
12
+ *
13
+ * Brings up a second postgres:17-alpine container on a spare port,
14
+ * pipes the artefact through psql into that container (via the same
15
+ * docker exec pattern), and asserts row-count and md5 checksum
16
+ * equality between source and restored databases.
12
17
  *
13
18
  * Anchors AC-27105-1 (recovery exported, restore round-trips the row
14
- * set).
19
+ * set, backupExported event fires).
15
20
  *
16
- * Cleans up: TRUNCATE users on source; stops the restore container and
17
- * removes its volume; deletes the artefact file.
21
+ * Cleanup: TRUNCATE users on source; stops the restore container and
22
+ * removes its volume; deletes the artefact directory. Every teardown
23
+ * step records its exit status in the report's `teardown` bag; a
24
+ * teardown failure FAILS the verdict per authoring-standard rule 5.
18
25
  */
19
26
 
20
27
  import { spawn, execFile } from 'node:child_process';
21
28
  import { promisify } from 'node:util';
22
- import { mkdir, writeFile, unlink, rm } from 'node:fs/promises';
29
+ import { mkdir, writeFile, rm, stat } from 'node:fs/promises';
23
30
  import { dirname, relative, resolve } from 'node:path';
24
31
  import { fileURLToPath } from 'node:url';
25
- import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
32
+ import { createStore, connectionUrlFromEnv, MissingPostgresHostError } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
33
+ import { exportDatabase } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/recovery.mjs';
34
+
35
+ export const DECLARED_ENV = Object.freeze([
36
+ 'POSTGRES_HOST',
37
+ 'POSTGRES_PORT',
38
+ 'POSTGRES_USER',
39
+ 'POSTGRES_PASSWORD',
40
+ 'POSTGRES_DB',
41
+ 'POSTGRES_SOURCE_CONTAINER',
42
+ 'POSTGRES_RESTORE_CONTAINER',
43
+ 'POSTGRES_RESTORE_PORT',
44
+ ]);
45
+
46
+ function skipRow(variable) {
47
+ return {
48
+ anchorAcId: null,
49
+ verdict: 'pass',
50
+ detail: `Given a live Postgres containing a small fixture rowset - accountBound: skipped (${variable} unset)`,
51
+ accountBoundSkipped: true,
52
+ reason: `${variable} unset`,
53
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
54
+ };
55
+ }
26
56
 
27
57
  const execFileAsync = promisify(execFile);
28
58
  const HERE = dirname(fileURLToPath(import.meta.url));
@@ -30,9 +60,15 @@ const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
30
60
  const ARTEFACT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/persistence-data-postgres/recovery');
31
61
  const ARTEFACT = resolve(ARTEFACT_DIR, 'backup.sql');
32
62
  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';
63
+ // Source container defaults to the fixture's docker-compose service
64
+ // name; a CI runner (or a positive-evidence run) may override via
65
+ // POSTGRES_SOURCE_CONTAINER. Restore container name and port are
66
+ // similarly overridable so parallel runs and non-default docker
67
+ // networks can pick free ports; both env vars are declared on the
68
+ // fixture's Declared env vars table.
69
+ const SOURCE_CONTAINER = process.env.POSTGRES_SOURCE_CONTAINER || 'infra-postgres-postgres-1';
70
+ const RESTORE_CONTAINER = process.env.POSTGRES_RESTORE_CONTAINER || 'infra-postgres-restore';
71
+ const RESTORE_PORT = process.env.POSTGRES_RESTORE_PORT || '55432';
36
72
 
37
73
  async function dockerExec(container, cmd, opts = {}) {
38
74
  return execFileAsync('docker', ['exec', container, ...cmd], { maxBuffer: 64 * 1024 * 1024, ...opts });
@@ -43,7 +79,7 @@ async function dockerExec(container, cmd, opts = {}) {
43
79
  * accept stdin buffers, so use spawn.
44
80
  */
45
81
  async function dockerExecStdin(container, cmd, stdinBuffer) {
46
- return new Promise((resolve2, reject) => {
82
+ return new Promise((resolveP, reject) => {
47
83
  const child = spawn('docker', ['exec', '-i', container, ...cmd]);
48
84
  const chunks = [];
49
85
  const errChunks = [];
@@ -51,7 +87,7 @@ async function dockerExecStdin(container, cmd, stdinBuffer) {
51
87
  child.stderr.on('data', (d) => errChunks.push(d));
52
88
  child.on('error', reject);
53
89
  child.on('exit', (code) => {
54
- if (code === 0) return resolve2({ stdout: Buffer.concat(chunks).toString('utf8'), stderr: Buffer.concat(errChunks).toString('utf8') });
90
+ if (code === 0) return resolveP({ stdout: Buffer.concat(chunks).toString('utf8'), stderr: Buffer.concat(errChunks).toString('utf8') });
55
91
  reject(new Error(`docker exec exit ${code}: ${Buffer.concat(errChunks).toString('utf8')}`));
56
92
  });
57
93
  child.stdin.write(stdinBuffer);
@@ -71,14 +107,43 @@ async function waitHealthy(container, maxSeconds = 30) {
71
107
  throw new Error(`container ${container} did not become healthy within ${maxSeconds}s`);
72
108
  }
73
109
 
110
+ /**
111
+ * Positively assert `container` is absent by asking docker to inspect
112
+ * it. Absent = docker exits non-zero WITH `No such object` on stderr.
113
+ * Any other error (daemon unreachable, permission denied) fails the
114
+ * assertion; the caller can then FAIL the row rather than treat it as
115
+ * "no problem here".
116
+ */
117
+ async function assertContainerAbsent(container) {
118
+ try {
119
+ await execFileAsync('docker', ['inspect', container]);
120
+ throw new Error(`container ${container} still exists`);
121
+ } catch (err) {
122
+ if (err && err.stderr && /[Nn]o such object|[Ee]rror: [Nn]o such/i.test(err.stderr)) return { absent: true };
123
+ if (err && err.message && err.message.includes('still exists')) throw err;
124
+ // Unrecognized inspect failure - do NOT treat as absent.
125
+ throw new Error(`docker inspect on ${container} produced an unrecognized error: ${err && (err.stderr || err.message) || 'unknown'}`);
126
+ }
127
+ }
128
+
74
129
  async function bringUpRestore() {
75
- // Remove any prior instance
76
- await execFileAsync('docker', ['rm', '-f', RESTORE_CONTAINER]).catch(() => {});
130
+ // Pre-run cleanup: remove any prior instance, THEN positively assert
131
+ // the container is gone. If the pre-run rm fails for a reason other
132
+ // than "container did not exist", let the run fail loudly rather
133
+ // than proceed to a `docker run` that would collide.
134
+ try {
135
+ await execFileAsync('docker', ['rm', '-f', RESTORE_CONTAINER]);
136
+ } catch (err) {
137
+ if (!(err && err.stderr && /[Nn]o such container|[Ee]rror: [Nn]o such/i.test(err.stderr))) {
138
+ throw new Error(`pre-run rm of ${RESTORE_CONTAINER} failed and did not name a No-such-container reason: ${err && (err.stderr || err.message) || 'unknown'}`);
139
+ }
140
+ }
141
+ await assertContainerAbsent(RESTORE_CONTAINER);
77
142
  await execFileAsync('docker', [
78
143
  'run', '-d',
79
144
  '--name', RESTORE_CONTAINER,
80
145
  '-e', 'POSTGRES_USER=rcf',
81
- '-e', 'POSTGRES_PASSWORD=rcf-dev-only',
146
+ '-e', 'POSTGRES_PASSWORD',
82
147
  '-e', 'POSTGRES_DB=rcf_test',
83
148
  '-p', `${RESTORE_PORT}:5432`,
84
149
  '--health-cmd', 'pg_isready -U rcf -d rcf_test',
@@ -89,20 +154,57 @@ async function bringUpRestore() {
89
154
  await waitHealthy(RESTORE_CONTAINER, 30);
90
155
  }
91
156
 
92
- async function tearDownRestore() {
93
- await execFileAsync('docker', ['rm', '-f', '-v', RESTORE_CONTAINER]).catch(() => {});
157
+ /**
158
+ * Attempt one teardown step; record its outcome on the accumulator.
159
+ * The step is the literal command reported so a reader sees exactly
160
+ * what ran.
161
+ */
162
+ async function recordTeardown(accumulator, label, fn) {
163
+ const entry = { step: label, ok: false, exitCode: null, error: null };
164
+ try {
165
+ const out = await fn();
166
+ entry.ok = true;
167
+ entry.exitCode = 0;
168
+ if (out && typeof out === 'object' && 'exitCode' in out) entry.exitCode = out.exitCode;
169
+ } catch (err) {
170
+ entry.error = err && err.message ? err.message : String(err);
171
+ entry.exitCode = err && typeof err.code === 'number' ? err.code : 1;
172
+ }
173
+ accumulator.push(entry);
174
+ return entry;
94
175
  }
95
176
 
96
177
  export default async function runProbe() {
178
+ let url;
179
+ try {
180
+ url = connectionUrlFromEnv();
181
+ } catch (err) {
182
+ if (err instanceof MissingPostgresHostError) {
183
+ return {
184
+ results: [skipRow(err.variable)],
185
+ accountBoundSkipped: true,
186
+ reason: `${err.variable} unset`,
187
+ envDeclared: [...DECLARED_ENV],
188
+ };
189
+ }
190
+ throw err;
191
+ }
97
192
  const events = [];
98
- const store = createStore({
99
- connectionUrl: connectionUrlFromEnv(),
193
+ const store = await createStore({
194
+ connectionUrl: url,
100
195
  onEvent: (e) => events.push(e),
101
196
  });
102
197
  const results = [];
198
+ const teardown = [];
199
+ let restoreBrought = false;
200
+ let artefactWritten = false;
201
+ let databaseName = null;
103
202
  try {
104
- await store.ready();
203
+ databaseName = await store.ready();
105
204
  const pool = store.getPool();
205
+ const pidRR = await pool.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid');
206
+ const backendPidSrc = String(pidRR.rows[0].pid);
207
+ const transactionIdSrc = String(pidRR.rows[0].txid);
106
208
 
107
209
  // Seed a known rowset on the source
108
210
  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())');
@@ -118,56 +220,167 @@ export default async function runProbe() {
118
220
  await pool.query('INSERT INTO users(name, email) VALUES ($1, $2)', [name, email]);
119
221
  }
120
222
 
121
- // Compute source row-count and checksum (md5 over concatenated name|email ordered by id)
223
+ // Compute source row-count and checksum
122
224
  const srcCount = (await pool.query('SELECT count(*)::int AS n FROM users')).rows[0].n;
123
225
  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
226
 
125
- // pg_dump inside the source container to stdout, capture as artefact
227
+ // Drive the shipped exportDatabase runner (TAC-2804) with a
228
+ // runPgDump override that shells out to docker exec inside the
229
+ // source container. The shipped runner still writes the artefact
230
+ // and emits backupExported; the probe proves both.
231
+ //
232
+ // Pre-run: assert the destination directory is absent, then create
233
+ // it. If a prior run left a stale artefact, remove it and
234
+ // positively re-check absence. Any failure here (permission
235
+ // denied, filesystem error) fails the row loudly.
236
+ try {
237
+ const preExist = await stat(ARTEFACT_DIR).catch((err) => {
238
+ if (err && err.code === 'ENOENT') return null;
239
+ throw err;
240
+ });
241
+ if (preExist) {
242
+ await rm(ARTEFACT_DIR, { recursive: true, force: true });
243
+ const after = await stat(ARTEFACT_DIR).catch((err) => {
244
+ if (err && err.code === 'ENOENT') return null;
245
+ throw err;
246
+ });
247
+ if (after) throw new Error(`pre-run: destination ${ARTEFACT_REL} still exists after rm -rf`);
248
+ }
249
+ } catch (err) {
250
+ if (!/still exists/.test(err && err.message)) throw new Error(`pre-run destination cleanup failed unrecognizably: ${err && (err.message || String(err))}`);
251
+ throw err;
252
+ }
126
253
  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');
254
+ const runnerEvents = [];
255
+ const exported = await exportDatabase({
256
+ destination: ARTEFACT,
257
+ onEvent: (e) => runnerEvents.push(e),
258
+ runPgDump: async ({ pgDumpArgs }) => {
259
+ const dump = await dockerExec(SOURCE_CONTAINER, ['pg_dump', '-U', 'rcf', '-d', 'rcf_test', ...pgDumpArgs]);
260
+ return dump.stdout;
261
+ },
262
+ });
263
+ artefactWritten = true;
264
+ const artefactStat = await stat(ARTEFACT);
265
+
266
+ // Assert the runner emitted backupExported per AC-27105-1.
267
+ // Sanitize the event's artefactPath (recovery.mjs records it as
268
+ // the absolute destination) to a project-relative path so a
269
+ // machine path does not land in the persisted evidence record.
270
+ const backupEvent = runnerEvents.find((e) => e.event === 'backupExported');
271
+ const backupEventSanitized = backupEvent
272
+ ? { ...backupEvent, artefactPath: relative(PROJECT_ROOT, backupEvent.artefactPath) }
273
+ : null;
274
+ results.push({
275
+ anchorAcId: 'AC-27105-1',
276
+ verdict: (backupEvent && typeof backupEvent.artefactPath === 'string' && typeof backupEvent.completedAt === 'string') ? 'pass' : 'fail',
277
+ detail: backupEvent
278
+ ? `Given a live Postgres containing a small fixture rowset - shipped exportDatabase emitted backupExported with artefactPath=${relative(PROJECT_ROOT, backupEvent.artefactPath)} completedAt=${backupEvent.completedAt}`
279
+ : `Given a live Postgres containing a small fixture rowset - expected backupExported event on the shipped exportDatabase runner; observed events=${runnerEvents.map((e) => e.event).join(',')}`,
280
+ evidence: {
281
+ backendPid: backendPidSrc,
282
+ transactionId: transactionIdSrc,
283
+ databaseName,
284
+ artefactPath: ARTEFACT_REL,
285
+ artefactBytesOnDisk: artefactStat.size,
286
+ bytesReportedByRunner: exported.bytes,
287
+ backupExportedEvent: backupEventSanitized,
288
+ },
289
+ });
130
290
 
131
291
  // Bring up restore container
132
292
  await bringUpRestore();
293
+ restoreBrought = true;
133
294
 
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'));
295
+ // Pipe artefact into psql on restore (the container ships psql).
296
+ await dockerExecStdin(RESTORE_CONTAINER, ['psql', '-U', 'rcf', '-d', 'rcf_test', '-v', 'ON_ERROR_STOP=1'], Buffer.from(await import('node:fs').then((fs) => fs.promises.readFile(ARTEFACT))));
136
297
 
137
- // Read row-count and checksum on restored
138
- const dstStore = createStore({ connectionUrl: `postgres://rcf:${encodeURIComponent('rcf-dev-only')}@localhost:${RESTORE_PORT}/rcf_test` });
298
+ // Read row-count and checksum on restored via a connection to the
299
+ // restore container's published port. Host is taken from
300
+ // POSTGRES_HOST (the docker host the restore container publishes
301
+ // its port on); no literal host default lives in shipped probe
302
+ // code.
303
+ // Password read from the declared POSTGRES_PASSWORD variable
304
+ // only; no literal password value in shipped probe source.
305
+ const dstStore = await createStore({ connectionUrl: `postgres://${process.env.POSTGRES_USER || 'rcf'}:${encodeURIComponent(process.env.POSTGRES_PASSWORD || '')}@${process.env.POSTGRES_HOST}:${RESTORE_PORT}/${process.env.POSTGRES_DB || 'rcf_test'}` });
139
306
  let dstCount = -1;
140
307
  let dstCk = 'unset';
308
+ let backendPidDst = null;
309
+ let transactionIdDst = null;
141
310
  try {
142
311
  await dstStore.ready();
143
312
  const dstPool = dstStore.getPool();
313
+ const pidRD = await dstPool.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid');
314
+ backendPidDst = String(pidRD.rows[0].pid);
315
+ transactionIdDst = String(pidRD.rows[0].txid);
144
316
  dstCount = (await dstPool.query('SELECT count(*)::int AS n FROM users')).rows[0].n;
145
317
  dstCk = (await dstPool.query('SELECT md5(string_agg(name || $1 || email, $2 ORDER BY id))::text AS ck FROM users', ['|', ','])).rows[0].ck;
146
318
  } finally {
147
319
  await dstStore.close();
148
320
  }
149
321
 
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
322
  results.push({
156
323
  anchorAcId: 'AC-27105-1',
157
324
  verdict: srcCount === dstCount ? 'pass' : 'fail',
158
- detail: `row-count source=${srcCount} restored=${dstCount}`,
325
+ detail: `Given a live Postgres containing a small fixture rowset - row-count source=${srcCount} restored=${dstCount}`,
326
+ evidence: { backendPid: backendPidDst, transactionId: transactionIdDst, databaseName, srcCount, dstCount, restoreContainer: RESTORE_CONTAINER, restorePort: RESTORE_PORT },
159
327
  });
160
328
  results.push({
161
329
  anchorAcId: 'AC-27105-1',
162
330
  verdict: srcCk === dstCk && srcCk != null ? 'pass' : 'fail',
163
- detail: `checksum source=${srcCk} restored=${dstCk}`,
331
+ detail: `Given a live Postgres containing a small fixture rowset - checksum source=${srcCk} restored=${dstCk}`,
332
+ evidence: { backendPid: backendPidDst, transactionId: transactionIdDst, srcChecksumMd5: srcCk, dstChecksumMd5: dstCk, checksumMatchStatus: (srcCk && dstCk && srcCk === dstCk) ? 'equal' : 'differ' },
164
333
  });
165
334
  } 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(() => {});
335
+ // Teardown, every step recorded. A failure here becomes a FAIL row
336
+ // on the results per authoring-standard rule 5.
337
+ await recordTeardown(teardown, 'TRUNCATE users on source', async () => {
338
+ try {
339
+ await store.getPool().query('TRUNCATE users RESTART IDENTITY');
340
+ } catch (err) {
341
+ // If the source is unreachable the probe still needs the store closed;
342
+ // rethrow so the accumulator records the failure.
343
+ throw err;
344
+ }
345
+ });
346
+ await recordTeardown(teardown, 'close source pool', async () => {
347
+ await store.close();
348
+ });
349
+ if (restoreBrought) {
350
+ await recordTeardown(teardown, `docker rm -f -v ${RESTORE_CONTAINER}`, async () => {
351
+ await execFileAsync('docker', ['rm', '-f', '-v', RESTORE_CONTAINER]);
352
+ });
353
+ // Positively confirm the container is gone. Any inspect outcome
354
+ // other than a "No such object" error fails the step so an
355
+ // unrecognized daemon-side error is not laundered into success.
356
+ await recordTeardown(teardown, `docker inspect ${RESTORE_CONTAINER} (expected: absent)`, async () => {
357
+ await assertContainerAbsent(RESTORE_CONTAINER);
358
+ return { exitCode: 0 };
359
+ });
360
+ }
361
+ if (artefactWritten) {
362
+ await recordTeardown(teardown, `rm -rf ${ARTEFACT_REL}`, async () => {
363
+ await rm(ARTEFACT_DIR, { recursive: true, force: true });
364
+ });
365
+ }
171
366
  }
172
- return results;
367
+ // Fold teardown outcomes into the result set (authoring-standard rule 5).
368
+ const failedTeardown = teardown.filter((t) => !t.ok);
369
+ // AC-27105-1 states rowset round-trip + backupExported. It does not
370
+ // state scratch-resource teardown, so this row is CONFORMANCE-ONLY:
371
+ // it records the operational teardown of the scratch restore
372
+ // container and artefact so a reader can see the run left no state
373
+ // behind, without claiming the AC's rowset property.
374
+ const AC27105_TEARDOWN_LIMITATION = 'AC-27105-1: Given a live Postgres containing a small fixture rowset, when the shipped recovery runner exports a backup, then backupExported fires with an artefact path and completedAt timestamp and a subsequent restore against a throwaway container yields byte-equal rowset content. Not observed on this row: this row records only the operational teardown (docker rm of the throwaway restore container plus removal of the pg_dump artefact tree) that follows the AC observing rows; the AC observing evidence is on the earlier rows in this same probe.';
375
+ results.push({
376
+ anchorAcId: null,
377
+ conformanceOnly: true,
378
+ limitation: AC27105_TEARDOWN_LIMITATION,
379
+ verdict: failedTeardown.length === 0 ? 'pass' : 'fail',
380
+ detail: failedTeardown.length === 0
381
+ ? `conformanceOnly (AC-27105-1: Given a live Postgres containing a small fixture) - teardown ok: ${teardown.map((t) => `${t.step} (exit=${t.exitCode})`).join('; ')}`
382
+ : `conformanceOnly (AC-27105-1: Given a live Postgres containing a small fixture) - teardown FAILED (${failedTeardown.length}/${teardown.length}): ${failedTeardown.map((t) => `${t.step} -> ${t.error}`).join('; ')}`,
383
+ evidence: { teardown },
384
+ });
385
+ return { results, extra: { teardown, restoreContainer: RESTORE_CONTAINER, restorePort: RESTORE_PORT } };
173
386
  }
@@ -10,70 +10,126 @@
10
10
  *
11
11
  * Anchors AC-27104-1.
12
12
  *
13
- * Cleans up: TRUNCATE users on exit; closes the pool.
13
+ * Cleans up: TRUNCATE users on exit; closes the pool. A teardown
14
+ * failure emits its own row (authoring-standard rule 5).
14
15
  */
15
16
 
16
- import { createStore, connectionUrlFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
17
+ import { createStore, connectionUrlFromEnv, MissingPostgresHostError } from '../../../../packages/rcf-lite/test/fixtures/infra-postgres/src/store.mjs';
18
+
19
+ const AC = 'Given the transaction helper wrapping a callback that';
20
+
21
+ export const DECLARED_ENV = Object.freeze([
22
+ 'POSTGRES_HOST',
23
+ 'POSTGRES_PORT',
24
+ 'POSTGRES_USER',
25
+ 'POSTGRES_PASSWORD',
26
+ 'POSTGRES_DB',
27
+ 'SIMULATE_CONSTRAINT_VIOLATION',
28
+ ]);
29
+
30
+ function skipRow(variable) {
31
+ return {
32
+ anchorAcId: null,
33
+ verdict: 'pass',
34
+ detail: `${AC} - accountBound: skipped (${variable} unset)`,
35
+ accountBoundSkipped: true,
36
+ reason: `${variable} unset`,
37
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
38
+ };
39
+ }
17
40
 
18
41
  export default async function runProbe() {
42
+ let url;
43
+ try {
44
+ url = connectionUrlFromEnv();
45
+ } catch (err) {
46
+ if (err instanceof MissingPostgresHostError) {
47
+ return {
48
+ results: [skipRow(err.variable)],
49
+ accountBoundSkipped: true,
50
+ reason: `${err.variable} unset`,
51
+ envDeclared: [...DECLARED_ENV],
52
+ };
53
+ }
54
+ throw err;
55
+ }
19
56
  const events = [];
20
- const store = createStore({
21
- connectionUrl: connectionUrlFromEnv(),
57
+ const store = await createStore({
58
+ connectionUrl: url,
22
59
  onEvent: (e) => events.push(e),
23
60
  });
24
61
  const results = [];
62
+ let databaseName = null;
25
63
  try {
26
- await store.ready();
64
+ databaseName = await store.ready();
27
65
  const pool = store.getPool();
28
- // Ensure schema and empty state
29
66
  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
67
  await pool.query('TRUNCATE users');
31
-
68
+ const pidRT = await pool.query('SELECT pg_backend_pid() AS pid, txid_current() AS txid');
69
+ const backendPid = String(pidRT.rows[0].pid);
70
+ const transactionId = String(pidRT.rows[0].txid);
32
71
  const email = 'transaction-atomicity@rcf.test';
33
72
  let caught = null;
34
73
  try {
35
74
  await store.withTransaction(async (tx) => {
36
75
  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
76
  await tx.query('INSERT INTO users(name, email) VALUES ($1, $2)', ['second-user', email]);
39
77
  });
40
78
  } catch (err) {
41
79
  caught = err;
42
80
  }
43
-
44
81
  const errorThrown = caught !== null;
45
82
  results.push({
46
83
  anchorAcId: 'AC-27104-1',
47
84
  verdict: errorThrown ? 'pass' : 'fail',
48
85
  detail: errorThrown
49
- ? `withTransaction re-threw underlying error code=${caught.code}`
50
- : 'withTransaction did not throw on the constraint violation',
86
+ ? `${AC} - withTransaction re-threw underlying error code=${caught.code}`
87
+ : `${AC} - withTransaction did not throw on the constraint violation`,
88
+ evidence: { backendPid, transactionId, databaseName, thrownErrorCode: caught && caught.code, thrownMessage: caught && caught.message },
51
89
  });
52
-
53
90
  const rolledBackEvent = events.find((e) => e.event === 'transactionRolledBack');
54
91
  const indexIsOne = rolledBackEvent && rolledBackEvent.statementIndex === 1;
55
92
  results.push({
56
93
  anchorAcId: 'AC-27104-1',
57
94
  verdict: indexIsOne ? 'pass' : 'fail',
58
95
  detail: rolledBackEvent
59
- ? `transactionRolledBack fired with statementIndex=${rolledBackEvent.statementIndex} code=${rolledBackEvent.code}`
60
- : `transactionRolledBack did not fire; events=${JSON.stringify(events)}`,
96
+ ? `${AC} - transactionRolledBack fired with statementIndex=${rolledBackEvent.statementIndex} code=${rolledBackEvent.code}`
97
+ : `${AC} - transactionRolledBack did not fire; events=${events.map((e) => e.event).join(',')}`,
98
+ evidence: { backendPid, transactionId, databaseName, transactionRolledBackEvent: rolledBackEvent || null, allEvents: events, rolledBackTimestamp: rolledBackEvent ? new Date(rolledBackEvent.ts).toISOString() : null, rolledBackVerificationOk: !!rolledBackEvent && rolledBackEvent.statementIndex === 1 },
61
99
  });
62
-
63
100
  const count = await store.countUsers();
64
101
  const noRowsPersist = count === 0;
65
102
  results.push({
66
103
  anchorAcId: 'AC-27104-1',
67
104
  verdict: noRowsPersist ? 'pass' : 'fail',
68
105
  detail: noRowsPersist
69
- ? 'users table empty after rollback (no partial commit landed)'
70
- : `users table carries ${count} row(s) after rollback (partial commit leaked)`,
106
+ ? `${AC} - users table empty after rollback (no partial commit landed)`
107
+ : `${AC} - users table carries ${count} row(s) after rollback (partial commit leaked)`,
108
+ evidence: { backendPid, transactionId, databaseName, postRollbackUserCount: count, postRollbackVerificationOk: count === 0 },
71
109
  });
72
110
  } finally {
111
+ const teardown = [];
73
112
  try {
74
113
  await store.getPool().query('TRUNCATE users');
75
- } catch { /* ignore */ }
76
- await store.close();
114
+ teardown.push({ step: 'TRUNCATE users on close', ok: true });
115
+ } catch (err) {
116
+ teardown.push({ step: 'TRUNCATE users on close', ok: false, error: err && err.message });
117
+ }
118
+ try {
119
+ await store.close();
120
+ teardown.push({ step: 'close pool', ok: true });
121
+ } catch (err) {
122
+ teardown.push({ step: 'close pool', ok: false, error: err && err.message });
123
+ }
124
+ const failed = teardown.filter((t) => !t.ok);
125
+ if (failed.length > 0) {
126
+ results.push({
127
+ anchorReqId: 'persistence-data-postgres-REQ-004',
128
+ verdict: 'fail',
129
+ detail: `The facade exposes a transaction helper - teardown FAILED: ${failed.map((t) => `${t.step} -> ${t.error}`).join('; ')}`,
130
+ evidence: { teardown },
131
+ });
132
+ }
77
133
  }
78
- return results;
134
+ return { results };
79
135
  }
@@ -2,7 +2,7 @@
2
2
  "reqId": "persistence-data-postgres-REQ-003",
3
3
  "prdId": "PRD-001",
4
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).",
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 the author-side check; the prepared-statement-scan probe surfaces the violation at gate time via a source-tree AST scan (per the persistence-data-d1 pattern).",
6
6
  "category": "technical",
7
7
  "domain": "persistence",
8
8
  "priority": "must",
@@ -60,7 +60,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
60
60
  | platform-docker-compose-host | 38101-38899 | 39xx | shipped v1.0.0 | `containerHostContract` |
61
61
  | edge-cloudflare-tunnel | 39101-39899 | 40xx | shipped v1.0.0 | `edgeIngressBridge` |
62
62
 
63
- US 27101-27110 sit at the LOW end of the 27101-27899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a persistence-data-postgres REQ id into the number 27110 would collide against the shipped US-27110; band headroom (27111-27899) leaves that space.
63
+ US 27101-27110 sit at the LOW end of the 27101-27899 band on purpose. A project-side story mechanically derived from a persistence-data-postgres REQ id into the number 27110 would collide against the shipped US-27110; band headroom (27111-27899) leaves that space.
64
64
 
65
65
  Postgres suffixes for this blueprint use the 2801-2899 block, continuing the widening pattern (persistence-data-sqlite 6xx, persistence-data-d1 14xx, and persistence-data-postgres 28xx).
66
66
 
@@ -1,14 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.5 - 2026-09-11
4
+
5
+ Strengthens the shared probe anatomy helper the seven core-shelf blueprints all lean on: rows whose only signal is a parsed log object with a message, a linesExcerpt array, a parsed component list, a rendered-state or -order list, a perFile / entries / commitEntries list, or a locally invented callTrackingId are refused as identifier evidence; retained anchor ids are checked against the applicable blueprint's shipped AC set; the WARN row shortcut that accepted a bare unobservableReason is removed and every WARN must now satisfy exact-skip, notObservableHere (browser-only) or identifier-plus-derived. No SQLite probe change was needed; SQLite remains GREEN.
6
+
7
+ ## 1.1.4 - 2026-09-11
8
+
9
+ wal-checkpoint AC-5105-3 anchor now observes the complete durability posture (PRAGMA journal_mode=wal + PRAGMA synchronous>=NORMAL + consumer-source grep) with a real integer rowId from a seed put through the facade; boot-open-migrate AC-5101-3 also carries a real rowId. Fixture store.mjs sets PRAGMA synchronous=NORMAL at open time and exposes synchronousNow(). Shared anatomy helper tightened per the strict-evidence contract (strict identifier set, existence check for shipped-AC limitation and notObservableHere.ac, exact-variable skip reason wire-up in all seven anatomy tests, notObservableHere is now refused for non-browser-only ACs, acceptedProfile removed from identifier lists, single JSON log-line string is derived only).
10
+
11
+ ## 1.1.3 - 2026-09-11
12
+
13
+ Adds a contributions/probes/ pack (boot-open-migrate, facade-round-trip, wal-checkpoint) with a fixture-side node:sqlite store facade under packages/rcf-lite/test/fixtures/probe-pack-persistence-data-sqlite/. Probes run against the real node:sqlite engine on Node 24; record real integer row ids, applied-migration lists, and wal_checkpoint(TRUNCATE) counters with the WAL sidecar shrink after truncate. No account gate.
14
+
15
+ Anchoring: boot-open-migrate anchors AC-5101-3 (open returns only after migrations run); the AC-5101-1 export-order row and the AC-5101-2 path-from-config row are de-claimed (conformanceOnly, anchorAcId=null) with limitations naming their respective ACs; the reopen row de-claims from AC-5101-3. wal-checkpoint anchors AC-5105-3 (durability posture set at open); the size-transition row and the walCheckpoint event row de-claim from AC-5105-1 and AC-5106-1 respectively. facade-round-trip anchors AC-5107-2 as its module anchor with the runtime CRUD rows de-claiming from AC-5107-2 (facade surface not exhaustively scanned) and the event row de-claiming from AC-5106-1. probe-utils normalisation and thrown-error rows carry an evidence object; the fallback anchorAcId is null (harnessError marks the row) rather than any placeholder id.
16
+
3
17
  ## 1.1.1 (register-sweep patch, 2026-09-10)
4
18
 
5
19
  - Register: neutral wording in shipped prose (no capability change).
6
20
 
7
21
  ## 1.1.0 - 2026-09-09
8
- Adds deliveredBy on REQ-001. Adds ownerRef on AC-5106-1 and AC-5110-2 (onEvent). Closes chain-contradiction specimen F-1: US-5109 AC-5109-3 now recovers a defective committed migration via a new numbered forward-only file (never editing the committed file in place), aligning with TAC-603 and the migration catalog's forward-only rule. Adds disposition to every AC.
22
+ Adds deliveredBy on REQ-001. Adds ownerRef on AC-5106-1 and AC-5110-2 (onEvent). US-5109 AC-5109-3 recovers a defective committed migration via a new numbered forward-only file (never editing the committed file in place), aligning with TAC-603 and the migration catalog's forward-only rule. Adds disposition to every AC.
9
23
 
10
24
 
11
25
 
12
- Review-fix (2026-09-09): Version bumped from 1.0.1 to 1.1.0 to reflect the net-added AC contributions on existing stories (permission-denied and concurrent-WAL failure paths added under US-5101; disk-full mid-migration added under US-5104). Prior 1.0.1 entry reclassified as prose-only; this bump covers the AC additions per section 8.
26
+ Version bumped from 1.0.1 to 1.1.0 to reflect the net-added AC contributions on existing stories (permission-denied and concurrent-WAL failure paths added under US-5101; disk-full mid-migration added under US-5104).
13
27
 
14
28
  Adds deliveredBy on REQ-002 through REQ-011 (ten of eleven mandatory REQs).
@@ -27,9 +27,9 @@ The doc set is contributions (copied into the project tree by `rcf define bluepr
27
27
 
28
28
  ## What it contributes, and what it deliberately does not
29
29
 
30
- Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (ratified decision 5) and no code.
30
+ Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (shipped policy 5) and no code.
31
31
 
32
- No FBS contributions, as a matter of principle (ratified policy 2026-08-19): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the store facade contract, the migration runner contract, the migration catalog shape, the backup runner contract, the event log discipline); the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
32
+ No FBS contributions, as a matter of principle (policy): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the store facade contract, the migration runner contract, the migration catalog shape, the backup runner contract, the event log discipline); the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
33
33
 
34
34
  Deliberately not contributed: the domain schema (the tables the project's own entities live in are project-authored, not blueprint-authored; the blueprint governs the store facade and the migration discipline, not the domain shape); ORMs, query builders, and any framework-shaped abstraction above the named CRUD verbs (the facade is a project-authored surface; how it internally implements its verbs is not blueprint-owned); a Postgres engine TAC (deferred; see ADR-601's alternatives and the guide 'when it does not fit'); logical schema-aware dumps (out of scope; see ADR-605's alternatives); connection pooling (an implementation detail of the facade when a project selects an engine that benefits from it, not a blueprint contribution).
35
35
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "slug": "persistence-data-sqlite",
3
- "version": "1.1.1",
3
+ "version": "1.1.5",
4
4
  "category": "persistence",
5
5
  "contributions": [
6
6
  {
@@ -162,5 +162,6 @@
162
162
  "kind": "adr",
163
163
  "path": "adrs/adr-605-persistence-data-sqlite-backup-model.json"
164
164
  }
165
- ]
165
+ ],
166
+ "updatedAt": "2026-09-11"
166
167
  }