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
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Retry-and-fail real-account probe (live-engine coverage).
3
+ *
4
+ * Exercises REAL Cloudflare Queues end-to-end through the vendor's
5
+ * pull-consumer + dead-letter-queue mechanism (per
6
+ * https://developers.cloudflare.com/queues/configuration/pull-consumers/
7
+ * and https://developers.cloudflare.com/queues/configuration/dead-letter-queues/).
8
+ *
9
+ * Flow:
10
+ * 1. Mint a scratch queue (name minted at run time from a probe
11
+ * constant plus a short random suffix; see the code below and
12
+ * the run-notes.md in the evidence tree for the resolved name)
13
+ * and a paired DLQ via the CF REST Queues API.
14
+ * 2. Attach an `http_pull` consumer to the main queue with
15
+ * max_retries=3, dead_letter_queue=<dlq name>, visibility timeout
16
+ * short (2 s) so the observation window stays tight. Attach an
17
+ * `http_pull` consumer to the DLQ so a subsequent pull can
18
+ * positively record DLQ landing.
19
+ * 3. Publish one message.
20
+ * 4. Pull, retry, repeat until the message no longer appears on the
21
+ * primary queue (Cloudflare moved it to the DLQ after
22
+ * max_retries+1 deliveries). Record the observed attempts on each
23
+ * pull.
24
+ * 5. Pull the DLQ and assert the message id landed there.
25
+ * 6. Teardown: delete both queues; confirm each is absent from the
26
+ * account queue listing.
27
+ *
28
+ * Skip on missing account creds: exactly one variable per skip row.
29
+ *
30
+ * Row anchoring:
31
+ * - The account-bound skip row anchors AC-jobs-retryOnHandlerFailure
32
+ * (the shipped retry AC) with `accountBoundSkipped: true` and a
33
+ * `reason` naming the one unset gate variable.
34
+ * - Every non-skip row is CONFORMANCE-ONLY with `anchorAcId: null`
35
+ * and a `limitation` naming the nearest shipped AC id and the
36
+ * property it states that this probe does NOT positively observe:
37
+ * - Provisioning row -> AC-jobs-requiresQueue (states init-time
38
+ * queue requirement; this row records vendor queue creation).
39
+ * - Attempts-counter row -> AC-jobs-retryOnHandlerFailure (states
40
+ * the applied in-memory queue redelivery and three jobStarted
41
+ * events on the sink; this row records Cloudflare Queues'
42
+ * vendor attempts counter, not the sink events).
43
+ * - DLQ landing row -> AC-30109-1 (states DLQ-producer invocation
44
+ * on the in-memory driver; this row records real Cloudflare
45
+ * Queues DLQ landing).
46
+ * - Teardown row -> AC-jobs-requiresQueue (no AC states scratch
47
+ * teardown; this row records DELETE + post-run absence).
48
+ */
49
+
50
+ export const accountBound = true;
51
+ export const DECLARED_ENV = Object.freeze([
52
+ 'CI_HAS_CLOUDFLARE_ACCOUNT',
53
+ 'CF_ACCOUNT_ID',
54
+ 'CF_API_TOKEN',
55
+ 'CF_API_BASE',
56
+ ]);
57
+
58
+ // CF_API_BASE is a required declared variable per the endpoint-hosts rule;
59
+ // no literal endpoint host in probe source. The runProbe() gate checks
60
+ // it before use and returns an exact one-variable skip when unset.
61
+
62
+ const AC_RETRY_FIRST8 = 'With SIMULATE_HANDLER_THROW=true set on the shared sample-app fixture,';
63
+ const AC_REQUIRES_FIRST8 = 'On a fresh init scratch project with NO';
64
+ const AC_PROVISION_LIMITATION = 'AC-jobs-requiresQueue: On a fresh init scratch project with NO messaging-queue provider applied, rcf-lite refuses to apply jobs-background with the stable message id jobs-background-no-queue. Not observed on this row: this row records vendor queue and DLQ provisioning on a real Cloudflare account, which the AC does not state (its property is CLI refusal at init time, not vendor-side queue creation).';
65
+ const AC_ATTEMPTS_LIMITATION = 'AC-jobs-retryOnHandlerFailure: With SIMULATE_HANDLER_THROW=true set on the shared sample-app fixture, the retry-and-fail probe schedules a job whose handler throws a retryable error; the applied in-memory queue redelivers the message per retryPolicy.maxAttempts. Three jobStarted events fire on the sink with the same jobId and attempts counter 1, 2, 3; after the third failure jobFailed fires with a terminal error code and no further re-delivery follows. Not observed on this row: the AC states applied in-memory queue redelivery and jobStarted-on-sink events; this row records the vendor Cloudflare Queues attempts counter across pulls [0,1,2,3], not the jobStarted sink events the AC states.';
66
+ const AC_DLQ_LIMITATION = 'AC-30109-1: The retry-and-fail probe report, after the three failing attempts, records the DLQ-producer invocation on the in-memory driver via a jobDeadLettered event carrying the terminal job id and the original job body. Not observed on this row: the AC pins the in-memory driver DLQ-producer invocation; this row records real Cloudflare Queues DLQ landing (backlog + payload-id match on a real DLQ), which the AC does not state.';
67
+ const AC_TEARDOWN_LIMITATION = 'AC-jobs-requiresQueue: On a fresh init scratch project with NO messaging-queue provider applied, rcf-lite refuses to apply jobs-background with the stable message id jobs-background-no-queue. Not observed on this row: this row records scratch Cloudflare Queues DELETE + post-run absence via the account queue listing, which no jobs-background AC or REQ states; the AC used as a signpost is the nearest shipped AC on queue existence.';
68
+
69
+ function skipRow(reason) {
70
+ return {
71
+ results: [{
72
+ anchorAcId: 'AC-jobs-retryOnHandlerFailure',
73
+ verdict: 'pass',
74
+ detail: `${AC_RETRY_FIRST8} - accountBound: skipped (${reason})`,
75
+ accountBoundSkipped: true,
76
+ reason,
77
+ evidence: { skip: true, reason, envDeclared: [...DECLARED_ENV] },
78
+ }],
79
+ extra: { accountBoundSkipped: true, reason, envDeclared: [...DECLARED_ENV] },
80
+ };
81
+ }
82
+
83
+ async function cf(apiBase, method, path, token, body) {
84
+ const res = await fetch(`${apiBase}${path}`, {
85
+ method,
86
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
87
+ body: body === undefined ? undefined : JSON.stringify(body),
88
+ });
89
+ const text = await res.text();
90
+ let json = null;
91
+ try { json = JSON.parse(text); } catch { /* keep raw */ }
92
+ return { httpStatus: res.status, json, raw: text };
93
+ }
94
+
95
+ function shortId() {
96
+ return Math.random().toString(36).slice(2, 8);
97
+ }
98
+
99
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
100
+
101
+ export default async function runProbe() {
102
+ const gate = process.env.CI_HAS_CLOUDFLARE_ACCOUNT;
103
+ if (gate == null || gate === '') return skipRow('CI_HAS_CLOUDFLARE_ACCOUNT unset');
104
+ if (gate !== 'true') return skipRow('CI_HAS_CLOUDFLARE_ACCOUNT (not "true")');
105
+ if (!process.env.CF_ACCOUNT_ID) return skipRow('CF_ACCOUNT_ID unset');
106
+ if (!process.env.CF_API_TOKEN) return skipRow('CF_API_TOKEN unset');
107
+ if (!process.env.CF_API_BASE) return skipRow('CF_API_BASE unset');
108
+
109
+ const API_BASE = process.env.CF_API_BASE;
110
+ const accountId = process.env.CF_ACCOUNT_ID;
111
+ const token = process.env.CF_API_TOKEN;
112
+ const short = shortId();
113
+ const queueName = `qa-e-jobs-q-${short}`;
114
+ const dlqName = `qa-e-jobs-dlq-${short}`;
115
+ const results = [];
116
+ const teardown = { deletePrimary: null, deleteDlq: null, primaryAbsent: null, dlqAbsent: null };
117
+ let qid = null;
118
+ let dlqId = null;
119
+ try {
120
+ // 1. mint DLQ first, then the main queue (main queue's consumer
121
+ // config references the DLQ by name).
122
+ const dlqCreate = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues`, token, { queue_name: dlqName });
123
+ dlqId = dlqCreate.json && dlqCreate.json.result && dlqCreate.json.result.queue_id;
124
+ if (!dlqId) throw new Error(`DLQ create failed: httpStatus=${dlqCreate.httpStatus} body=${dlqCreate.raw}`);
125
+ const dlqConsumer = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${dlqId}/consumers`, token, {
126
+ type: 'http_pull',
127
+ settings: { batch_size: 10, visibility_timeout_ms: 10000, max_retries: 3, retry_delay: 0 },
128
+ });
129
+ if (!(dlqConsumer.json && dlqConsumer.json.success)) throw new Error(`DLQ consumer attach failed: ${dlqConsumer.raw}`);
130
+
131
+ const primaryCreate = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues`, token, { queue_name: queueName });
132
+ qid = primaryCreate.json && primaryCreate.json.result && primaryCreate.json.result.queue_id;
133
+ if (!qid) throw new Error(`primary create failed: httpStatus=${primaryCreate.httpStatus} body=${primaryCreate.raw}`);
134
+ const primaryConsumer = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${qid}/consumers`, token, {
135
+ type: 'http_pull',
136
+ dead_letter_queue: dlqName,
137
+ settings: { batch_size: 10, visibility_timeout_ms: 2000, max_retries: 3, retry_delay: 0 },
138
+ });
139
+ if (!(primaryConsumer.json && primaryConsumer.json.success)) throw new Error(`primary consumer attach failed: ${primaryConsumer.raw}`);
140
+
141
+ results.push({
142
+ anchorAcId: null,
143
+ conformanceOnly: true,
144
+ limitation: AC_PROVISION_LIMITATION,
145
+ verdict: 'pass',
146
+ detail: `conformanceOnly (${AC_PROVISION_LIMITATION}) - provisioned scratch queue ${queueName} (id=${qid}) with DLQ ${dlqName} (id=${dlqId}), both with http_pull consumers, max_retries=3`,
147
+ evidence: {
148
+ queueName, dlqName,
149
+ primaryConsumerResponseMetadata: primaryConsumer.json && primaryConsumer.json.result,
150
+ dlqConsumerResponseMetadata: dlqConsumer.json && dlqConsumer.json.result,
151
+ },
152
+ });
153
+
154
+ // 3. publish one message
155
+ const publishJobId = `job-${short}`;
156
+ const pubBody = { jobId: publishJobId, jobName: 'send-welcome-email', jobInput: { userId: 7, email: 'ok@example.com' } };
157
+ const pub = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${qid}/messages`, token, { body: pubBody, content_type: 'json' });
158
+ if (!(pub.json && pub.json.success)) throw new Error(`publish failed: ${pub.raw}`);
159
+
160
+ // 4. pull + retry loop; observe attempts increasing to 3, then absent
161
+ const attemptsObserved = [];
162
+ let messageIdObserved = null;
163
+ for (let i = 0; i < 20; i += 1) {
164
+ const pull = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${qid}/messages/pull`, token, {
165
+ batch_size: 10,
166
+ visibility_timeout_ms: 2000,
167
+ });
168
+ const msgs = (pull.json && pull.json.result && pull.json.result.messages) || [];
169
+ if (msgs.length === 0) {
170
+ // Wait a bit; message may have been consumed by the retry cycle
171
+ // and not yet visible again, OR moved to DLQ.
172
+ attemptsObserved.push({ pulled: 0 });
173
+ await sleep(2500);
174
+ continue;
175
+ }
176
+ const m = msgs[0];
177
+ messageIdObserved = m.id;
178
+ attemptsObserved.push({ pulled: msgs.length, attempts: m.attempts, id: m.id });
179
+ // Retry: tell CF to reschedule with retry_delay=0
180
+ const ack = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${qid}/messages/ack`, token, {
181
+ retries: [{ lease_id: m.lease_id, delay_seconds: 0 }],
182
+ });
183
+ if (!(ack.json && ack.json.success)) throw new Error(`ack retry failed: ${ack.raw}`);
184
+ await sleep(500);
185
+ }
186
+ // After the loop, message should be either absent (moved to DLQ) or
187
+ // in the DLQ. Poll the DLQ a few times to allow for the vendor's
188
+ // internal retry-to-DLQ transfer window.
189
+ let dlqMsgs = [];
190
+ let dlqBacklog = 0;
191
+ let dlqPullAttempts = 0;
192
+ for (let dp = 0; dp < 10; dp += 1) {
193
+ await sleep(2000);
194
+ dlqPullAttempts += 1;
195
+ const dlqPull = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${dlqId}/messages/pull`, token, {
196
+ batch_size: 10,
197
+ visibility_timeout_ms: 30000,
198
+ });
199
+ dlqMsgs = (dlqPull.json && dlqPull.json.result && dlqPull.json.result.messages) || [];
200
+ dlqBacklog = (dlqPull.json && dlqPull.json.result && dlqPull.json.result.message_backlog_count) || dlqMsgs.length;
201
+ if (dlqMsgs.length > 0 || dlqBacklog >= 1) break;
202
+ }
203
+ // Cloudflare Queues assigns fresh transport message ids when a
204
+ // message lands in the DLQ, so a strict transport id-match is not
205
+ // achievable at the vendor surface. The probe carries its own
206
+ // application-level correlation id in the message body payload
207
+ // (`publishJobId`) and matches on that: the row is only a pass
208
+ // when the same payload jobId that was published to the primary
209
+ // is observed on the DLQ landing.
210
+ const dlqPayloadIds = dlqMsgs.map((mm) => (mm.body && (typeof mm.body === 'string'
211
+ ? (() => { try { return JSON.parse(mm.body).jobId; } catch { return null; } })()
212
+ : mm.body.jobId))).filter(Boolean);
213
+ const idMatch = dlqPayloadIds.includes(publishJobId);
214
+ const seenInDlq = idMatch; // strict: payload correlation-id match required
215
+ // Ack the DLQ message so it doesn't loiter (deletion also happens
216
+ // in teardown). Ack failures are NOT swallowed - they land on
217
+ // teardown.dlqAcks so a failure surfaces on the teardown row.
218
+ teardown.dlqAcks = [];
219
+ for (const mm of dlqMsgs) {
220
+ try {
221
+ const ack = await cf(API_BASE, 'POST', `/accounts/${accountId}/queues/${dlqId}/messages/ack`, token, {
222
+ acks: [{ lease_id: mm.lease_id }],
223
+ });
224
+ teardown.dlqAcks.push({
225
+ lease_id: mm.lease_id,
226
+ httpStatus: ack.httpStatus,
227
+ success: !!(ack.json && ack.json.success === true),
228
+ });
229
+ } catch (err) {
230
+ teardown.dlqAcks.push({ lease_id: mm.lease_id, ok: false, error: err && err.message });
231
+ }
232
+ }
233
+
234
+ // Assertion 1: observed attempts sequence includes non-zero values
235
+ // (real engine incremented the counter).
236
+ const uniqueAttempts = [...new Set(attemptsObserved.filter((a) => a.attempts != null).map((a) => a.attempts))].sort((a, b) => a - b);
237
+ // REQ-004 states the applied queue redelivers per its own retry
238
+ // contract (Cloudflare Queues ceiling 100 per ADR-3003) and the
239
+ // jobs runtime records the attempt counter on each jobStarted
240
+ // event. With max_retries=3 the vendor's attempts counter must
241
+ // reach exactly the [0..3] consecutive sequence (initial delivery
242
+ // 0 plus three retries 1, 2, 3). A gapped sequence such as [0,2,3]
243
+ // fails the row.
244
+ const expectedAttempts = [0, 1, 2, 3];
245
+ const sawRetries = uniqueAttempts.length === expectedAttempts.length
246
+ && uniqueAttempts.every((v, i) => v === expectedAttempts[i]);
247
+ results.push({
248
+ anchorAcId: null,
249
+ conformanceOnly: true,
250
+ limitation: AC_ATTEMPTS_LIMITATION,
251
+ verdict: sawRetries ? 'pass' : 'fail',
252
+ detail: sawRetries
253
+ ? `conformanceOnly (AC-jobs-retryOnHandlerFailure: With SIMULATE_HANDLER_THROW=true set on the shared sample-app fixture) - Cloudflare Queues incremented the vendor attempts counter across pulls: observed attempts values ${JSON.stringify(uniqueAttempts)}`
254
+ : `conformanceOnly (AC-jobs-retryOnHandlerFailure: With SIMULATE_HANDLER_THROW=true set on the shared sample-app fixture) - did not observe the vendor attempts counter increment across pulls; attemptsObserved=${JSON.stringify(attemptsObserved)}`,
255
+ evidence: { attemptsObserved, uniqueAttempts, messageId: messageIdObserved, queueName },
256
+ });
257
+
258
+ // Assertion 2: message ended up on DLQ (positive dead-letter
259
+ // landing in a real Cloudflare Queue).
260
+ results.push({
261
+ anchorAcId: null,
262
+ conformanceOnly: true,
263
+ limitation: AC_DLQ_LIMITATION,
264
+ verdict: seenInDlq ? 'pass' : 'fail',
265
+ detail: seenInDlq
266
+ ? `conformanceOnly (${AC_DLQ_LIMITATION}) - after ${attemptsObserved.length} primary pulls and ${dlqPullAttempts} DLQ polls the message landed on the DLQ ${dlqName} (backlog=${dlqBacklog}, payload-id-match=true for ${publishJobId})`
267
+ : `conformanceOnly (${AC_DLQ_LIMITATION}) - published payload jobId ${publishJobId} did not appear on the DLQ ${dlqName} within ${dlqPullAttempts} polls; dlqBacklog=${dlqBacklog} observedDlqPayloadIds=${JSON.stringify(dlqPayloadIds)} primary pulls=${attemptsObserved.length}`,
268
+ evidence: { dlqName, dlqId, dlqBacklog, dlqTransportMessageIds: dlqMsgs.map((mm) => mm.id), dlqPayloadJobIds: dlqPayloadIds, expectedPayloadJobId: publishJobId, primaryTransportMessageId: messageIdObserved, payloadIdMatch: idMatch, dlqPollAttempts: dlqPullAttempts },
269
+ });
270
+ } finally {
271
+ // 6. Teardown: delete both queues; confirm absent from listing.
272
+ // A teardown failure FAILS the verdict (authoring-standard rule 5).
273
+ if (qid) {
274
+ try {
275
+ const d = await cf(API_BASE, 'DELETE', `/accounts/${accountId}/queues/${qid}`, token);
276
+ teardown.deletePrimary = { queueId: qid, ok: d.json && d.json.success === true, httpStatus: d.httpStatus };
277
+ } catch (err) {
278
+ teardown.deletePrimary = { queueId: qid, ok: false, error: err && err.message };
279
+ }
280
+ }
281
+ if (dlqId) {
282
+ try {
283
+ const d = await cf(API_BASE, 'DELETE', `/accounts/${accountId}/queues/${dlqId}`, token);
284
+ teardown.deleteDlq = { queueId: dlqId, ok: d.json && d.json.success === true, httpStatus: d.httpStatus };
285
+ } catch (err) {
286
+ teardown.deleteDlq = { queueId: dlqId, ok: false, error: err && err.message };
287
+ }
288
+ }
289
+ // Confirm absence via a queue list. Assert HTTP status 200 AND
290
+ // json.success === true before treating the listing as authoritative;
291
+ // record both on the teardown so an unsuccessful response never
292
+ // normalises to an empty list (absence must be positive evidence).
293
+ // Cloudflare Queues DELETE is asynchronous - the listing can still
294
+ // carry the queue for a few seconds after DELETE 200. Poll the
295
+ // listing up to ~30 s (six 5-second sleeps) before accepting the
296
+ // result as authoritative. The final observed listing (with the
297
+ // number of polls it took) lands on teardown.listing.
298
+ let listingPolls = 0;
299
+ let list = null;
300
+ try {
301
+ for (let i = 0; i < 6; i += 1) {
302
+ listingPolls += 1;
303
+ list = await cf(API_BASE, 'GET', `/accounts/${accountId}/queues`, token);
304
+ const httpOk = list.httpStatus === 200;
305
+ const successFlag = !!(list.json && list.json.success === true);
306
+ if (!httpOk || !successFlag) break;
307
+ const nms = (list.json.result || []).map((q) => q.queue_name);
308
+ if (!nms.includes(queueName) && !nms.includes(dlqName)) break;
309
+ await sleep(5000);
310
+ }
311
+ const httpOk = list && list.httpStatus === 200;
312
+ const successFlag = !!(list && list.json && list.json.success === true);
313
+ const listingOk = httpOk && successFlag;
314
+ const names = listingOk
315
+ ? ((list.json && list.json.result) || []).map((q) => q.queue_name)
316
+ : [];
317
+ teardown.listing = {
318
+ httpStatus: list ? list.httpStatus : null,
319
+ success: successFlag,
320
+ listingOk,
321
+ listedCount: names.length,
322
+ pollsTaken: listingPolls,
323
+ errors: list && list.json && list.json.errors ? list.json.errors : null,
324
+ };
325
+ teardown.primaryAbsent = listingOk
326
+ ? { ok: !names.includes(queueName), listedCount: names.length, httpStatus: list.httpStatus, success: successFlag }
327
+ : { ok: false, listedCount: names.length, httpStatus: list.httpStatus, success: successFlag, note: 'listing unsuccessful; absence cannot be asserted' };
328
+ teardown.dlqAbsent = listingOk
329
+ ? { ok: !names.includes(dlqName), listedCount: names.length, httpStatus: list.httpStatus, success: successFlag }
330
+ : { ok: false, listedCount: names.length, httpStatus: list.httpStatus, success: successFlag, note: 'listing unsuccessful; absence cannot be asserted' };
331
+ } catch (err) {
332
+ teardown.listing = { httpStatus: null, success: false, listingOk: false, error: err && err.message };
333
+ teardown.primaryAbsent = { ok: false, error: err && err.message };
334
+ teardown.dlqAbsent = { ok: false, error: err && err.message };
335
+ }
336
+ const dlqAcksOk = Array.isArray(teardown.dlqAcks)
337
+ && teardown.dlqAcks.every((a) => a.success === true);
338
+ const teardownOk = teardown.deletePrimary && teardown.deletePrimary.ok
339
+ && teardown.deleteDlq && teardown.deleteDlq.ok
340
+ && teardown.primaryAbsent && teardown.primaryAbsent.ok
341
+ && teardown.dlqAbsent && teardown.dlqAbsent.ok
342
+ && dlqAcksOk;
343
+ results.push({
344
+ anchorAcId: null,
345
+ conformanceOnly: true,
346
+ limitation: AC_TEARDOWN_LIMITATION,
347
+ verdict: teardownOk ? 'pass' : 'fail',
348
+ detail: teardownOk
349
+ ? `conformanceOnly (${AC_TEARDOWN_LIMITATION}) - scratch queues ${queueName} and ${dlqName} deleted and confirmed absent from post-run account queue listing`
350
+ : `conformanceOnly (${AC_TEARDOWN_LIMITATION}) - queue teardown FAILED: ${JSON.stringify(teardown)}`,
351
+ evidence: { teardown },
352
+ });
353
+ }
354
+ return { results, extra: { envDeclared: [...DECLARED_ENV], queueName, dlqName, teardown } };
355
+ }
@@ -19,6 +19,8 @@ import { createScheduler, createFakeClock } from '../../../../packages/rcf-lite/
19
19
  import { PROJECT_ROOT } from './probe-utils.mjs';
