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
@@ -12,18 +12,41 @@
12
12
  * Anchors AC-28105-1.
13
13
  */
14
14
 
15
- 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';
16
16
  import { secretsShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs';
17
17
 
18
+ export const DECLARED_ENV = Object.freeze(['S3_ENDPOINT_URL']);
19
+
18
20
  const WHITELIST = new Set(['event', 'ts', 'key', 'size', 'contentType', 'ttl', 'endpointHost', 'bucketName']);
19
21
  const FORBIDDEN_FIELDS = ['userId', 'ssn', 'dob', 'email', 'body', 'bodyBytes', 'bodyChecksum'];
20
22
  const PII_TEXT = 'PII-FIXTURE-DO-NOT-LOG';
21
23
 
24
+ const AC28105_1 = 'Given a lifecycle-event spy attached to the sink,';
25
+
26
+ function skipRow(variable) {
27
+ return {
28
+ anchorAcId: null,
29
+ verdict: 'pass',
30
+ detail: `${AC28105_1} - accountBound: skipped (${variable} unset)`,
31
+ accountBoundSkipped: true,
32
+ reason: `${variable} unset`,
33
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
34
+ };
35
+ }
36
+
22
37
  export default async function runProbe() {
23
- 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
+ }
24
47
  const credentials = await credentialsFromShim(secretsShim);
25
48
  const events = [];
26
- const store = createObjectStore({
49
+ const store = await createObjectStore({
27
50
  endpointUrl: endpoint,
28
51
  bucket,
29
52
  credentialsRef: credentials,
@@ -34,8 +57,21 @@ export default async function runProbe() {
34
57
  const results = [];
35
58
  const key = 'users/1234/passport.jpg';
36
59
  const body = Buffer.from(`prefix-${PII_TEXT}-suffix`);
60
+ const vendorReq = { put: null, get: null, del: null };
37
61
  try {
38
62
  await store.ready();
63
+ // Drive one PutObject via SDK directly for per-row vendor
64
+ // evidence, then delete it, then run the shipped-facade path.
65
+ const { loadSdk } = await import('../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs'); const sdk = await loadSdk();
66
+ const client = store.getClient();
67
+ const rawPut = await client.send(new sdk.PutObjectCommand({ Bucket: bucket, Key: `${key}.evidence`, Body: body, ContentType: 'image/jpeg' }));
68
+ vendorReq.put = { httpStatus: rawPut.$metadata && rawPut.$metadata.httpStatusCode, requestId: rawPut.$metadata && rawPut.$metadata.requestId };
69
+ const rawGet = await client.send(new sdk.GetObjectCommand({ Bucket: bucket, Key: `${key}.evidence` }));
70
+ vendorReq.get = { httpStatus: rawGet.$metadata && rawGet.$metadata.httpStatusCode, requestId: rawGet.$metadata && rawGet.$metadata.requestId };
71
+ try { await rawGet.Body.transformToByteArray(); } catch { /* drain */ }
72
+ const rawDel = await client.send(new sdk.DeleteObjectCommand({ Bucket: bucket, Key: `${key}.evidence` }));
73
+ vendorReq.del = { httpStatus: rawDel.$metadata && rawDel.$metadata.httpStatusCode, requestId: rawDel.$metadata && rawDel.$metadata.requestId };
74
+
39
75
  await store.putObject(key, 'image/jpeg', body);
40
76
  await store.getObject(key);
41
77
  await store.presignGetUrl(key, 60);
@@ -52,8 +88,14 @@ export default async function runProbe() {
52
88
  anchorAcId: 'AC-28105-1',
53
89
  verdict: nonWhitelistKeys.size === 0 ? 'pass' : 'fail',
54
90
  detail: nonWhitelistKeys.size === 0
55
- ? `every event carries only whitelisted fields (${[...WHITELIST].join(',')})`
56
- : `unexpected event fields: ${[...nonWhitelistKeys].join(',')}`,
91
+ ? `${AC28105_1} - every event carries only whitelisted fields (${[...WHITELIST].join(',')})`
92
+ : `${AC28105_1} - unexpected event fields: ${[...nonWhitelistKeys].join(',')}`,
93
+ evidence: {
94
+ vendorRequestId: (vendorReq.put && vendorReq.put.requestId) || null,
95
+ bucketName: bucket,
96
+ whitelist: [...WHITELIST], nonWhitelistedFields: [...nonWhitelistKeys],
97
+ eventCount: events.length, vendorRequestIdMetadata: vendorReq,
98
+ },
57
99
  });
58
100
 
59
101
  // No forbidden field names
@@ -67,8 +109,14 @@ export default async function runProbe() {
67
109
  anchorAcId: 'AC-28105-1',
68
110
  verdict: foundForbidden.length === 0 ? 'pass' : 'fail',
69
111
  detail: foundForbidden.length === 0
70
- ? 'no forbidden PII field name appeared on any event'
71
- : `forbidden fields present: ${foundForbidden.join(',')}`,
112
+ ? `${AC28105_1} - no forbidden PII field name appeared on any event`
113
+ : `${AC28105_1} - forbidden fields present: ${foundForbidden.join(',')}`,
114
+ evidence: {
115
+ vendorRequestId: (vendorReq.get && vendorReq.get.requestId) || null,
116
+ bucketName: bucket,
117
+ forbiddenFieldNames: FORBIDDEN_FIELDS, foundForbidden,
118
+ eventCount: events.length, vendorRequestIdMetadata: vendorReq,
119
+ },
72
120
  });
73
121
 
74
122
  // No event value contains the PII fixture text
@@ -82,8 +130,14 @@ export default async function runProbe() {
82
130
  anchorAcId: 'AC-28105-1',
83
131
  verdict: leaks.length === 0 ? 'pass' : 'fail',
84
132
  detail: leaks.length === 0
85
- ? `no event value contained the PII fixture text ${PII_TEXT}`
86
- : `PII fixture text leaked in: ${leaks.join(',')}`,
133
+ ? `${AC28105_1} - no event value contained the PII fixture text ${PII_TEXT}`
134
+ : `${AC28105_1} - PII fixture text leaked in: ${leaks.join(',')}`,
135
+ evidence: {
136
+ vendorRequestId: (vendorReq.del && vendorReq.del.requestId) || null,
137
+ bucketName: bucket,
138
+ piiFixtureLiteral: PII_TEXT, leakSites: leaks,
139
+ eventCount: events.length, vendorRequestIdMetadata: vendorReq,
140
+ },
87
141
  });
88
142
 
89
143
  // The key itself is passed through unchanged; it is not decomposed
@@ -93,11 +147,18 @@ export default async function runProbe() {
93
147
  anchorAcId: 'AC-28105-1',
94
148
  verdict: keyPass ? 'pass' : 'fail',
95
149
  detail: keyPass
96
- ? `objectPut carried the key ${key} as an opaque string; no userId extraction`
97
- : `key was decomposed or absent on objectPut: ${JSON.stringify(putEvent)}`,
150
+ ? `${AC28105_1} - objectPut carried the key ${key} as an opaque string; no userId extraction`
151
+ : `${AC28105_1} - key was decomposed or absent on objectPut: ${JSON.stringify(putEvent)}`,
152
+ evidence: {
153
+ vendorRequestId: (vendorReq.put && vendorReq.put.requestId) || null,
154
+ bucketName: bucket,
155
+ expectedKey: key,
156
+ objectPutEvent: putEvent || null,
157
+ vendorRequestIdMetadata: vendorReq,
158
+ },
98
159
  });
99
160
  } finally {
100
161
  await store.close();
101
162
  }
102
- return results;
163
+ return { results, extra: { envDeclared: [...DECLARED_ENV] } };
103
164
  }
@@ -8,14 +8,37 @@
8
8
  * Anchors AC-28101-1.
9
9
  */
10
10
 
11
- import { createObjectStore, endpointFromEnv, credentialsFromShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
11
+ import { createObjectStore, endpointFromEnv, credentialsFromShim, MissingS3EndpointError } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
12
12
  import { secretsShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs';
13
13
 
14
+ export const DECLARED_ENV = Object.freeze(['S3_ENDPOINT_URL']);
15
+
16
+ const AC28101_1 = 'On process boot, the facade opens an S3';
17
+
18
+ function skipRow(variable) {
19
+ return {
20
+ anchorAcId: null,
21
+ verdict: 'pass',
22
+ detail: `${AC28101_1} - accountBound: skipped (${variable} unset)`,
23
+ accountBoundSkipped: true,
24
+ reason: `${variable} unset`,
25
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
26
+ };
27
+ }
28
+
14
29
  export default async function runProbe() {
15
- const { endpoint, bucket, region, forcePathStyle } = endpointFromEnv();
30
+ let endpoint, bucket, region, forcePathStyle;
31
+ try {
32
+ ({ endpoint, bucket, region, forcePathStyle } = endpointFromEnv());
33
+ } catch (err) {
34
+ if (err instanceof MissingS3EndpointError) {
35
+ return { results: [skipRow(err.variable)], extra: { accountBoundSkipped: true, reason: `${err.variable} unset`, envDeclared: [...DECLARED_ENV] } };
36
+ }
37
+ throw err;
38
+ }
16
39
  const credentials = await credentialsFromShim(secretsShim);
17
40
  const events = [];
18
- const store = createObjectStore({
41
+ const store = await createObjectStore({
19
42
  endpointUrl: endpoint,
20
43
  bucket,
21
44
  credentialsRef: credentials,
@@ -28,16 +51,41 @@ export default async function runProbe() {
28
51
  await store.ready();
29
52
  const ready = events.find((e) => e.event === 'facadeReady');
30
53
  const endpointHost = new URL(endpoint).host;
31
- const pass = ready && ready.endpointHost === endpointHost && ready.bucketName === bucket;
54
+ // Drive a HeadBucket call directly through the fixture's SDK
55
+ // client so the row carries a real vendor request id and HTTP
56
+ // status excerpt so the facade-ready and event-secrecy rows
57
+ // each carry per-row vendor evidence.
58
+ let vendorMetadata = null;
59
+ try {
60
+ const { loadSdk } = await import('../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs'); const sdk = await loadSdk();
61
+ const head = await store.getClient().send(new sdk.HeadBucketCommand({ Bucket: bucket }));
62
+ vendorMetadata = head && head.$metadata ? {
63
+ httpStatusCode: head.$metadata.httpStatusCode,
64
+ requestId: head.$metadata.requestId,
65
+ extendedRequestId: head.$metadata.extendedRequestId,
66
+ } : null;
67
+ } catch (err) {
68
+ vendorMetadata = { error: err && err.message, httpStatusCode: err && err.$metadata && err.$metadata.httpStatusCode };
69
+ }
70
+ const pass = ready && ready.endpointHost === endpointHost && ready.bucketName === bucket && vendorMetadata && vendorMetadata.httpStatusCode === 200;
32
71
  results.push({
33
72
  anchorAcId: 'AC-28101-1',
34
73
  verdict: pass ? 'pass' : 'fail',
35
74
  detail: pass
36
- ? `facadeReady fired with endpointHost=${ready.endpointHost} bucketName=${ready.bucketName}`
37
- : `facadeReady did not fire cleanly; events=${JSON.stringify(events)}`,
75
+ ? `${AC28101_1} - facadeReady fired with endpointHost=${ready.endpointHost} bucketName=${ready.bucketName}; HeadBucket returned ${vendorMetadata.httpStatusCode} (requestId=${vendorMetadata.requestId})`
76
+ : `${AC28101_1} - facadeReady did not fire cleanly; ready=${JSON.stringify(ready)} vendorMetadata=${JSON.stringify(vendorMetadata)}`,
77
+ evidence: {
78
+ facadeReadyEvent: ready || null,
79
+ endpointHost,
80
+ bucketName: bucket,
81
+ vendorRequestId: vendorMetadata && vendorMetadata.requestId,
82
+ vendorHttpStatus: vendorMetadata && vendorMetadata.httpStatusCode,
83
+ vendorMetadata,
84
+ allEvents: events,
85
+ },
38
86
  });
39
87
  } finally {
40
88
  await store.close();
41
89
  }
42
- return results;
90
+ return { results, extra: { envDeclared: [...DECLARED_ENV] } };
43
91
  }
@@ -36,17 +36,48 @@
36
36
  import { probeKey } from './probe-utils.mjs';
37
37
 
38
38
  export const accountBound = true;
39
+ export const DECLARED_ENV = Object.freeze([
40
+ 'CI_HAS_HETZNER_OBJECT_STORAGE',
41
+ 'HETZNER_OBJECT_STORAGE_ACCESS_KEY_ID',
42
+ 'HETZNER_OBJECT_STORAGE_SECRET_ACCESS_KEY',
43
+ 'HETZNER_OBJECT_STORAGE_BUCKET',
44
+ 'HETZNER_OBJECT_STORAGE_LOCATION',
45
+ ]);
39
46
 
40
47
  const VENDOR_PATTERN = /^https:\/\/[^./]+\.(fsn1|hel1|nbg1)\.your-objectstorage\.com$/;
41
48
 
42
- export default async function runProbe() {
43
- if (!process.env.CI_HAS_HETZNER_OBJECT_STORAGE) {
44
- return [{
49
+ const AC28110_1 = 'Given the extended infra-s3-and-queue fixture at packages/rcf-lite/test/fixtures/infra-s3-and-queue/ carrying';
50
+ const REQ001 = 'The application accesses object storage through a single';
51
+
52
+ function skipResult(reason) {
53
+ return {
54
+ results: [{
45
55
  anchorAcId: 'AC-28110-1',
46
56
  verdict: 'pass',
47
- detail: 'accountBound: skipped (no CI_HAS_HETZNER_OBJECT_STORAGE)',
57
+ detail: `${AC28110_1} - accountBound: skipped (${reason})`,
48
58
  accountBoundSkipped: true,
49
- }];
59
+ reason,
60
+ evidence: { skip: true, reason, envDeclared: [...DECLARED_ENV] },
61
+ }],
62
+ extra: { accountBoundSkipped: true, reason, envDeclared: [...DECLARED_ENV] },
63
+ };
64
+ }
65
+
66
+ export default async function runProbe() {
67
+ const gate = process.env.CI_HAS_HETZNER_OBJECT_STORAGE;
68
+ if (gate == null || gate === '') {
69
+ return skipResult('CI_HAS_HETZNER_OBJECT_STORAGE unset');
70
+ }
71
+ if (gate !== 'true') {
72
+ return skipResult('CI_HAS_HETZNER_OBJECT_STORAGE (not "true")');
73
+ }
74
+ for (const varName of [
75
+ 'HETZNER_OBJECT_STORAGE_ACCESS_KEY_ID',
76
+ 'HETZNER_OBJECT_STORAGE_SECRET_ACCESS_KEY',
77
+ 'HETZNER_OBJECT_STORAGE_BUCKET',
78
+ 'HETZNER_OBJECT_STORAGE_LOCATION',
79
+ ]) {
80
+ if (!process.env[varName]) return skipResult(`${varName} unset`);
50
81
  }
51
82
 
52
83
  // Dynamic imports so the accountBoundSkipped path above loads
@@ -65,7 +96,8 @@ export default async function runProbe() {
65
96
  return [{
66
97
  anchorAcId: 'AC-28110-1',
67
98
  verdict: 'fail',
68
- detail: 'CI_HAS_HETZNER_OBJECT_STORAGE set but one or more required env vars missing (HETZNER_OBJECT_STORAGE_ACCESS_KEY_ID, HETZNER_OBJECT_STORAGE_SECRET_ACCESS_KEY, HETZNER_OBJECT_STORAGE_BUCKET, HETZNER_OBJECT_STORAGE_LOCATION)',
99
+ detail: `${AC28110_1} - CI_HAS_HETZNER_OBJECT_STORAGE set but one or more required env vars missing (HETZNER_OBJECT_STORAGE_ACCESS_KEY_ID, HETZNER_OBJECT_STORAGE_SECRET_ACCESS_KEY, HETZNER_OBJECT_STORAGE_BUCKET, HETZNER_OBJECT_STORAGE_LOCATION)`,
100
+ evidence: { envSet: false },
69
101
  }];
70
102
  }
71
103
 
@@ -77,19 +109,21 @@ export default async function runProbe() {
77
109
  return [{
78
110
  anchorAcId: 'AC-28110-1',
79
111
  verdict: 'fail',
80
- detail: `endpoint composition threw on field ${err.field || 'unknown'}: ${err.message}`,
112
+ detail: `${AC28110_1} - endpoint composition threw on field ${err.field || 'unknown'}: ${err.message}`,
113
+ evidence: { endpointCompositionError: err && err.message, endpointField: err.field || 'unknown' },
81
114
  }];
82
115
  }
83
116
  if (!VENDOR_PATTERN.test(endpoint)) {
84
117
  return [{
85
118
  anchorAcId: 'AC-28110-1',
86
119
  verdict: 'fail',
87
- detail: `composed endpoint does not match vendor pattern <bucket>.<location>.your-objectstorage.com; got ${endpoint}; missing subdomain: your-objectstorage.com`,
120
+ detail: `${AC28110_1} - composed endpoint does not match vendor pattern <bucket>.<location>.your-objectstorage.com; got ${endpoint}; missing subdomain: your-objectstorage.com`,
121
+ evidence: { composedEndpoint: endpoint, vendorPatternMatched: false },
88
122
  }];
89
123
  }
90
124
 
91
125
  const events = [];
92
- const store = createObjectStore({
126
+ const store = await createObjectStore({
93
127
  endpointUrl: endpoint,
94
128
  bucket,
95
129
  credentialsRef: { accessKeyId, secretAccessKey },
@@ -110,27 +144,77 @@ export default async function runProbe() {
110
144
  const body = Buffer.alloc(1024, 0x48);
111
145
  try {
112
146
  await store.ready();
113
- await store.putObject(key, 'application/octet-stream', body);
147
+ const putRes = await store.putObject(key, 'application/octet-stream', body);
114
148
  const got = await store.getObject(key);
115
149
  const roundTripEqual = got.body.length === 1024 && got.body.equals(body);
116
150
  results.push({
117
151
  anchorAcId: 'AC-28110-1',
118
152
  verdict: roundTripEqual ? 'pass' : 'fail',
119
153
  detail: roundTripEqual
120
- ? `Hetzner Object Storage round-trip byte-equal against ${endpoint} bucket=${bucket} location=${location}`
121
- : `Hetzner Object Storage round-trip failed byte equality; expected 1024 bytes got ${got.body.length}`,
154
+ ? `${AC28110_1} - Hetzner Object Storage round-trip byte-equal against the composed vendor endpoint`
155
+ : `${AC28110_1} - Hetzner Object Storage round-trip failed byte equality; expected 1024 bytes got ${got.body.length}`,
156
+ evidence: {
157
+ vendorRequestId: (putRes && putRes.requestId) || (got && got.requestId) || null,
158
+ eTag: (putRes && putRes.eTag) || (got && got.eTag) || null,
159
+ endpointVendorPatternMatched: true, bucketNamePresent: Boolean(bucket),
160
+ locationCode: location, byteCount: got.body.length,
161
+ },
122
162
  });
163
+ // Event-secrecy limitation: AC-28110-1 states endpoint composition,
164
+ // put/get/delete round-trip, teardown, skip, and malformed-endpoint
165
+ // behavior; it does NOT state event-record secrecy. The shipped AC
166
+ // for event-secrecy is AC-28105-1 (metadata-only lifecycle events),
167
+ // which the object-storage-s3 event-secrecy probe already anchors
168
+ // against the local MinIO engine. This Hetzner-run event assertion
169
+ // is recorded as conformanceOnly so it stops falsely counting
170
+ // toward AC-28110-1.
123
171
  const evAssertion = assertMetadataOnlyEventRecords(events);
124
172
  results.push({
125
- anchorAcId: 'AC-28110-1',
173
+ anchorAcId: null,
174
+ conformanceOnly: true,
175
+ limitation: `AC-28105-1: Given a lifecycle-event spy attached to the sink, when put, get, delete, and presign verbs run against a PII fixture, then every event record on the sink carries only fields from the whitelist {event, key, size, contentType, ttl, ts, endpointHost, bucketName}. Not observed as an anchor on this row: AC-28105-1 is observed against the local MinIO engine in event-secrecy.mjs; the Hetzner probe re-checks the same whitelist against the vendor engine and records the result as conformanceOnly evidence toward AC-28105-1.`,
126
176
  verdict: evAssertion.pass ? 'pass' : 'fail',
127
177
  detail: evAssertion.pass
128
- ? `every lifecycle event carries only whitelisted fields (${[...HETZNER_EVENT_WHITELIST].join(',')})`
129
- : `event-secrecy leak: forbidden fields present ${evAssertion.leaked.join(',')}`,
178
+ ? `conformanceOnly (AC-28105-1) - every Hetzner lifecycle event carries only whitelisted fields (${[...HETZNER_EVENT_WHITELIST].join(',')})`
179
+ : `conformanceOnly (AC-28105-1) - Hetzner event-secrecy leak: forbidden fields present ${evAssertion.leaked.join(',')}`,
180
+ evidence: {
181
+ whitelistedFields: [...HETZNER_EVENT_WHITELIST], leakedFields: evAssertion.leaked || [],
182
+ eventCount: events.length,
183
+ },
130
184
  });
131
185
  } finally {
132
- try { await store.deleteObject(key); } catch { /* teardown best effort */ }
133
- await store.close();
186
+ // Teardown outcomes are recorded on the results per authoring-standard rule
187
+ // 5; a teardown FAILURE fails the verdict.
188
+ const teardown = { deleteObject: null };
189
+ let teardownDeleteRequestId = null;
190
+ try {
191
+ const dRes = await store.deleteObject(key);
192
+ teardownDeleteRequestId = (dRes && dRes.requestId) || null;
193
+ teardown.deleteObject = { key, ok: true, requestId: teardownDeleteRequestId };
194
+ } catch (err) {
195
+ teardown.deleteObject = { key, ok: false, error: err && err.message };
196
+ }
197
+ let facadeCloseError = null;
198
+ try { await store.close(); } catch (err) { facadeCloseError = err && err.message; }
199
+ if (facadeCloseError) {
200
+ results.push({
201
+ anchorReqId: 'object-storage-s3-REQ-001',
202
+ verdict: 'fail',
203
+ detail: `${REQ001} - facade close FAILED on Hetzner teardown: ${facadeCloseError}`,
204
+ evidence: { teardownStep: 'facade close', error: facadeCloseError },
205
+ });
206
+ }
207
+ results.push({
208
+ anchorAcId: 'AC-28110-1',
209
+ verdict: teardown.deleteObject && teardown.deleteObject.ok ? 'pass' : 'fail',
210
+ detail: teardown.deleteObject && teardown.deleteObject.ok
211
+ ? `${AC28110_1} - scratch object ${key} deleted on teardown`
212
+ : `${AC28110_1} - scratch object teardown FAILED: ${JSON.stringify(teardown.deleteObject)}`,
213
+ evidence: {
214
+ vendorRequestId: teardownDeleteRequestId,
215
+ teardown, teardownOk: teardown.deleteObject && teardown.deleteObject.ok,
216
+ },
217
+ });
134
218
  }
135
- return results;
219
+ return { results, extra: { envDeclared: [...DECLARED_ENV] } };
136
220
  }
@@ -1,23 +1,60 @@
1
1
  /**
2
2
  * Multipart upload probe.
3
3
  *
4
- * Puts a 10 MiB payload above the ADR-2903 threshold, asserts multipart
5
- * upload completes, get returns full size, objectPut fires with size
6
- * 10485760. Asserts no in-flight multipart upload remains on the bucket
7
- * after completion.
4
+ * Two positive-evidence branches per user-story-28104:
8
5
  *
9
- * Anchors AC-28104-1, AC-28104-2.
6
+ * 1. Canonical multipart round-trip: puts a 10 MiB payload above the
7
+ * ADR-2903 threshold, asserts multipart upload completes, get
8
+ * returns full 10485760 bytes byte-equal, objectPut fires with
9
+ * size=10485760, and no in-flight multipart upload remains.
10
+ * Anchors AC-28104-1.
11
+ *
12
+ * 2. Abort-on-failure branch: forces SIMULATE_PART_UPLOAD_FAIL on
13
+ * the facade for a second put, asserts the promise rejects, and
14
+ * asserts a follow-up ListMultipartUploads on the failure key
15
+ * returns zero in-flight uploads after the abort branch issues
16
+ * AbortMultipartUpload on the failure key. Records the observed
17
+ * error and the aborted upload id (if any).
18
+ * Anchors AC-28104-2.
19
+ *
20
+ * The abort branch is REQUIRED , the probe sets SIMULATE_PART_UPLOAD
21
+ * _FAIL locally on process.env for the second put (restoring the
22
+ * previous value afterwards) so AC-28104-2 always carries observed
23
+ * behaviour on AC-28104-2, never "path not run".
10
24
  */
11
25
 
12
- import { createObjectStore, endpointFromEnv, credentialsFromShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
26
+ import { createObjectStore, endpointFromEnv, credentialsFromShim, MissingS3EndpointError } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/object-store.mjs';
13
27
  import { secretsShim } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/secrets.mjs';
14
28
  import { probeKey } from './probe-utils.mjs';
15
29
 
30
+ export const DECLARED_ENV = Object.freeze(['S3_ENDPOINT_URL']);
31
+
32
+ const AC28104_FIRST8 = 'Given the elicited multipart threshold at 8 MiB';
33
+
34
+ function skipRow(variable) {
35
+ return {
36
+ anchorAcId: null,
37
+ verdict: 'pass',
38
+ detail: `${AC28104_FIRST8} - accountBound: skipped (${variable} unset)`,
39
+ accountBoundSkipped: true,
40
+ reason: `${variable} unset`,
41
+ evidence: { skip: true, reason: `${variable} unset`, envDeclared: [...DECLARED_ENV] },
42
+ };
43
+ }
44
+
16
45
  export default async function runProbe() {
17
- const { endpoint, bucket, region, forcePathStyle } = endpointFromEnv();
46
+ let endpoint, bucket, region, forcePathStyle;
47
+ try {
48
+ ({ endpoint, bucket, region, forcePathStyle } = endpointFromEnv());
49
+ } catch (err) {
50
+ if (err instanceof MissingS3EndpointError) {
51
+ return { results: [skipRow(err.variable)], extra: { accountBoundSkipped: true, reason: `${err.variable} unset`, envDeclared: [...DECLARED_ENV] } };
52
+ }
53
+ throw err;
54
+ }
18
55
  const credentials = await credentialsFromShim(secretsShim);
19
56
  const events = [];
20
- const store = createObjectStore({
57
+ const store = await createObjectStore({
21
58
  endpointUrl: endpoint,
22
59
  bucket,
23
60
  credentialsRef: credentials,
@@ -29,11 +66,11 @@ export default async function runProbe() {
29
66
  const key = probeKey('probe/multipart');
30
67
  const SIZE = 10 * 1024 * 1024; // 10 MiB
31
68
  const body = Buffer.alloc(SIZE);
32
- // Fill with a stable pattern so byte equality is meaningful
33
69
  for (let i = 0; i < SIZE; i += 1) body[i] = i & 0xff;
34
70
  try {
35
71
  await store.ready();
36
- await store.putObject(key, 'application/octet-stream', body);
72
+ // --- AC-28104-1: canonical multipart round-trip ---
73
+ const putRes = await store.putObject(key, 'application/octet-stream', body);
37
74
  const got = await store.getObject(key);
38
75
  const sizePass = got.body.length === SIZE && got.body.equals(body);
39
76
  const putEvent = events.find((e) => e.event === 'objectPut' && e.key === key);
@@ -42,43 +79,75 @@ export default async function runProbe() {
42
79
  anchorAcId: 'AC-28104-1',
43
80
  verdict: sizePass && eventPass ? 'pass' : 'fail',
44
81
  detail: sizePass && eventPass
45
- ? `10 MiB multipart round-trip byte-equal; objectPut fired with size=${putEvent.size}`
46
- : `sizePass=${sizePass} eventPass=${eventPass} got.size=${got.body.length} put=${JSON.stringify(putEvent)}`,
82
+ ? `Given the elicited multipart threshold at 8 MiB - 10 MiB round-trip byte-equal; objectPut fired with size=${putEvent.size}`
83
+ : `Given the elicited multipart threshold at 8 MiB - sizePass=${sizePass} eventPass=${eventPass} got.size=${got.body.length} put=${JSON.stringify(putEvent)}`,
84
+ evidence: {
85
+ uploadId: (putRes && putRes.uploadId) || null,
86
+ vendorRequestId: (putRes && putRes.requestId) || (got && got.requestId) || null,
87
+ eTag: (putRes && putRes.eTag) || (got && got.eTag) || null,
88
+ bucketName: bucket, key, size: SIZE,
89
+ gotSize: got.body.length, byteEqual: sizePass,
90
+ objectPutEvent: putEvent || null,
91
+ },
47
92
  });
48
- // no in-flight uploads after complete
49
93
  const inflight = await store.listMultipartUploads(key);
94
+ const inflightRequestId = (inflight && inflight.requestId) || null;
50
95
  results.push({
51
96
  anchorAcId: 'AC-28104-1',
52
97
  verdict: inflight.length === 0 ? 'pass' : 'fail',
53
98
  detail: inflight.length === 0
54
- ? 'no in-flight multipart uploads after complete'
55
- : `unexpected in-flight uploads: ${JSON.stringify(inflight)}`,
99
+ ? 'Given the elicited multipart threshold at 8 MiB - no in-flight multipart uploads after complete'
100
+ : `Given the elicited multipart threshold at 8 MiB - unexpected in-flight uploads: ${JSON.stringify(inflight)}`,
101
+ evidence: {
102
+ vendorRequestId: inflightRequestId,
103
+ bucketName: bucket, key,
104
+ inflightCount: inflight.length, inflight: [...inflight],
105
+ },
56
106
  });
57
107
  await store.deleteObject(key);
58
108
 
59
- // Abort-on-failure surface: run a second put with SIMULATE_PART_UPLOAD_FAIL
60
- if (process.env.SIMULATE_PART_UPLOAD_FAIL === 'true') {
61
- const failKey = probeKey('probe/multipart-fail');
62
- let threw = false;
63
- try { await store.putObject(failKey, 'application/octet-stream', body); }
64
- catch { threw = true; }
65
- const failInflight = await store.listMultipartUploads(failKey);
66
- results.push({
67
- anchorAcId: 'AC-28104-2',
68
- verdict: threw && failInflight.length === 0 ? 'pass' : 'fail',
69
- detail: threw && failInflight.length === 0
70
- ? 'part-upload failure propagated and Abort left no in-flight uploads'
71
- : `threw=${threw} inflight=${JSON.stringify(failInflight)}`,
72
- });
73
- } else {
74
- results.push({
75
- anchorAcId: 'AC-28104-2',
76
- verdict: 'pass',
77
- detail: 'abort-on-failure path exercised only when SIMULATE_PART_UPLOAD_FAIL=true; not-run on canonical fixture state',
78
- });
109
+ // --- AC-28104-2: forced abort-on-failure branch ---
110
+ // The probe unconditionally exercises the induced-failure path.
111
+ const before = process.env.SIMULATE_PART_UPLOAD_FAIL;
112
+ process.env.SIMULATE_PART_UPLOAD_FAIL = 'true';
113
+ const failKey = probeKey('probe/multipart-fail');
114
+ let observedError = null;
115
+ let observedUploadId = null;
116
+ let observedAbortError = null;
117
+ try {
118
+ await store.putObject(failKey, 'application/octet-stream', body);
119
+ } catch (err) {
120
+ observedError = { name: err && err.name, message: err && err.message, uploadId: err && err.uploadId };
121
+ observedUploadId = err && err.uploadId;
122
+ observedAbortError = err && err.abortError ? err.abortError : null;
123
+ } finally {
124
+ if (before === undefined) delete process.env.SIMULATE_PART_UPLOAD_FAIL;
125
+ else process.env.SIMULATE_PART_UPLOAD_FAIL = before;
79
126
  }
127
+ const failInflight = await store.listMultipartUploads(failKey);
128
+ const failInflightRequestId = (failInflight && failInflight.requestId) || null;
129
+ const uploadIdPresent = typeof observedUploadId === 'string' && observedUploadId.length > 0;
130
+ const abortSucceeded = observedAbortError === null;
131
+ const abortPass = observedError !== null && failInflight.length === 0 && uploadIdPresent && abortSucceeded;
132
+ results.push({
133
+ anchorAcId: 'AC-28104-2',
134
+ verdict: abortPass ? 'pass' : 'fail',
135
+ detail: abortPass
136
+ ? `Given a simulated part-upload failure mid-multipart (SIMULATE_PART_UPLOAD_FAIL fixture) - propagated (${observedError.name || observedError.message}), aborted upload id=${observedUploadId}, no in-flight uploads for ${failKey}, abort call itself succeeded`
137
+ : `Given a simulated part-upload failure mid-multipart (SIMULATE_PART_UPLOAD_FAIL fixture) - abort-on-failure conditions not all met: errorObserved=${observedError !== null} inflightCount=${failInflight.length} uploadIdPresent=${uploadIdPresent} abortSucceeded=${abortSucceeded}${observedAbortError ? ` abortError=${JSON.stringify(observedAbortError)}` : ''}`,
138
+ evidence: {
139
+ observedUploadId,
140
+ vendorRequestId: failInflightRequestId,
141
+ bucketName: bucket,
142
+ failKey,
143
+ observedError,
144
+ abortError: observedAbortError,
145
+ inflightCountAfter: failInflight.length,
146
+ inflightAfter: [...failInflight],
147
+ },
148
+ });
80
149
  } finally {
81
150
  await store.close();
82
151
  }
83
- return results;
152
+ return { results, extra: { key, size: SIZE, events } };
84
153
  }