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,24 +1,52 @@
1
1
  /**
2
2
  * Presigned URL probe.
3
3
  *
4
- * Issues a presigned URL with TTL 60 seconds, fetches it with Node
5
- * built-in fetch, asserts 200 within TTL. Sleeps to TTL+2 seconds,
6
- * fetches again, asserts 403 or the storage-side 403-equivalent.
4
+ * Per AC-28103-1 the property is: with a bounded TTL, a fetch WITHIN
5
+ * TTL returns 200, and the SAME URL fetched after TTL+2 seconds
6
+ * returns 403 (S3-shape AccessDenied). This probe proves the property
7
+ * exactly: it presigns a URL at the ADR-2902 floor of 60s, fetches it
8
+ * within TTL and records 200 + body-equal, then sleeps TTL+2s and
9
+ * fetches the SAME URL again and records 403.
7
10
  *
8
- * Anchors AC-28103-1.
11
+ * The floor-refusal below the 60s floor is also asserted (a separate
12
+ * result row) per ADR-2902.
9
13
  */
10
14
 
11
- import { createObjectStore, endpointFromEnv, credentialsFromShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
15
+ import { createObjectStore, endpointFromEnv, credentialsFromShim, MissingS3EndpointError } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
12
16
  import { secretsShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs';
13
17
  import { probeKey } from './probe-utils.mjs';
18
+ import { createHash } from 'node:crypto';
19
+
20
+ export const DECLARED_ENV = Object.freeze(['S3_ENDPOINT_URL']);
14
21
 
15
22
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
23
+ const AC28103_1 = 'Given a presignGetUrl call with ttl=60 seconds for';
24
+ const REQ003 = 'The facade exposes a presignGetUrl verb that issues';
25
+
26
+ function skipRow(variable) {
27
+ return {
28
+ anchorAcId: null,
29
+ verdict: 'pass',
30
+ detail: `${AC28103_1} - accountBound: skipped (${variable} unset)`,
31
+ accountBoundSkipped: true,
32
+ reason: `${variable} unset`,
33
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
34
+ };
35
+ }
16
36
 
17
37
  export default async function runProbe() {
18
- const { endpoint, bucket, region, forcePathStyle } = endpointFromEnv();
38
+ let endpoint, bucket, region, forcePathStyle;
39
+ try {
40
+ ({ endpoint, bucket, region, forcePathStyle } = endpointFromEnv());
41
+ } catch (err) {
42
+ if (err instanceof MissingS3EndpointError) {
43
+ return { results: [skipRow(err.variable)], extra: { accountBoundSkipped: true, reason: `${err.variable} unset`, envDeclared: [...DECLARED_ENV] } };
44
+ }
45
+ throw err;
46
+ }
19
47
  const credentials = await credentialsFromShim(secretsShim);
20
48
  const events = [];
21
- const store = createObjectStore({
49
+ const store = await createObjectStore({
22
50
  endpointUrl: endpoint,
23
51
  bucket,
24
52
  credentialsRef: credentials,
@@ -31,71 +59,92 @@ export default async function runProbe() {
31
59
  const body = Buffer.from('presigned url payload');
32
60
  try {
33
61
  await store.ready();
34
- await store.putObject(key, 'text/plain', body);
62
+ const putRes = await store.putObject(key, 'text/plain', body);
63
+
64
+ // AC-28103-1 canonical timing test: TTL=60, fetch within TTL, then
65
+ // fetch the SAME URL after TTL+2s.
35
66
  const ttl = 60;
36
67
  const url = await store.presignGetUrl(key, ttl);
68
+ const urlSha256 = createHash('sha256').update(url).digest('hex');
69
+ const issuedAt = Date.now();
37
70
  const first = await fetch(url);
38
71
  const firstBody = Buffer.from(await first.arrayBuffer());
39
- const firstPass = first.status === 200 && firstBody.equals(body);
72
+ const firstStatus = first.status;
73
+ const firstEqual = firstBody.equals(body);
40
74
  const issued = events.find((e) => e.event === 'presignedIssued' && e.key === key && e.ttl === ttl);
41
75
  results.push({
42
76
  anchorAcId: 'AC-28103-1',
43
- verdict: firstPass && issued ? 'pass' : 'fail',
44
- detail: firstPass && issued
45
- ? `fetch within TTL returned ${first.status} with matching body; presignedIssued fired with ttl=${ttl}`
46
- : `firstStatus=${first.status} bodyMatch=${firstBody.equals(body)} issued=${Boolean(issued)}`,
77
+ verdict: firstStatus === 200 && firstEqual && issued ? 'pass' : 'fail',
78
+ detail: firstStatus === 200 && firstEqual && issued
79
+ ? `${AC28103_1} - fetch within TTL returned 200 with matching body; presignedIssued fired with ttl=${ttl}; urlSha256=${urlSha256.slice(0, 12)}`
80
+ : `${AC28103_1} - firstStatus=${firstStatus} bodyMatch=${firstEqual} issued=${Boolean(issued)}`,
81
+ evidence: {
82
+ eTag: (putRes && putRes.eTag) || null,
83
+ vendorRequestId: (putRes && putRes.requestId) || null,
84
+ bucketName: bucket,
85
+ key,
86
+ ttl,
87
+ firstStatus,
88
+ firstBodyBytes: firstBody.length,
89
+ firstBodyEqual: firstEqual,
90
+ presignedIssuedEvent: issued || null,
91
+ urlSha256,
92
+ elapsedMsSincePresign: Date.now() - issuedAt,
93
+ },
47
94
  });
48
95
 
49
- // Test TTL expiration: sleep past TTL, expect 403
50
- // NOTE: TTL floor probe (below the 1-minute floor) is asserted via a
51
- // separate try/catch below to avoid a 60+ second sleep in CI.
52
- const shortUrl = await store.presignGetUrl(key, 60);
53
- // Sleep past the 60s TTL is too slow for CI: instead we test the
54
- // signature-expiry surface by asserting the presign floor refuses.
55
- // The 200-then-403 expiration behaviour is asserted at real-time via
56
- // the second URL fetch after a much shorter tampered TTL below.
57
-
58
- // Truncated ttl test: use a 1s-expired presign by generating a URL
59
- // with a very short (but at-floor) TTL and awaiting past it.
60
- const shortTtl = 60;
61
- const shortUrl2 = await store.presignGetUrl(key, shortTtl);
62
- // We simulate expiry by tampering the X-Amz-Date to a stale value
63
- // via SIMULATE_PRESIGN_MALFORMED; the real 200-then-403 timing test
64
- // runs with SIMULATE_PRESIGN_EXPIRE=true which sleeps TTL+2 seconds.
65
- if (process.env.SIMULATE_PRESIGN_EXPIRE === 'true') {
66
- await sleep((shortTtl + 2) * 1000);
67
- const second = await fetch(shortUrl2);
68
- results.push({
69
- anchorAcId: 'AC-28103-1',
70
- verdict: second.status === 403 ? 'pass' : 'fail',
71
- detail: `after TTL fetch returned ${second.status} (expected 403)`,
72
- });
73
- } else {
74
- // Time-shortened path: presign at floor and immediately corrupt
75
- // the signature so the endpoint returns 403 without a wall-clock
76
- // wait. This proves the 403-shape on tampered signatures; the
77
- // real timing test remains available via SIMULATE_PRESIGN_EXPIRE.
78
- const tampered = shortUrl2.replace(/X-Amz-Signature=[^&]*/, 'X-Amz-Signature=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef');
79
- const second = await fetch(tampered);
80
- results.push({
81
- anchorAcId: 'AC-28103-1',
82
- verdict: second.status === 403 ? 'pass' : 'fail',
83
- detail: `tampered signature fetch returned ${second.status} (expected 403; set SIMULATE_PRESIGN_EXPIRE=true for full TTL wall-clock)`,
84
- });
85
- }
96
+ // Wait past TTL and fetch the SAME URL. AC-28103-1 explicitly says
97
+ // "the same URL". This is a wall-clock wait; the probe budget
98
+ // includes it.
99
+ const waitMs = (ttl + 2) * 1000;
100
+ await sleep(waitMs);
101
+ const second = await fetch(url);
102
+ const secondStatus = second.status;
103
+ results.push({
104
+ anchorAcId: 'AC-28103-1',
105
+ verdict: secondStatus === 403 ? 'pass' : 'fail',
106
+ detail: secondStatus === 403
107
+ ? `${AC28103_1} - after TTL+2s the SAME presigned URL (urlSha256=${urlSha256.slice(0, 12)}) returned 403 (AccessDenied / expired-URL family)`
108
+ : `${AC28103_1} - after TTL+2s the SAME presigned URL returned ${secondStatus}, expected 403`,
109
+ evidence: {
110
+ eTag: (putRes && putRes.eTag) || null,
111
+ vendorRequestId: (putRes && putRes.requestId) || null,
112
+ bucketName: bucket,
113
+ key,
114
+ ttl,
115
+ waitedMs: waitMs,
116
+ secondStatus,
117
+ urlSha256,
118
+ totalElapsedMsSincePresign: Date.now() - issuedAt,
119
+ },
120
+ });
86
121
 
87
- // Floor refusal (1 minute per ADR-2902)
122
+ // ADR-2902 floor refusal is not stated by any AC (AC-28103-1
123
+ // states TTL 60 success/expiry). Anchor to REQ-003 which names
124
+ // the floor of 1 minute.
88
125
  let refusedBelowFloor = false;
89
- try { await store.presignGetUrl(key, 30); } catch { refusedBelowFloor = true; }
126
+ let refusedError = null;
127
+ try { await store.presignGetUrl(key, 30); } catch (err) { refusedBelowFloor = true; refusedError = err && err.message; }
90
128
  results.push({
91
- anchorAcId: 'AC-28103-1',
129
+ anchorReqId: 'object-storage-s3-REQ-003',
92
130
  verdict: refusedBelowFloor ? 'pass' : 'fail',
93
- detail: refusedBelowFloor ? 'presign below 60s floor refused per ADR-2902' : 'presign below floor did not refuse',
131
+ detail: refusedBelowFloor
132
+ ? `${REQ003} - presign below the 60s floor refused per ADR-2902 (${refusedError})`
133
+ : `${REQ003} - presign below the 60s floor did not refuse`,
134
+ evidence: {
135
+ eTag: (putRes && putRes.eTag) || null,
136
+ vendorRequestId: (putRes && putRes.requestId) || null,
137
+ bucketName: bucket,
138
+ requestedTtlSeconds: 30, floorSeconds: 60,
139
+ refused: refusedBelowFloor, error: refusedError,
140
+ refusalFired: refusedBelowFloor,
141
+ refusalCode: refusedBelowFloor ? 'below-floor' : 'accepted',
142
+ },
94
143
  });
95
144
 
96
145
  await store.deleteObject(key);
97
146
  } finally {
98
147
  await store.close();
99
148
  }
100
- return results;
149
+ return { results, extra: { key } };
101
150
  }
@@ -25,47 +25,82 @@ export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/object-
25
25
  * - pass otherwise
26
26
  */
27
27
  export function aggregate(results) {
28
+ // Empty or null result sets are a FAIL: a probe that emitted no rows
29
+ // proved nothing (authoring-standard rule 3, criterion e conformance).
30
+ if (!Array.isArray(results) || results.length === 0) return 'fail';
28
31
  if (results.some((r) => r.verdict === 'fail')) return 'fail';
29
32
  if (results.some((r) => r.verdict === 'warn')) return 'warn';
30
33
  return 'pass';
31
34
  }
32
35
 
36
+ /**
37
+ * Return true when every result is an account-bound skip; the
38
+ * aggregate then flips to pass per spec section 3.5 and authoring
39
+ * standard section 7d.
40
+ */
41
+ export function isAccountBoundSkipped(results) {
42
+ return results.length > 0 && results.every((r) => r.accountBoundSkipped === true);
43
+ }
44
+
33
45
  /**
34
46
  * Write the per-blueprint probe report at
35
47
  * .rcf/reports/blueprints/object-storage-s3/<probeName>.json
36
- * per spec section 3.4.
48
+ * per spec section 3.4. Accepts an optional extra bag that is
49
+ * spread onto the report envelope (e.g. envDeclared, evidence,
50
+ * accountBoundSkipped) so real-account probes can surface positive
51
+ * evidence per authoring standard section 7d.
37
52
  */
38
- export async function writeReport({ probeName, engine, results }) {
53
+ export async function writeReport({ probeName, engine, results, extra }) {
39
54
  await mkdir(REPORT_DIR, { recursive: true });
55
+ const raw = aggregate(results);
56
+ const aggregateVerdict = isAccountBoundSkipped(results) ? 'pass' : raw;
40
57
  const report = {
41
58
  slug: 'object-storage-s3',
42
59
  probeName,
43
60
  runAt: new Date().toISOString(),
44
61
  engine,
45
62
  results,
46
- aggregateVerdict: aggregate(results),
63
+ aggregateVerdict,
64
+ ...(extra ?? {}),
47
65
  };
48
66
  const path = resolve(REPORT_DIR, `${probeName}.json`);
49
67
  await writeFile(path, JSON.stringify(report, null, 2), 'utf8');
50
68
  return { report, path };
51
69
  }
52
70
 
71
+ function normaliseMain(value) {
72
+ if (value == null) {
73
+ // A probe that returned null / undefined proved nothing (authoring-standard rule 3).
74
+ return { results: [{ anchorReqId: 'object-storage-s3-REQ-001', verdict: 'fail', detail: 'no checks ran (probe returned null / undefined)', evidence: { probeReturnedNullOrUndefined: true } }], extra: {} };
75
+ }
76
+ if (Array.isArray(value)) return { results: value, extra: {} };
77
+ if (value && Array.isArray(value.results)) {
78
+ const { results, ...extra } = value;
79
+ return { results, extra };
80
+ }
81
+ throw new Error('probe main must return an array or an object with a results[] field');
82
+ }
83
+
53
84
  /**
54
85
  * Drive an async main() and exit 0 on aggregate pass, 1 otherwise.
55
- * Prints the report JSON to stdout for the gate-reviewer to read.
86
+ * Prints the report JSON to stdout for the gate-operator to read.
87
+ * The probe main may return either an array of result records or an
88
+ * envelope { results, ...extra } whose extra bag is written onto the
89
+ * report envelope alongside the aggregateVerdict.
56
90
  */
57
91
  export async function runShim(probeName, engine, mainFn) {
58
92
  try {
59
- const results = await mainFn();
60
- const { report, path } = await writeReport({ probeName, engine, results });
93
+ const { results, extra } = normaliseMain(await mainFn());
94
+ const { report, path } = await writeReport({ probeName, engine, results, extra });
61
95
  process.stdout.write(JSON.stringify(report, null, 2) + '\n');
62
96
  process.stdout.write(`report written to ${path}\n`);
63
97
  process.exit(report.aggregateVerdict === 'pass' ? 0 : 1);
64
98
  } catch (err) {
65
99
  const results = [{
66
- anchorAcId: 'unknown',
100
+ anchorReqId: 'object-storage-s3-REQ-001',
67
101
  verdict: 'fail',
68
102
  detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
103
+ evidence: { probeThrew: true, errorMessage: err && err.message ? err.message : String(err), errorName: err && err.name },
69
104
  }];
70
105
  const { report, path } = await writeReport({ probeName, engine, results });
71
106
  process.stdout.write(JSON.stringify(report, null, 2) + '\n');
@@ -83,3 +118,90 @@ export function probeKey(prefix) {
83
118
  const suffix = Math.random().toString(36).slice(2, 10);
84
119
  return `${prefix}/${Date.now()}-${suffix}`;
85
120
  }
121
+
122
+ /**
123
+ * Fetch MinIO /minio/health/live for the current run's S3 endpoint and
124
+ * return an observed engine descriptor:
125
+ * { kind: 's3', vendor: 'minio', endpointHost, healthLive: { httpStatus, responseTimeMs, ok } }
126
+ * Never returns a fabricated healthy: true. A failed probe returns
127
+ * `{ ok: false, error }` under `healthLive`.
128
+ */
129
+ export async function observeMinioEngine() {
130
+ const endpointUrl = process.env.S3_ENDPOINT_URL;
131
+ if (!endpointUrl) {
132
+ // S3_ENDPOINT_URL is a required declared variable per the
133
+ // endpoint-hosts rule; caller records an exact one-variable skip when unset.
134
+ return { kind: 's3', vendor: 'minio', endpointHost: null, healthLive: { ok: false, error: 'S3_ENDPOINT_URL unset' } };
135
+ }
136
+ const url = new URL('/minio/health/live', endpointUrl);
137
+ const started = Date.now();
138
+ try {
139
+ const res = await fetch(url.toString(), { method: 'GET' });
140
+ return {
141
+ kind: 's3',
142
+ vendor: 'minio',
143
+ endpointHost: url.host,
144
+ healthLive: {
145
+ ok: res.status === 200,
146
+ httpStatus: res.status,
147
+ responseTimeMs: Date.now() - started,
148
+ endpoint: url.toString(),
149
+ },
150
+ };
151
+ } catch (err) {
152
+ return {
153
+ kind: 's3',
154
+ vendor: 'minio',
155
+ endpointHost: url.host,
156
+ healthLive: {
157
+ ok: false,
158
+ error: err && err.message,
159
+ responseTimeMs: Date.now() - started,
160
+ endpoint: url.toString(),
161
+ },
162
+ };
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Observe R2 by issuing a lightweight ListBuckets against the R2
168
+ * endpoint from the fixture secrets shim. Returns an engine descriptor
169
+ * with a real request id and http status. Returns a not-observed
170
+ * descriptor when the account gate is unset , the probe itself will
171
+ * account-bound-skip and no wire call should be made here.
172
+ */
173
+ export async function observeR2Engine() {
174
+ if (process.env.CI_HAS_CLOUDFLARE_ACCOUNT !== 'true') {
175
+ return { kind: 's3', vendor: 'cloudflare-r2', observed: false, reason: 'CI_HAS_CLOUDFLARE_ACCOUNT unset' };
176
+ }
177
+ try {
178
+ const { secretsShim } = await import('../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs');
179
+ const { credentialsFromShim } = await import('../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs');
180
+ const { createBucketOps } = await import('../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/bucket-ops.mjs');
181
+ const r2 = await secretsShim.getSecret('r2Endpoint');
182
+ if (!r2 || !r2.endpoint) return { kind: 's3', vendor: 'cloudflare-r2', observed: false, reason: 'r2Endpoint unresolvable' };
183
+ const credentials = await credentialsFromShim(secretsShim);
184
+ const ops = createBucketOps({ endpointUrl: r2.endpoint, region: 'auto', credentials, forcePathStyle: false });
185
+ const started = Date.now();
186
+ try {
187
+ const list = await ops.listBuckets();
188
+ const host = new URL(r2.endpoint).host;
189
+ return {
190
+ kind: 's3',
191
+ vendor: 'cloudflare-r2',
192
+ endpointHostRedacted: host.replace(/^[0-9a-f]+/, '[account-id]'),
193
+ listBuckets: {
194
+ ok: true,
195
+ httpStatus: list.raw && list.raw.$metadata && list.raw.$metadata.httpStatusCode,
196
+ requestId: list.raw && list.raw.$metadata && list.raw.$metadata.requestId,
197
+ bucketCount: list.buckets.length,
198
+ responseTimeMs: Date.now() - started,
199
+ },
200
+ };
201
+ } finally {
202
+ ops.close();
203
+ }
204
+ } catch (err) {
205
+ return { kind: 's3', vendor: 'cloudflare-r2', observed: false, error: err && err.message };
206
+ }
207
+ }
@@ -9,15 +9,40 @@
9
9
  * Anchors AC-28102-1, AC-28102-2, AC-28102-3.
10
10
  */
11
11
 
12
- import { createObjectStore, endpointFromEnv, credentialsFromShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
12
+ import { createObjectStore, endpointFromEnv, credentialsFromShim, MissingS3EndpointError } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
13
13
  import { secretsShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs';
14
14
  import { probeKey } from './probe-utils.mjs';
15
15
 
16
+ export const DECLARED_ENV = Object.freeze(['S3_ENDPOINT_URL']);
17
+
18
+ const AC28102_1 = 'Given a putObject through the facade for a';
19
+ const AC28102_2 = 'Given a deleteObject through the facade for a';
20
+ const AC28102_3 = 'Given at least three objects put under a';
21
+
22
+ function skipRow(variable) {
23
+ return {
24
+ anchorAcId: null,
25
+ verdict: 'pass',
26
+ detail: `${AC28102_1} - accountBound: skipped (${variable} unset)`,
27
+ accountBoundSkipped: true,
28
+ reason: `${variable} unset`,
29
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
30
+ };
31
+ }
32
+
16
33
  export default async function runProbe() {
17
- const { endpoint, bucket, region, forcePathStyle } = endpointFromEnv();
34
+ let endpoint, bucket, region, forcePathStyle;
35
+ try {
36
+ ({ endpoint, bucket, region, forcePathStyle } = endpointFromEnv());
37
+ } catch (err) {
38
+ if (err instanceof MissingS3EndpointError) {
39
+ return { results: [skipRow(err.variable)], extra: { accountBoundSkipped: true, reason: `${err.variable} unset`, envDeclared: [...DECLARED_ENV] } };
40
+ }
41
+ throw err;
42
+ }
18
43
  const credentials = await credentialsFromShim(secretsShim);
19
44
  const events = [];
20
- const store = createObjectStore({
45
+ const store = await createObjectStore({
21
46
  endpointUrl: endpoint,
22
47
  bucket,
23
48
  credentialsRef: credentials,
@@ -29,9 +54,11 @@ export default async function runProbe() {
29
54
  const key = probeKey('probe/put-get');
30
55
  const body = Buffer.alloc(1024, 0x41); // 1 KiB of A
31
56
  const contentType = 'application/octet-stream';
57
+ const prefix = probeKey('probe/list-parent');
58
+ const listKeys = [`${prefix}/a`, `${prefix}/b`, `${prefix}/c`];
32
59
  try {
33
60
  await store.ready();
34
- await store.putObject(key, contentType, body);
61
+ const putRes = await store.putObject(key, contentType, body);
35
62
  const got = await store.getObject(key);
36
63
  const roundTripPass = got.body.length === 1024
37
64
  && got.body.equals(body)
@@ -42,24 +69,39 @@ export default async function runProbe() {
42
69
  anchorAcId: 'AC-28102-1',
43
70
  verdict: roundTripPass && eventPass ? 'pass' : 'fail',
44
71
  detail: roundTripPass && eventPass
45
- ? `1 KiB round-trip byte-equal; objectPut fired with size=${putEvent.size}`
46
- : `roundTripPass=${roundTripPass} eventPass=${eventPass} got.size=${got.body.length}`,
72
+ ? `${AC28102_1} - 1 KiB round-trip byte-equal; objectPut fired with size=${putEvent.size}`
73
+ : `${AC28102_1} - roundTripPass=${roundTripPass} eventPass=${eventPass} got.size=${got.body.length}`,
74
+ evidence: {
75
+ vendorRequestId: (putRes && putRes.requestId) || (got && got.requestId) || null,
76
+ eTag: (putRes && putRes.eTag) || (got && got.eTag) || null,
77
+ bucketName: bucket, key,
78
+ requestedContentType: contentType, gotContentType: got.contentType,
79
+ gotSize: got.body.length, byteEqual: got.body.equals(body),
80
+ objectPutEvent: putEvent || null,
81
+ },
47
82
  });
48
83
 
49
84
  // list under prefix
50
- const prefix = probeKey('probe/list-parent');
51
- const listKeys = [`${prefix}/a`, `${prefix}/b`, `${prefix}/c`];
52
- for (const k of listKeys) await store.putObject(k, 'text/plain', Buffer.from(k));
85
+ const listPuts = [];
86
+ for (const k of listKeys) listPuts.push(await store.putObject(k, 'text/plain', Buffer.from(k)));
53
87
  const listed = await store.listObjects(prefix);
54
88
  const listPass = listKeys.every((k) => listed.keys.includes(k)) && typeof listed.isTruncated === 'boolean';
55
89
  results.push({
56
90
  anchorAcId: 'AC-28102-3',
57
91
  verdict: listPass ? 'pass' : 'fail',
58
- detail: listPass ? `list returned ${listed.keys.length} keys with isTruncated=${listed.isTruncated}` : `listed=${JSON.stringify(listed)}`,
92
+ detail: listPass
93
+ ? `${AC28102_3} - list returned ${listed.keys.length} keys with isTruncated=${listed.isTruncated}`
94
+ : `${AC28102_3} - listed=${JSON.stringify(listed)}`,
95
+ evidence: {
96
+ vendorRequestId: (listed && listed.requestId) || (listPuts.find((p) => p && p.requestId) || {}).requestId || null,
97
+ bucketName: bucket, prefix,
98
+ expectedKeys: listKeys, returnedKeys: listed.keys,
99
+ isTruncated: listed.isTruncated,
100
+ },
59
101
  });
60
102
 
61
103
  // delete and confirm 404
62
- await store.deleteObject(key);
104
+ const delRes = await store.deleteObject(key);
63
105
  let deletedEvent = events.find((e) => e.event === 'objectDeleted' && e.key === key);
64
106
  let notFound = false;
65
107
  try { await store.getObject(key); } catch (err) {
@@ -70,15 +112,35 @@ export default async function runProbe() {
70
112
  anchorAcId: 'AC-28102-2',
71
113
  verdict: deletedEvent && notFound ? 'pass' : 'fail',
72
114
  detail: deletedEvent && notFound
73
- ? 'objectDeleted fired and get after delete returned NoSuchKey'
74
- : `deletedEvent=${Boolean(deletedEvent)} notFound=${notFound}`,
115
+ ? `${AC28102_2} - objectDeleted fired and get after delete returned NoSuchKey`
116
+ : `${AC28102_2} - deletedEvent=${Boolean(deletedEvent)} notFound=${notFound}`,
117
+ evidence: {
118
+ vendorRequestId: (delRes && delRes.requestId) || null,
119
+ bucketName: bucket, key,
120
+ objectDeletedEvent: deletedEvent || null,
121
+ getAfterDeleteWasNotFound: notFound,
122
+ },
75
123
  });
76
- // clean up the list keys
124
+ // Teardown: delete the list keys and close the facade. Every
125
+ // teardown step is recorded on the teardown[] accumulator and any
126
+ // failure emits its own row (authoring-standard rule 5).
127
+ } finally {
128
+ const teardown = [];
77
129
  for (const k of listKeys) {
78
- try { await store.deleteObject(k); } catch { /* ignore */ }
130
+ try { await store.deleteObject(k); teardown.push({ step: `deleteObject ${k}`, ok: true }); }
131
+ catch (err) { teardown.push({ step: `deleteObject ${k}`, ok: false, error: err && err.message }); }
132
+ }
133
+ try { await store.close(); teardown.push({ step: 'facade close', ok: true }); }
134
+ catch (err) { teardown.push({ step: 'facade close', ok: false, error: err && err.message }); }
135
+ const failed = teardown.filter((t) => !t.ok);
136
+ if (failed.length > 0) {
137
+ results.push({
138
+ anchorReqId: 'object-storage-s3-REQ-002',
139
+ verdict: 'fail',
140
+ detail: `The facade exposes named domain verbs (putObject, getObject, - teardown FAILED: ${failed.map((t) => `${t.step} -> ${t.error}`).join('; ')}`,
141
+ evidence: { teardown },
142
+ });
79
143
  }
80
- } finally {
81
- await store.close();
82
144
  }
83
- return results;
145
+ return { results, extra: { envDeclared: [...DECLARED_ENV] } };
84
146
  }