20
20
  import { resolve } from 'node:path';
21
21
 
22
+ const AC_FIRST8 = 'With SIMULATE_HANDLER_THROW=true set on the shared sample-app fixture,';
23
+
22
24
  export default async function runProbe() {
23
25
  const cfg = queueConfigFromEnv();
24
26
  // maxRetries on the driver matches send-welcome-email.maxAttempts=3.
@@ -54,12 +56,41 @@ export default async function runProbe() {
54
56
  const oneJobId = jobIds.size === 1;
55
57
  const failedOk = !!jobFailed && typeof jobFailed.terminalErrorCode === 'string';
56
58
  const pass = attemptsOk && oneJobId && failedOk;
59
+ const scalarJobId = jobIds.size > 0 ? [...jobIds][0] : null;
57
60
  results.push({
58
61
  anchorAcId: 'AC-jobs-retryOnHandlerFailure',
59
62
  verdict: pass ? 'pass' : 'fail',
60
63
  detail: pass
61
- ? `three jobStarted events attempts=[1,2,3] same jobId; jobFailed carries terminalErrorCode=${jobFailed.terminalErrorCode}`
62
- : `attemptsSeq=${JSON.stringify(attemptsSeq)}; jobIds.size=${jobIds.size}; jobFailed=${JSON.stringify(jobFailed)}`,
64
+ ? `${AC_FIRST8} - three jobStarted events attempts=[1,2,3] same jobId; jobFailed carries terminalErrorCode=${jobFailed.terminalErrorCode}`
65
+ : `${AC_FIRST8} - attemptsSeq=${JSON.stringify(attemptsSeq)}; jobIds.size=${jobIds.size}; jobFailed=${JSON.stringify(jobFailed)}`,
66
+ evidence: {
67
+ jobId: scalarJobId,
68
+ attemptsSequence: attemptsSeq,
69
+ distinctJobIdList: [...jobIds],
70
+ jobStartedCount: jobStartedEvents.length,
71
+ terminalJobFailed: jobFailed || null,
72
+ dlqInvoked,
73
+ },
74
+ });
75
+ // AC-30109-1: after the three failing jobStarted events and the
76
+ // terminal jobFailed event, the underlying in-memory queue driver
77
+ // invoked the DLQ producer path. Observed as `dlqInvoked:true`
78
+ // (state.dlq carries the failing message id after the drain).
79
+ const dlqEntry = pair.state.dlq[0] || null;
80
+ const dlqPass = dlqInvoked === true && failedOk;
81
+ results.push({
82
+ anchorAcId: 'AC-30109-1',
83
+ verdict: dlqPass ? 'pass' : 'fail',
84
+ detail: dlqPass
85
+ ? `The retry-and-fail probe's report, after the three failing jobStarted events and the terminal jobFailed event, records that the in-memory queue driver invoked the DLQ producer path for the failing message id: AC-30109-1 observed with dlqInvoked:true; terminal jobFailed event carries terminalErrorCode=${jobFailed.terminalErrorCode}; the failing message id was routed to state.dlq after maxAttempts exhausted`
86
+ : `The retry-and-fail probe's report, after the three failing jobStarted events and the terminal jobFailed event, did not record dlqInvoked true: AC-30109-1 not observed - dlqInvoked=${dlqInvoked} jobFailed=${JSON.stringify(jobFailed)}`,
87
+ evidence: {
88
+ jobId: scalarJobId,
89
+ dlqInvoked,
90
+ dlqLength: pair.state.dlq.length,
91
+ attemptsSequence: attemptsSeq,
92
+ terminalJobFailed: jobFailed || null,
93
+ },
63
94
  });
64
95
  return { results, extra: { events, dlqInvoked, attemptsSeq } };
65
96
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shim: run retry-and-fail-real-account against the the real-account credentials
3
+ * Cloudflare account. Records real HTTP status + per-pull observations
4
+ * as engine descriptor.
5
+ */
6
+ import runProbe from './retry-and-fail-real-account.mjs';
7
+ import { runShim } from './probe-utils.mjs';
8
+
9
+ const engine = process.env.CI_HAS_CLOUDFLARE_ACCOUNT === 'true'
10
+ ? { kind: 'queue', vendor: 'cloudflare-queues', observed: 'per-request on results' }
11
+ : { kind: 'queue', vendor: 'cloudflare-queues', observed: false, reason: 'CI_HAS_CLOUDFLARE_ACCOUNT unset' };
12
+ runShim('retry-and-fail-real-account', engine, runProbe);
@@ -56,7 +56,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
56
56
  | platform-docker-compose-host | 38101-38899 | 39xx | shipped v1.0.0 | `containerHostContract` |
57
57
  | edge-cloudflare-tunnel | 39101-39899 | 40xx | shipped v1.0.0 | `edgeIngressBridge` |
58
58
 
59
- US 30101-30109 sit at the LOW end of the 30101-30899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a jobs-background REQ id into the number 30110 would collide against a shipped US-30110; band headroom (30110-30899) leaves that space.
59
+ US 30101-30109 sit at the LOW end of the 30101-30899 band on purpose. A project-side story mechanically derived from a jobs-background REQ id into the number 30110 would collide against a shipped US-30110; band headroom (30110-30899) leaves that space.
60
60
 
61
61
  ADR/TAC suffixes for this blueprint use the 3101-3199 block, continuing the shelf pattern.
62
62
 
@@ -144,4 +144,4 @@ What does NOT change:
144
144
 
145
145
  - `observability-logging` (companion): supplies the run-log upstream so the four lifecycle events flow through the applied logger's channel policy.
146
146
  - `application-error-handling` (companion): supplies the error record factory a `jobFailed` constructs on the terminal path.
147
- - `messaging-queue-cloudflare`: the shipped `queue` capability provider today. The `messaging-queue-postgres` sibling (reserved slug per maintainer decision in the documentation) mints on demand and composes here without any change to `jobs-background`.
147
+ - `messaging-queue-cloudflare`: the shipped `queue` capability provider today. The `messaging-queue-postgres` sibling (reserved slug per policy in the documentation) mints on demand and composes here without any change to `jobs-background`.
@@ -1,8 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.3 (positive-evidence patch, 2026-09-10)
4
+
5
+ - `real-account-concurrency-smoke.mjs`: skip results now carry a discrete `reason` field naming the exact unset environment variable or missing account prerequisite. The credential-missing branch (`CF_ACCOUNT_ID` or `CF_API_TOKEN` unset with `CI_HAS_CLOUDFLARE_ACCOUNT=true`) records `accountBoundSkipped: true` naming only the missing variables (never the gate variable that is set on that branch) rather than a bare fail, closing the authoring standard section 7d shape.
6
+ - Adds a live pre-flight observation of the target Cloudflare account's workers.dev subdomain state via `GET /accounts/{id}/workers/subdomain` (verifiedOn 2026-09-10 per https://developers.cloudflare.com/api/resources/workers/subresources/subdomain/methods/get/). A `404` response or an empty `result.subdomain` marks the account as unprovisioned and the probe records `accountBoundSkipped: true` with a reason naming the missing account prerequisite and a detail carrying the observed status and Cloudflare error code as positive evidence. A provisioned subdomain causes the probe to run the mint / drive / teardown sequence unconditionally.
7
+ - Teardown discipline hardened: if `destroyScratchQueueAndWorker` throws, the probe now records an additional `verdict: fail` result naming the potentially orphaned queue id, consumer worker name and telemetry KV id (`teardownFailed: true`, `orphaned: {...}`), so the aggregate verdict fails when live-account state may be dirty rather than passing on a stderr-only note.
8
+ - `GITHUB_RUN_ID` is declared on the probe's `envDeclared` output and on the fixture's "Declared env vars" table (already read by the shim's run-id derivation, previously undeclared).
9
+ - No capability change.
10
+
3
11
  ## 1.1.2 - 2026-09-10
4
12
 
5
- Register cleanup on shipped prose: neutral wording in the README six-probes paragraph, which now describes the probe module envelope directly. Guide `publishBatch` sample updated: the `x-trace-id` example values are now `trace-order-1001` and `trace-order-1002`, and a one-line pointer follows the sample to the owner at `TAC-3001.interfaces[2].description`. Anatomy pin updated to 1.1.2. Chain-consistency lint zero on pass 1 and pass 2. Closes criterion-f finding 1 for messaging-queue-cloudflare; finding 2 was verified as not a defect (the flagged tokens were `x-trace-id` header values in the sample rather than register labels, and the sample now uses order-scoped example values that remove the ambiguity).
13
+ - README six-probes paragraph now describes the probe module envelope directly. Guide `publishBatch` sample updated: the `x-trace-id` example values are `trace-order-1001` and `trace-order-1002`, and a one-line pointer follows the sample to the owner at `TAC-3001.interfaces[2].description`. Anatomy pin updated to 1.1.2.
6
14
 
7
15
  ## 1.1.1 (register-sweep patch, 2026-09-10)
8
16
 
@@ -10,41 +18,39 @@ Register cleanup on shipped prose: neutral wording in the README six-probes para
10
18
 
11
19
  ## 1.1.0 - 2026-09-09
12
20
 
13
- Adds the elicits block (queue-binding-name, queue-name, max-attempts, dead-letter-queue, batch-size, batch-timeout-seconds) that the REQs and guide were already describing in prose. Adds deliveredBy on REQ-002 and REQ-006. Closes chain-contradiction specimens F-2 (retry count off by one: REQ-004 and AC-29104-1 now name maxDeliveries and map to the vendor max_retries as maxDeliveries - 1; new AC-29104-2 asserts the maxDeliveries=1 boundary case), F-3 (REQ-006 and AC-29106-1 standardise on ts as the wall-clock milliseconds-since-epoch field name, aligning with TAC-3001, TAC-3003 and the guide), F-6 (REQ-002 replaces the "idempotent" label with an explicit at-least-once semantics naming ADR-3002 as the ratified delivery decision). Adds disposition to every AC.
21
+ Adds the elicits block (queue-binding-name, queue-name, max-attempts, dead-letter-queue, batch-size, batch-timeout-seconds) that the REQs and guide were already describing in prose. Adds deliveredBy on REQ-002 and REQ-006. REQ-004 and AC-29104-1 name maxDeliveries and map to the vendor max_retries as maxDeliveries - 1, with new AC-29104-2 asserting the maxDeliveries=1 boundary case. REQ-006 and AC-29106-1 standardise on ts as the wall-clock milliseconds-since-epoch field name, aligning with TAC-3001, TAC-3003 and the guide. REQ-002 replaces the "idempotent" label with an explicit at-least-once semantics naming ADR-3002 as the shipped delivery contract. Adds disposition to every AC.
14
22
 
15
23
  # messaging-queue-cloudflare changelog
16
24
 
17
25
  ## 1.0.2 - 2026-09-08
18
26
 
19
- The review-train follow-up (addendum item 6 fixture defect): the real-account queue probe now self-provisions its own throwaway Queue + consumer Worker + telemetry KV namespace, closing the second-tier undeclared-env skip the operator estate hit at the real-account gate on 2026-09-08 (`REAL RUN: PARTIAL`, `MERGE DECISION: HOLD`). No shipped-code capability change.
20
-
21
- - `real-account-concurrency-smoke.mjs` rewritten against a new self-provisioning fixture shim at `packages/rcf-lite/test/fixtures/cf-platform/h2-cf-queue-real-account-shim.mjs`. AC-29108-2 requires a real consumer to process the published messages ("the consumer processes them concurrently up to the documented 250-invocation cap"), so the shim mints a scratch Cloudflare Queue under `h2-cf-probe-integrity-scratch-q-`, a scratch KV namespace for consumer telemetry under `h2-cf-probe-integrity-scratch-kv-tel-`, and a throwaway consumer Worker under `h2-cf-probe-integrity-scratch-w-` bound to the queue (consumer) with `RCF_TEST_QUEUE` (shipped queue producer binding name matching `packages/rcf-lite/test/fixtures/infra-s3-and-queue/wrangler.toml`) + `RCF_TEST_TELEMETRY_KV` bindings. NO workers.dev subdomain is enabled (operator ruling): the consumer is invoked BY THE QUEUE, not over HTTP; the driver publishes via the Cloudflare Queues REST publish endpoint and reads consumer telemetry via the KV REST list + get endpoints. The consumer Worker's source is a plain module (`h2-cf-queue-consumer-worker.mjs`); its `queue()` handler records one telemetry entry per invocation (start / end timestamps + batchSize) to the bound telemetry KV namespace; the driver computes `maxConcurrent` from an interval-overlap analysis on those timestamps.
27
+ Fixture-side fix: the real-account queue probe now self-provisions its own throwaway Queue + consumer Worker + telemetry KV namespace, closing the second-tier undeclared-env skip at the real-account gate. No shipped-code capability change.
28
+ - `real-account-concurrency-smoke.mjs` rewritten against a new self-provisioning fixture shim at `packages/rcf-lite/test/fixtures/cf-platform/h2-cf-queue-real-account-shim.mjs`. AC-29108-2 requires a real consumer to process the published messages ("the consumer processes them concurrently up to the documented 250-invocation cap"), so the shim mints a scratch Cloudflare Queue under `h2-cf-probe-integrity-scratch-q-`, a scratch KV namespace for consumer telemetry under `h2-cf-probe-integrity-scratch-kv-tel-`, and a throwaway consumer Worker under `h2-cf-probe-integrity-scratch-w-` bound to the queue (consumer) with `RCF_TEST_QUEUE` (shipped queue producer binding name matching `packages/rcf-lite/test/fixtures/infra-s3-and-queue/wrangler.toml`) + `RCF_TEST_TELEMETRY_KV` bindings. No workers.dev subdomain is enabled: the consumer is invoked BY THE QUEUE, not over HTTP; the driver publishes via the Cloudflare Queues REST publish endpoint and reads consumer telemetry via the KV REST list + get endpoints. The consumer Worker's source is a plain module (`h2-cf-queue-consumer-worker.mjs`); its `queue()` handler records one telemetry entry per invocation (start / end timestamps + batchSize) to the bound telemetry KV namespace; the driver computes `maxConcurrent` from an interval-overlap analysis on those timestamps.
22
29
  - Declared env for a real-account run is now `CI_HAS_CLOUDFLARE_ACCOUNT` + `CF_ACCOUNT_ID` + `CF_API_TOKEN` (optional `CF_API_BASE_URL` test override; optional `CF_QUEUE_MESSAGE_COUNT` per section 3.5). The `CF_QUEUE_WORKER_URL` and `CF_QUEUE_NAME` second-tier gates are removed; the fixture provides them itself. Every skip-causing env var enumerated in `report.extra.envDeclared` on the probe result and mirrored in the shim's `DECLARED_ENV` export.
23
- - Teardown deletes the consumer Worker first (so the queue has no active consumer at delete time), then the Queue, then the telemetry KV namespace, all by EXACT id / EXACT name against the mint record with three independent prefix guards per resource. `workerDelete` and `queueDelete` are idempotent on 404 (operator ruling items 3+4): a botched-retry teardown treats an already-gone resource as success rather than stranding siblings.
24
- - Separate crash-recovery `sweepOrphans` code path filters over the account by the frozen throwaway prefix constants and deletes each match by exact identity; the sweep is structurally unable to select a non-prefixed name. All account listings paginate to completion (operator ruling item 5): KV namespaces + Queues use the documented `per_page` + `page` loop, Workers scripts use the cursor loop, so `sweepOrphans` is not silently truncated to page one on a busy account. Dedicated sweep-safety test at `packages/rcf-lite/test/fixtures/cf-platform/test/h2-cf-sweep-safety.test.mjs` seeds the mock account with the ten live production Worker script names on the operator account plus mid-string-prefix decoys AND a 250-per-type multi-page cover, and asserts sweep selects zero of them.
25
- - Queue consumer-attach body sends `type: "worker"` (operator ruling item 1: survives CF schema tightening on the discriminated attach union) and omits `dead_letter_queue` entirely rather than sending an explicit `null` (item 2).
30
+ - Teardown deletes the consumer Worker first (so the queue has no active consumer at delete time), then the Queue, then the telemetry KV namespace, all by EXACT id / EXACT name against the mint record with three independent prefix guards per resource. `workerDelete` and `queueDelete` are idempotent on 404: a botched-retry teardown treats an already-gone resource as success rather than stranding siblings.
31
+ - Separate crash-recovery `sweepOrphans` code path filters over the account by the frozen throwaway prefix constants and deletes each match by exact identity; the sweep is structurally unable to select a non-prefixed name. All account listings paginate to completion: KV namespaces + Queues use the documented `per_page` + `page` loop, Workers scripts use the cursor loop, so `sweepOrphans` is not silently truncated to page one on a busy account. Dedicated sweep-safety test at `packages/rcf-lite/test/fixtures/cf-platform/test/h2-cf-sweep-safety.test.mjs` seeds the mock account with the ten live production Worker script names on the operator account plus mid-string-prefix decoys AND a 250-per-type multi-page cover, and asserts sweep selects zero of them.
32
+ - Queue consumer-attach body sends `type: "worker"` (survives CF schema tightening on the discriminated attach union) and omits `dead_letter_queue` entirely rather than sending an explicit `null`.
26
33
  - Local proof harness (`packages/rcf-lite/test/fixtures/cf-platform/test/mock-cf-api-server.mjs`) is a zero-dep in-process mock of the Cloudflare REST contract, not the wire. **The local run exercises OUR lifecycle logic against a mock of Cloudflare's contract; the real-account gate is the only surface that proves the wire format.** The probe is therefore never described as "locally verified" - the local runs are our own lifecycle-logic proof; wire correctness is proven at the operator estate real-account gate.
27
34
 
28
35
  ## 1.0.1 - 2026-09-08
29
36
 
30
- The review-train hardening pass (`h2-cf-platform-probe-integrity`): probe-integrity patch. No capability change.
31
-
37
+ Probe-integrity patch (`h2-cf-platform-probe-integrity`). No capability change.
32
38
  - Replaced the `accountBoundSkipped: true` pass-stub in `real-account-concurrency-smoke.mjs` with a real 500-message concurrency driver against a live Queues binding on a deployed Worker. When `CI_HAS_CLOUDFLARE_ACCOUNT` is set with `CF_QUEUE_WORKER_URL` and `CF_QUEUE_NAME`, the driver publishes 500 messages through the producer facade in 10 concurrent 50-message batches, polls consumer telemetry via `/stats`, and asserts `drained`, `withinCap` and `observedConcurrency > 1` against Cloudflare's documented push-invocation cap (250). The env-absent branch keeps the pass-with-skip shape. Locally proven against `wrangler dev --local` end-to-end (500/500 messages in 583 ms; local queue serialises so the concurrency assertion FAIL tail is the expected local-proof outcome; on real Cloudflare push consumers the assertion passes at the operator estate gate time).
33
- - Re-verified the Cloudflare Queues limits URL (`https://developers.cloudflare.com/queues/platform/limits/`) returns `HTTP/2 200`; recorded in the review-train PR provenance (2026-09-08T13:38:07Z).
39
+ - The Cloudflare Queues limits URL `https://developers.cloudflare.com/queues/platform/limits/` supports the documented push-invocation cap.
34
40
  - Extended the fixture Worker at `packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/worker.mjs` with consumer telemetry and `/publish-batch`, `/stats` and `/reset` endpoints; added `wrangler ^4.0.0` as devDep on the fixture package.
35
41
 
36
42
  ## 1.0.0 - 2026-09-06
37
43
 
38
- Initial release. Directed producer-to-consumer worklist queue on Cloudflare Queues; first shipped adapter with the reserved `messaging-queue-postgres` sibling (maintainer decision) named beside it in the section 6a capability table. Accessed through a producer facade that is the sole reader of the Cloudflare Queues binding (`env.RCF_TEST_QUEUE` in the fixture). Landed via the infra round 5 spec (ratified 2026-09-06) as the queue-adapter track.
44
+ Initial release. Directed producer-to-consumer worklist queue on Cloudflare Queues; first shipped adapter with the reserved `messaging-queue-postgres` sibling (sibling reservation) named beside it in the section 6a capability table. Accessed through a producer facade that is the sole reader of the Cloudflare Queues binding (`env.RCF_TEST_QUEUE` in the fixture).
39
45
 
40
46
  - 21 contributions: 6 REQs on producer facade sole-reader / publish-consume-ack / retry / dead-letter / batch / lifecycle events; 8 USs at 29101-29108; 3 TACs (3001 producer facade, 3002 consumer registration, 3003 event sink); 4 ADRs (3001 adapter Cloudflare Queues shipped, 3002 `deliverySemantics` scope global at-least-once, 3003 max_retries default 3 floor 1 ceiling 100, 3004 batch size default 10 batch timeout default 5 seconds).
41
- - Five Node-only probes under `contributions/probes/` proven against the wrangler-dev-equivalent seam (in-memory queue driver realising the Cloudflare Queues binding shape per SDR-3-a on US-29107): `producer-facade-ready`, `publish-to-delivery`, `retry-and-dlq`, `event-secrecy`, and the accountBound `real-account-concurrency-smoke`. The real-account smoke records `accountBoundSkipped: true` when `CI_HAS_CLOUDFLARE_ACCOUNT` is unset per spec section 3.5.
47
+ - Five Node-only probes under `contributions/probes/` proven against the wrangler-dev-equivalent seam (in-memory queue driver realising the Cloudflare Queues binding shape per the wrangler-dev-equivalent seam decision on US-29107): `producer-facade-ready`, `publish-to-delivery`, `retry-and-dlq`, `event-secrecy`, and the accountBound `real-account-concurrency-smoke`. The real-account smoke records `accountBoundSkipped: true` when `CI_HAS_CLOUDFLARE_ACCOUNT` is unset per spec section 3.5.
42
48
  - The messaging-queue-cloudflare slice of the shared sample-app fixture at `packages/rcf-lite/test/fixtures/infra-s3-and-queue/` adds a `wrangler.toml` declaring the queue binding (`RCF_TEST_QUEUE`), DLQ binding (`RCF_TEST_DLQ`), `dead_letter_queue = "rcf-test-dlq"`, `max_retries = 3`, `max_batch_size = 10`, `max_batch_timeout = 5`; plus `src/queue-driver.mjs`, `src/producer.mjs`, `src/consumer.mjs`, `src/dlq-inspector.mjs`, `src/event-sink.mjs`. Three wired induced-failure switches (`SIMULATE_CONSUMER_RETRY`, `SIMULATE_DLQ_OVERFLOW`, `SIMULATE_PII_IN_BODY`) drive the negative-run paths.
43
- - Declares `capabilities: ["queue"]`, `suggestedCompanions: [{role: "logging"}, {role: "errorHandling"}]`, `providesRoles` absent, `requiresAppliedCapabilities` absent. Composes on `deploy-cloudflare-workers` transitively via the wrangler binding (not through the capability mechanism), so `jobs-background` reads the `queue` capability at apply time via the capability-consumer mechanism from the visual round.
49
+ - Declares `capabilities: ["queue"]`, `suggestedCompanions: [{role: "logging"}, {role: "errorHandling"}]`, `providesRoles` absent, `requiresAppliedCapabilities` absent. Composes on `deploy-cloudflare-workers` transitively via the wrangler binding (not through the capability mechanism), so `jobs-background` reads the `queue` capability at apply time via the capability-consumer mechanism.
44
50
  - Contributes ADR-3002 as `scope: global` on new topic `deliverySemantics`. Future exactly-once, at-most-once or `messaging-queue-postgres` siblings conflict here by design.
45
- - Every ADR contribution entry on `blueprint.json` carries a `standardsTraceClause` per section 8a.2 (mandatory per the operator estate mid-flight ruling after PR #154 gate).
46
- - Extends `packages/rcf-lite/docs/blueprint-authoring.md` section 6a capability-declaration table with one row for `queue` naming the reserved `messaging-queue-postgres` sibling per maintainer decision and spec section 5.6.
47
- - The Miniflare Queues sub-page under the workers testing miniflare storage tree is NOT cited: the ratified round-5 spec's status block records it returning 404 on 2026-09-06. The Cloudflare Queues local-development page (`https://developers.cloudflare.com/queues/configuration/local-development/`) is the sole citation for the local seam.
48
- - Lifecycle event whitelist reuses the object-storage-s3 blueprint's `{event, ts, ...}` common envelope prefix (per PR #157 gate reviewer note 2026-09-06) so a future v1.1 minor can promote one shared shape to schema enforcement.
51
+ - Every ADR contribution entry on `blueprint.json` carries a `standardsTraceClause` per section 8a.2 (mandatory).
52
+ - Extends `packages/rcf-lite/docs/blueprint-authoring.md` section 6a capability-declaration table with one row for `queue` naming the reserved `messaging-queue-postgres` sibling per the sibling reservation in spec section 5.6.
53
+ - The Miniflare Queues sub-page under the workers testing miniflare storage tree is NOT cited (it returns 404). The Cloudflare Queues local-development page (`https://developers.cloudflare.com/queues/configuration/local-development/`) is the sole vendor citation supporting the local seam.
54
+ - Lifecycle event whitelist reuses the object-storage-s3 blueprint's `{event, ts, ...}` common envelope prefix so a future v1.1 minor can promote one shared shape to schema enforcement.
49
55
 
50
- Review-fix (2026-09-09): Adds deliveredBy on REQ-003 and REQ-004. Sweeps vendorCitation onto fixed ACs resting on vendor facts (AC-29107-2, AC-29108-2).
56
+ Adds deliveredBy on REQ-003 and REQ-004. AC-29107-2 and AC-29108-2 carry vendorCitation.
@@ -1,6 +1,6 @@
1
1
  # messaging-queue-cloudflare
2
2
 
3
- A directed producer-to-consumer worklist queue on Cloudflare Queues, accessed through a producer facade that is the sole reader of the Queues binding. Cloudflare Queues is the first adapter (queue binding under wrangler config, consumer registered on the Worker `queue` handler); the reserved `messaging-queue-postgres` sibling (maintainer decision) mints on demand. Ships publish, consume, ack, retry, and DLQ; four lifecycle events (`producerReady`, `messagePublished`, `messageAcked`, `messageDeadLettered`) with a metadata-only field discipline. Composes on `deploy-cloudflare-workers` transitively via the wrangler binding, not through the capability mechanism, so `capabilities: ["queue"]` is what `jobs-background` reads to obtain the producer facade at apply time; no `requiresAppliedCapabilities` block ships at v1.0.0.
3
+ A directed producer-to-consumer worklist queue on Cloudflare Queues, accessed through a producer facade that is the sole reader of the Queues binding. Cloudflare Queues is the first adapter (queue binding under wrangler config, consumer registered on the Worker `queue` handler); the reserved `messaging-queue-postgres` sibling (sibling reservation) mints on demand. Ships publish, consume, ack, retry, and DLQ; four lifecycle events (`producerReady`, `messagePublished`, `messageAcked`, `messageDeadLettered`) with a metadata-only field discipline. Composes on `deploy-cloudflare-workers` transitively via the wrangler binding, not through the capability mechanism, so `capabilities: ["queue"]` is what `jobs-background` reads to obtain the producer facade at apply time; no `requiresAppliedCapabilities` block ships at v1.0.0.
4
4
 
5
5
  ## What this blueprint gives you
6
6
 
@@ -44,11 +44,11 @@ Queue name (or binding name in a Workers deploy); `max_retries` before DLQ (defa
44
44
 
45
45
  ## Composition and conflicts
46
46
 
47
- Composes on `deploy-cloudflare-workers` transitively via the wrangler binding (not through the capability mechanism), so no `requiresAppliedCapabilities` block ships at v1.0.0. Contributes ADR-3002 as `scope: global` on new topic `deliverySemantics`; a future `messaging-queue-postgres` sibling (maintainer decision, deferred v1.0.0 pending demand) or an exactly-once / at-most-once sibling would conflict here by design. `capabilities: ["queue"]`; `providesRoles: []`.
47
+ Composes on `deploy-cloudflare-workers` transitively via the wrangler binding (not through the capability mechanism), so no `requiresAppliedCapabilities` block ships at v1.0.0. Contributes ADR-3002 as `scope: global` on new topic `deliverySemantics`; a future `messaging-queue-postgres` sibling (sibling reservation, deferred v1.0.0 pending demand) or an exactly-once / at-most-once sibling would conflict here by design. `capabilities: ["queue"]`; `providesRoles: []`.
48
48
 
49
49
  ## Reserved sibling
50
50
 
51
- `messaging-queue-postgres` (maintainer decision). Reserved slug beside the `queue` capability row in `packages/rcf-lite/docs/blueprint-authoring.md` section 6a. When demand mints it, the sibling composes on `persistence-data-postgres` as its transport and conflicts by design on `deliverySemantics` with this blueprint; the operator picks one queue backend per project via a project-level ADR.
51
+ `messaging-queue-postgres` (sibling reservation). Reserved slug beside the `queue` capability row in `packages/rcf-lite/docs/blueprint-authoring.md` section 6a. When demand mints it, the sibling composes on `persistence-data-postgres` as its transport and conflicts by design on `deliverySemantics` with this blueprint; the operator picks one queue backend per project via a project-level ADR.
52
52
 
53
53
  ## The six probes
54
54
 
@@ -60,7 +60,7 @@ Each probe is a Node module under `contributions/probes/` exporting the shipped
60
60
  | `publish-to-delivery` | AC-29102-1, AC-29102-2, AC-29105-1, AC-29108-1 | 5 messages round-trip body byte-equal with stable message-ids and producer-supplied trace-ids preserved; per-message ack; wrangler-dev-equivalent seam. | false |
61
61
  | `retry-and-dlq` | AC-29103-1, AC-29104-1 | Consumer returning `retry` observes same stable message-id with attempts 1..max_retries; DLQ landing fires `messageDeadLettered` at `max_retries + 1`; DLQ contents body byte-equal via the DLQ inspector helper. | false |
62
62
  | `event-secrecy` | AC-29106-1 | Every event record carries only the whitelist (event, ts, messageId, queueName, attempts); no PII fixture text on JSON grep. | false |
63
- | `real-account-concurrency-smoke` | AC-29108-2 | Self-provisioning (v1.0.2): the fixture shim (`packages/rcf-lite/test/fixtures/cf-platform/h2-cf-queue-real-account-shim.mjs`) mints a scratch Cloudflare Queue under the CI scratch prefix `h2-cf-probe-integrity-scratch-q-`, a scratch KV namespace for consumer telemetry under `h2-cf-probe-integrity-scratch-kv-tel-`, and a throwaway consumer Worker under `h2-cf-probe-integrity-scratch-w-` bound to the queue (consumer) with `RCF_TEST_QUEUE` (shipped queue binding name) + `RCF_TEST_TELEMETRY_KV` bindings. The Worker has NO fetch surface and NO workers.dev subdomain is enabled (operator ruling): the consumer is invoked BY THE QUEUE, not over HTTP. Driver publishes 500 messages in 10 concurrent 50-message batches via the Cloudflare Queues REST publish endpoint, polls the telemetry KV namespace via the KV REST list + get endpoints until drained, and asserts `totalConsumed === published` and `1 < maxConcurrent <= 250` per https://developers.cloudflare.com/queues/platform/limits/. Teardown deletes Worker, Queue and telemetry KV namespace on exit; the shim's separate `sweepOrphans` path lists over the account with full pagination (operator ruling item 5) and deletes any prefixed residue after a mid-run crash. **The local proof exercises OUR lifecycle logic against a mock of Cloudflare's contract; the real-account gate is the only surface that proves the wire format.** Without `CI_HAS_CLOUDFLARE_ACCOUNT` records `accountBoundSkipped: true`. | true |
63
+ | `real-account-concurrency-smoke` | AC-29108-2 | Self-provisioning (v1.0.2): the fixture shim (`packages/rcf-lite/test/fixtures/cf-platform/h2-cf-queue-real-account-shim.mjs`) mints a scratch Cloudflare Queue under the CI scratch prefix `h2-cf-probe-integrity-scratch-q-`, a scratch KV namespace for consumer telemetry under `h2-cf-probe-integrity-scratch-kv-tel-`, and a throwaway consumer Worker under `h2-cf-probe-integrity-scratch-w-` bound to the queue (consumer) with `RCF_TEST_QUEUE` (shipped queue binding name) + `RCF_TEST_TELEMETRY_KV` bindings. The Worker has no fetch surface and no workers.dev subdomain is enabled: the consumer is invoked BY THE QUEUE, not over HTTP. Driver publishes 500 messages in 10 concurrent 50-message batches via the Cloudflare Queues REST publish endpoint, polls the telemetry KV namespace via the KV REST list + get endpoints until drained, and asserts `totalConsumed === published` and `1 < maxConcurrent <= 250` per https://developers.cloudflare.com/queues/platform/limits/. Teardown deletes Worker, Queue and telemetry KV namespace on exit; the shim's separate `sweepOrphans` path lists over the account with full pagination and deletes any prefixed residue after a mid-run crash. Without `CI_HAS_CLOUDFLARE_ACCOUNT` records `accountBoundSkipped: true`. | true |
64
64
 
65
65
  ## Anatomy
66
66
 
@@ -98,19 +98,19 @@ blueprints/messaging-queue-cloudflare/
98
98
 
99
99
  ## Known limitations and mechanism-reach gaps
100
100
 
101
- The five local probes drive the fixture's in-memory queue-driver (`src/queue-driver.mjs`), which realises the Cloudflare Queues binding shape (`send` / `sendBatch` on the producer side, batch envelope with per-message `ack` / `retry` on the consumer side) so the producer facade module and consumer registration are indistinguishable from a live Queues run at the facade boundary. The wrangler-dev-equivalent seam (SDR-3-a on US-29107) is a deliberate v1.0.0 posture: rcf-lite gains no runtime dependency, CI stays reproducible without a live Cloudflare account, and Cloudflare Queues does not support consumer concurrency under `wrangler dev` per https://developers.cloudflare.com/queues/configuration/local-development/ (that assertion is what `real-account-concurrency-smoke` carries as `accountBound: true`).
101
+ The five local probes drive the fixture's in-memory queue-driver (`src/queue-driver.mjs`), which realises the Cloudflare Queues binding shape (`send` / `sendBatch` on the producer side, batch envelope with per-message `ack` / `retry` on the consumer side) so the producer facade module and consumer registration are indistinguishable from a live Queues run at the facade boundary. The wrangler-dev-equivalent seam (the wrangler-dev-equivalent seam decision on US-29107) is a deliberate v1.0.0 posture: rcf-lite gains no runtime dependency, CI stays reproducible without a live Cloudflare account, and Cloudflare Queues does not support consumer concurrency under `wrangler dev` per https://developers.cloudflare.com/queues/configuration/local-development/ (that assertion is what `real-account-concurrency-smoke` carries as `accountBound: true`).
102
102
 
103
103
  Two live paths are unproven at v1.0.0 and are recorded per AC below so the gate reviewer and any downstream composing blueprint see exactly what is and is not proven for each AC. The gate reviewer's own single `wrangler dev` run and the `accountBound` smoke are what promote these gaps to proven.
104
104
 
105
- - **AC-29101-1** (producer facade opens on boot; `producerReady` fires with `queueName`): proven against the in-memory realisation of the Cloudflare Queues binding shape (probe `producer-facade-ready`, verdict pass); live Queues delivery unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
105
+ - **AC-29101-1** (producer facade opens on boot; `producerReady` fires with `queueName`): proven against the in-memory realisation of the Cloudflare Queues binding shape (probe `producer-facade-ready`, verdict pass); live Queues delivery unproven pending an operator `wrangler dev` run or the accountBound smoke.
106
106
  - **AC-29101-2** (sole-reader grep on the applied fixture): proven against the in-memory realisation (source-tree scan of `src/producer.mjs` against `src/consumer.mjs` peers); live-Queues source-tree posture is identical (the grep target is the fixture tree, not the vendor surface), so this AC has no live-only gap.
107
- - **AC-29102-1** (5 messages round-trip body byte-equal with stable message-id and producer-supplied trace-id): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues delivery of the same 5-message batch unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
108
- - **AC-29102-2** (`messageAcked` fires per successful consumer return; message not redelivered): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues per-message ack behaviour unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
109
- - **AC-29103-1** (retry trajectory: same stable message-id across attempts 1..max_retries with incrementing attempt counter): proven against the in-memory realisation of the binding shape (probe `retry-and-dlq`, verdict pass with attempts 1,2,3 on the same message-id); live Queues retry counter observation unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
110
- - **AC-29104-1** (DLQ landing at `max_retries + 1` with `messageDeadLettered` event and body byte-equal on DLQ inspection): proven against the in-memory realisation of the binding shape (probe `retry-and-dlq`, verdict pass with DLQ landing at attempts=4 and byte-equal body); live Queues DLQ landing via wrangler `dead_letter_queue` field and inspection via `wrangler queues consumer add --dead-letter-queue` unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
111
- - **AC-29105-1** (batch consume: 5 messages in one batch, per-message ack semantics under `max_batch_size = 10`): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues `max_batch_size` / `max_batch_timeout` behaviour on the [[queues.consumers]] block unproven pending a reviewer `wrangler dev` run or the accountBound smoke.
107
+ - **AC-29102-1** (5 messages round-trip body byte-equal with stable message-id and producer-supplied trace-id): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues delivery of the same 5-message batch unproven pending an operator `wrangler dev` run or the accountBound smoke.
108
+ - **AC-29102-2** (`messageAcked` fires per successful consumer return; message not redelivered): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues per-message ack behaviour unproven pending an operator `wrangler dev` run or the accountBound smoke.
109
+ - **AC-29103-1** (retry trajectory: same stable message-id across attempts 1..max_retries with incrementing attempt counter): proven against the in-memory realisation of the binding shape (probe `retry-and-dlq`, verdict pass with attempts 1,2,3 on the same message-id); live Queues retry counter observation unproven pending an operator `wrangler dev` run or the accountBound smoke.
110
+ - **AC-29104-1** (DLQ landing at `max_retries + 1` with `messageDeadLettered` event and body byte-equal on DLQ inspection): proven against the in-memory realisation of the binding shape (probe `retry-and-dlq`, verdict pass with DLQ landing at attempts=4 and byte-equal body); live Queues DLQ landing via wrangler `dead_letter_queue` field and inspection via `wrangler queues consumer add --dead-letter-queue` unproven pending an operator `wrangler dev` run or the accountBound smoke.
111
+ - **AC-29105-1** (batch consume: 5 messages in one batch, per-message ack semantics under `max_batch_size = 10`): proven against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); live Queues `max_batch_size` / `max_batch_timeout` behaviour on the [[queues.consumers]] block unproven pending an operator `wrangler dev` run or the accountBound smoke.
112
112
  - **AC-29106-1** (metadata-only event whitelist; no PII body / header value / consumer context leaks): proven end-to-end against the in-memory realisation (probe `event-secrecy`, verdict pass; the whitelist is code-enforced in `src/event-sink.mjs`, independent of transport); live-Queues run does not change the sink code path, so this AC has no live-only gap.
113
- - **AC-29108-1** (wrangler-dev-equivalent seam round-trip): proven end-to-end against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); a live `wrangler dev` process was not driven in this pass. Rationale: SDR-3-a on US-29107 makes the wrangler-dev-equivalent seam the shipped local seam because Cloudflare Queues does not support consumer concurrency under `wrangler dev` and does not support `wrangler dev --remote` per the local-development doc, so a live-wrangler run adds observability (a real process on port 8787) but does not add facade-contract certainty over the in-memory realisation. The gate reviewer drives one live `wrangler dev` run in their own scratch to close the observability gap.
113
+ - **AC-29108-1** (wrangler-dev-equivalent seam round-trip): proven end-to-end against the in-memory realisation of the binding shape (probe `publish-to-delivery`, verdict pass); a live `wrangler dev` process is not driven by this seam. Rationale: the wrangler-dev-equivalent seam decision on US-29107 makes the wrangler-dev-equivalent seam the shipped local seam because Cloudflare Queues does not support consumer concurrency under `wrangler dev` and does not support `wrangler dev --remote` per the local-development doc, so a live-wrangler run adds observability (a real process on port 8787) but does not add facade-contract certainty over the in-memory realisation. The gate reviewer drives one live `wrangler dev` run to close the observability gap.
114
114
  - **AC-29108-2** (real-account concurrency smoke: 500 messages, consumer concurrency up to 250): as of v1.0.2 the probe SELF-PROVISIONS the throwaway Queue + consumer Worker + telemetry KV namespace under the CI scratch prefixes and requires no hand-provisioned CI infrastructure . Declared env for a live run: `CI_HAS_CLOUDFLARE_ACCOUNT` + `CF_ACCOUNT_ID` + `CF_API_TOKEN`. Without `CI_HAS_CLOUDFLARE_ACCOUNT` the probe records `accountBoundSkipped: true` per spec section 3.5 and the per-blueprint report carries `aggregateVerdict: pass` on the skipped shape. **The local proof harness under `packages/rcf-lite/test/fixtures/cf-platform/test/` is a mock of Cloudflare's REST contract, not the wire; the local runs exercise OUR lifecycle logic against that mock, and the real-account gate is the only surface that proves the wire format.**
115
115
 
116
116
  ## Other limitations (not mechanism-reach gaps)