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,188 @@
1
+ // Shared helpers for security-auth-clerk probes.
2
+ //
3
+ // Runtime-dependency posture:
4
+ // - Local probes drive shipped-shape checks against the fixture at
5
+ // packages/rcf-lite/test/fixtures/security-auth-clerk/ without
6
+ // contacting Clerk.
7
+ // - real-account-* probes call the Clerk Backend API (base URL
8
+ // https://api.clerk.com/v1, docs verifiedOn 2026-09-11
9
+ // https://clerk.com/docs/reference/backend-api) via fetch. The
10
+ // probe records real request ids (Clerk stamps X-Request-ID and
11
+ // returns object ids like user_..., ses_...) and cleans up the
12
+ // scratch principal in a finally block. Without
13
+ // CI_HAS_CLERK_ACCOUNT the probe records accountBoundSkipped: true
14
+ // naming the missing var per rule 7d.
15
+
16
+ import { mkdir, writeFile } from 'node:fs/promises';
17
+ import { dirname, resolve } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+
20
+ const HERE = dirname(fileURLToPath(import.meta.url));
21
+ export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
22
+ export const SLUG = 'security-auth-clerk';
23
+ export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/security-auth-clerk');
24
+ export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/security-auth-clerk');
25
+
26
+ // Declared env vars (mirror the fixture README table).
27
+ export const DECLARED_ENV = Object.freeze([
28
+ 'CI_HAS_CLERK_ACCOUNT',
29
+ 'CLERK_SECRET_KEY',
30
+ 'CLERK_PUBLISHABLE_KEY',
31
+ 'CLERK_API_BASE_URL',
32
+ 'GITHUB_RUN_ID',
33
+ ]);
34
+
35
+ export const SCRATCH_PRINCIPAL_PREFIX = 'pxe-clerk-';
36
+
37
+ // First-8-words-of-anchor helper. Each result row's `detail` starts
38
+ // with the first eight words of the anchored AC's or REQ's
39
+ // description text. Anchor lookup walks contributions/user-stories/
40
+ // and contributions/requirements/ under the blueprint root and
41
+ // caches the map on first call. Null / unknown / missing anchors
42
+ // yield an empty prefix.
43
+ import { readFileSync as _rf } from 'node:fs';
44
+ import { readdirSync as _rd } from 'node:fs';
45
+ let _anchorMap = null;
46
+ function _loadAnchorMap() {
47
+ const map = new Map();
48
+ const dirs = [
49
+ { dir: resolve(PROJECT_ROOT, 'blueprints', SLUG, 'contributions', 'user-stories'), kind: 'ac' },
50
+ { dir: resolve(PROJECT_ROOT, 'blueprints', SLUG, 'contributions', 'requirements'), kind: 'req' },
51
+ ];
52
+ for (const { dir, kind } of dirs) {
53
+ let entries;
54
+ try { entries = _rd(dir); } catch { continue; }
55
+ for (const name of entries) {
56
+ if (!name.endsWith('.json')) continue;
57
+ let j;
58
+ try { j = JSON.parse(_rf(resolve(dir, name), 'utf8')); } catch { continue; }
59
+ if (kind === 'ac') {
60
+ const usId = j.usId;
61
+ for (const ac of (j.acceptanceCriteria || [])) {
62
+ // AC id in the shipped JSON is like "AC-9101-1"; the
63
+ // anchor form used by probes is "<slug>-AC-9101-1".
64
+ const key = `${SLUG}-${ac.id}`;
65
+ map.set(key, ac.description || '');
66
+ }
67
+ } else {
68
+ const key = j.reqId; // already "<slug>-REQ-###"
69
+ if (key) map.set(key, j.description || j.title || '');
70
+ }
71
+ }
72
+ }
73
+ return map;
74
+ }
75
+ export function first8Words(anchor) {
76
+ if (!anchor) return '';
77
+ if (!_anchorMap) _anchorMap = _loadAnchorMap();
78
+ const txt = _anchorMap.get(anchor) || '';
79
+ if (!txt) return '';
80
+ const words = txt.split(/\s+/).filter(Boolean).slice(0, 8).join(' ');
81
+ return words;
82
+ }
83
+ export function withAnchorPrefix(row) {
84
+ const prefix = first8Words(row.anchorAcId);
85
+ if (!prefix) return row;
86
+ const already = typeof row.detail === 'string' && row.detail.startsWith(prefix);
87
+ if (already) return row;
88
+ const oldDetail = row.detail || '';
89
+ return { ...row, detail: `${prefix} :: ${oldDetail}` };
90
+ }
91
+
92
+ export function aggregate(results) {
93
+ if (!Array.isArray(results) || results.length === 0) return 'fail';
94
+ if (results.some((r) => r.verdict === 'fail')) return 'fail';
95
+ if (results.some((r) => r.verdict === 'warn')) return 'warn';
96
+ return 'pass';
97
+ }
98
+
99
+ export function isSkipped(results) {
100
+ return results.length > 0 && results.every((r) => r.accountBoundSkipped === true);
101
+ }
102
+
103
+ export async function writeReport({ probeName, engine, results, extra }) {
104
+ await mkdir(REPORT_DIR, { recursive: true });
105
+ // Prefix every row's detail with the first eight words of its
106
+ // anchored AC or REQ description; unanchored rows are left alone.
107
+ const prefixedResults = (results || []).map(withAnchorPrefix);
108
+ const raw = aggregate(prefixedResults);
109
+ const aggregateVerdict = isSkipped(prefixedResults) ? 'pass' : raw;
110
+ const report = {
111
+ slug: 'security-auth-clerk',
112
+ probeName,
113
+ runAt: new Date().toISOString(),
114
+ engine,
115
+ results: prefixedResults,
116
+ aggregateVerdict,
117
+ ...(extra ?? {}),
118
+ };
119
+ const path = resolve(REPORT_DIR, `${probeName}.json`);
120
+ await writeFile(path, JSON.stringify(report, null, 2) + '\n', 'utf8');
121
+ return { report, path };
122
+ }
123
+
124
+ export async function runShim(probeName, engine, mainFn) {
125
+ try {
126
+ const outcome = await mainFn();
127
+ if (!outcome || !Array.isArray(outcome.results) || outcome.results.length === 0) {
128
+ const results = [{
129
+ anchorAcId: 'unknown',
130
+ verdict: 'fail',
131
+ detail: 'no checks ran',
132
+ }];
133
+ const { report, path } = await writeReport({ probeName, engine, results });
134
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
135
+ process.stderr.write(`no-checks-ran fail written to ${path}\n`);
136
+ process.exitCode = 1;
137
+ return;
138
+ }
139
+ const { results, extra } = outcome;
140
+ const { report, path } = await writeReport({ probeName, engine, results, extra });
141
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
142
+ process.stdout.write(`report written to ${path}\n`);
143
+ if (report.aggregateVerdict === 'fail') process.exitCode = 1;
144
+ } catch (err) {
145
+ const results = [{
146
+ anchorAcId: 'unknown',
147
+ verdict: 'fail',
148
+ detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
149
+ }];
150
+ const { report, path } = await writeReport({ probeName, engine, results });
151
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
152
+ process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
153
+ process.stderr.write(`report written to ${path}\n`);
154
+ process.exitCode = 1;
155
+ }
156
+ }
157
+
158
+ // De-claim helper. When the shipped AC does not observe what the probe observes, the row keeps its
159
+ // verdict, evidence and engine as they are, but the anchor drops to null and the
160
+ // row carries conformanceOnly:true plus a limitation string naming the AC that
161
+ // this probe does NOT observe and why. The integration-harness follow-up (the auth integration harness follow-up)
162
+ // is the surface where those AC-level properties become observable.
163
+ export function deClaim(row, { ac, limitation }) {
164
+ const acId = ac || 'unknown-AC';
165
+ const limText = (limitation || '').trim();
166
+ const finalLim = /^(security-[a-z0-9-]+-)?(AC|REQ)-/.test(limText) ? limText : (limText ? `${acId}: ${limText}` : `${acId}: not observable at this probe surface; needs the integration harness (the auth integration harness follow-up)`);
167
+ const out = { ...row };
168
+ out.anchorAcId = null;
169
+ if ('anchorReqId' in out) delete out.anchorReqId;
170
+ out.conformanceOnly = true;
171
+ out.limitation = finalLim;
172
+ const tag = ` :: conformance-only (${finalLim})`;
173
+ if (typeof out.detail === 'string' && !out.detail.includes('conformance-only')) {
174
+ out.detail = out.detail + tag;
175
+ }
176
+ return out;
177
+ }
178
+
179
+ export function accountBoundSkippedResult(anchorAcId, capability, reason) {
180
+ return {
181
+ anchorAcId,
182
+ capability,
183
+ verdict: 'pass',
184
+ accountBoundSkipped: true,
185
+ reason,
186
+ detail: `accountBoundSkipped: ${reason} unset; probe did not execute against a real Clerk account. Set the missing var and re-run.`,
187
+ };
188
+ }
@@ -0,0 +1,216 @@
1
+ // Real-account principal-directory smoke for security-auth-clerk.
2
+ //
3
+ // Conformance-only. This probe drives the Clerk Backend API
4
+ // principal-directory (users) surface end to end (create + read +
5
+ // list + delete + list-diff) and records what the Backend API
6
+ // returned. The blueprint's shipped principal-directory acceptance
7
+ // criteria bind runtime sign-in and session semantics on the
8
+ // project's own middleware; a Backend API smoke against
9
+ // api.clerk.com does not observe those runtime properties, so the
10
+ // row is emitted with `anchorAcId: null` and a limitation naming
11
+ // the nearest shipped AC whose property the probe does not
12
+ // observe. Positive evidence per rule 7d is preserved on the row:
13
+ // the Clerk-assigned user_ id, the created-then-deleted resource id
14
+ // in the pre-diff / post-diff inventory pair, and the HTTP status
15
+ // codes. The probe reads the X-Request-Id header from each response
16
+ // and records it on every call, but Clerk's Backend API did not
17
+ // return that header on the instance these records were captured
18
+ // from, so every request-id field is null; the evidence rests on
19
+ // the created id, the inventory-diff pair and the response
20
+ // statuses rather than on request-id capture.
21
+ //
22
+ // Teardown is fail-safe: a mid-run crash leaves the user address
23
+ // deterministic; the finally block always issues DELETE. A
24
+ // teardown failure flips the verdict to FAIL regardless of
25
+ // upstream success.
26
+ //
27
+ // Base URL is https://api.clerk.com/v1 by default; CLERK_API_BASE_URL
28
+ // (declared, optional) may override for local mock testing.
29
+ //
30
+ // Docs: Clerk Backend API https://clerk.com/docs/reference/backend-api
31
+ // verifiedOn 2026-09-11.
32
+ //
33
+ // capability: principalDirectory.
34
+ // accountBound: true.
35
+
36
+ import { DECLARED_ENV, SCRATCH_PRINCIPAL_PREFIX, accountBoundSkippedResult } from './probe-utils.mjs';
37
+
38
+ export const anchorAcId = null;
39
+ export const capability = 'principalDirectory';
40
+ export const accountBound = true;
41
+ // AC-9110-1 states the project runtime does not create, update, or
42
+ // delete users on Clerk. This probe drives the Backend API from a
43
+ // probe process, not the project runtime, so it cannot observe the
44
+ // runtime property AC-9110-1 states; the row records that limit
45
+ // alongside the raw Backend API evidence it did capture.
46
+ const DECLAIM_LIMITATION = 'security-auth-clerk-AC-9110-1: probe drives the Clerk Backend API users surface from a probe process; the AC states the project runtime does not create, update or delete users on Clerk, which requires observing the deployed runtime through the integration harness follow-up.';
47
+
48
+ const BASE_URL_DEFAULT = 'https://api.clerk.com/v1';
49
+
50
+ function shortRandom() {
51
+ return Math.random().toString(36).slice(2, 10);
52
+ }
53
+
54
+ function pickRequestId(headers) {
55
+ return (
56
+ headers.get('x-request-id') ||
57
+ headers.get('cf-request-id') ||
58
+ headers.get('x-clerk-request-id') ||
59
+ null
60
+ );
61
+ }
62
+
63
+ async function clerkFetch({ baseUrl, path, method, body, token }) {
64
+ const url = `${baseUrl}${path}`;
65
+ const init = {
66
+ method,
67
+ headers: {
68
+ Authorization: `Bearer ${token}`,
69
+ Accept: 'application/json',
70
+ },
71
+ };
72
+ if (body !== undefined) {
73
+ init.headers['Content-Type'] = 'application/json';
74
+ init.body = JSON.stringify(body);
75
+ }
76
+ const res = await fetch(url, init);
77
+ const requestId = pickRequestId(res.headers);
78
+ let payload = null;
79
+ const text = await res.text();
80
+ if (text.length > 0) {
81
+ try { payload = JSON.parse(text); } catch { payload = { rawText: text.slice(0, 200) }; }
82
+ }
83
+ return { status: res.status, ok: res.ok, requestId, payload };
84
+ }
85
+
86
+ function gateResult(varName, value) {
87
+ if (value === undefined || value === '') return { kind: 'unset', reason: varName };
88
+ if (value !== 'true') return { kind: 'set-not-true', reason: `${varName}_SET_NOT_TRUE`, observedValue: value };
89
+ return { kind: 'true' };
90
+ }
91
+
92
+ export default async function runProbe() {
93
+ const gate = gateResult('CI_HAS_CLERK_ACCOUNT', process.env.CI_HAS_CLERK_ACCOUNT);
94
+ if (gate.kind === 'unset') {
95
+ return {
96
+ results: [accountBoundSkippedResult(null, capability, 'CI_HAS_CLERK_ACCOUNT')],
97
+ extra: { accountBoundSkipped: true, reason: 'CI_HAS_CLERK_ACCOUNT', envDeclared: [...DECLARED_ENV] },
98
+ };
99
+ }
100
+ if (gate.kind === 'set-not-true') {
101
+ return {
102
+ results: [{
103
+ anchorAcId: null, capability, verdict: 'fail',
104
+ conformanceOnly: true, limitation: DECLAIM_LIMITATION,
105
+ detail: `conformance-only: CI_HAS_CLERK_ACCOUNT is set to "${gate.observedValue}" (not the string "true"). Gate refuses this shape; set the variable to the exact string "true" to run the live branch.`,
106
+ evidence: { gate: 'CI_HAS_CLERK_ACCOUNT', observedValue: gate.observedValue, expected: 'true' },
107
+ }],
108
+ extra: { gateMisconfigured: true, gate: 'CI_HAS_CLERK_ACCOUNT', envDeclared: [...DECLARED_ENV] },
109
+ };
110
+ }
111
+ if (!process.env.CLERK_SECRET_KEY) {
112
+ return {
113
+ results: [accountBoundSkippedResult(null, capability, 'CLERK_SECRET_KEY')],
114
+ extra: { accountBoundSkipped: true, reason: 'CLERK_SECRET_KEY', envDeclared: [...DECLARED_ENV] },
115
+ };
116
+ }
117
+
118
+ const baseUrl = process.env.CLERK_API_BASE_URL || BASE_URL_DEFAULT;
119
+ const token = process.env.CLERK_SECRET_KEY;
120
+ const runId = process.env.GITHUB_RUN_ID || `local-${Date.now()}`;
121
+ const short = shortRandom();
122
+ const emailAddress = `${SCRATCH_PRINCIPAL_PREFIX}${short}+clerk_test@example.com`;
123
+
124
+ const evidence = {
125
+ envDeclared: [...DECLARED_ENV],
126
+ baseUrl,
127
+ scratchEmailAddress: emailAddress,
128
+ runId,
129
+ calls: [],
130
+ };
131
+ const resultRow = { anchorAcId: null, conformanceOnly: true, limitation: DECLAIM_LIMITATION, capability, verdict: 'fail', detail: '', evidence: {} };
132
+ let createdUserId = null;
133
+
134
+ try {
135
+ const created = await clerkFetch({
136
+ baseUrl,
137
+ path: '/users',
138
+ method: 'POST',
139
+ token,
140
+ body: {
141
+ email_address: [emailAddress],
142
+ first_name: 'ProbeUser',
143
+ last_name: short,
144
+ username: `probe_clerk_${short}`,
145
+ skip_password_requirement: true,
146
+ },
147
+ });
148
+ evidence.calls.push({ verb: 'POST /users', status: created.status, requestId: created.requestId, resourceId: created.payload && created.payload.id });
149
+ if (!created.ok || !(created.payload && created.payload.id)) {
150
+ resultRow.detail = `POST /v1/users failed: status=${created.status} requestId=${created.requestId} payloadKeys=${JSON.stringify(Object.keys(created.payload || {}))} bodyExcerpt=${JSON.stringify(created.payload).slice(0, 200)}`;
151
+ return { results: [resultRow], extra: evidence };
152
+ }
153
+ createdUserId = created.payload.id;
154
+ evidence.createdUserId = createdUserId;
155
+
156
+ const readBack = await clerkFetch({ baseUrl, path: `/users/${createdUserId}`, method: 'GET', token });
157
+ evidence.calls.push({ verb: `GET /users/${createdUserId}`, status: readBack.status, requestId: readBack.requestId, resourceId: readBack.payload && readBack.payload.id });
158
+ const readOk = readBack.ok && readBack.payload && readBack.payload.id === createdUserId;
159
+
160
+ const listPre = await clerkFetch({ baseUrl, path: `/users?limit=200&order_by=-created_at`, method: 'GET', token });
161
+ const listedIdsPre = Array.isArray(listPre.payload) ? listPre.payload.map((u) => u.id) : [];
162
+ evidence.calls.push({ verb: 'GET /users?limit=200 (pre-delete)', status: listPre.status, requestId: listPre.requestId, listedCount: listedIdsPre.length, foundScratch: listedIdsPre.includes(createdUserId) });
163
+ const listPreOk = listPre.ok && listedIdsPre.includes(createdUserId);
164
+
165
+ const deleted = await clerkFetch({ baseUrl, path: `/users/${createdUserId}`, method: 'DELETE', token });
166
+ evidence.calls.push({ verb: `DELETE /users/${createdUserId}`, status: deleted.status, requestId: deleted.requestId });
167
+ const deleteOk = deleted.ok;
168
+
169
+ const listPost = await clerkFetch({ baseUrl, path: `/users?limit=200&order_by=-created_at`, method: 'GET', token });
170
+ const listedIdsPost = Array.isArray(listPost.payload) ? listPost.payload.map((u) => u.id) : [];
171
+ evidence.calls.push({ verb: 'GET /users?limit=200 (post-delete)', status: listPost.status, requestId: listPost.requestId, listedCount: listedIdsPost.length, foundScratch: listedIdsPost.includes(createdUserId) });
172
+ const listPostOk = listPost.ok && !listedIdsPost.includes(createdUserId);
173
+
174
+ if (readOk && listPreOk && deleteOk && listPostOk) {
175
+ resultRow.verdict = 'pass';
176
+ resultRow.detail =
177
+ `Clerk Backend API users surface observation: created ${createdUserId} (POST status ${created.status}, requestId ${created.requestId}); ` +
178
+ `readBack GET ${readBack.status} (requestId ${readBack.requestId}); listPre observed ${listedIdsPre.length} users, created id present; ` +
179
+ `DELETE ${deleted.status} (requestId ${deleted.requestId}); listPost observed ${listedIdsPost.length} users, created id absent.`;
180
+ resultRow.evidence = {
181
+ createdUserId,
182
+ createStatus: created.status, createRequestId: created.requestId,
183
+ readBackStatus: readBack.status, readBackRequestId: readBack.requestId,
184
+ listPreCount: listedIdsPre.length, listPreContainsCreated: listPreOk,
185
+ deleteStatus: deleted.status, deleteRequestId: deleted.requestId,
186
+ listPostCount: listedIdsPost.length, listPostAbsence: listPostOk,
187
+ };
188
+ createdUserId = null;
189
+ } else {
190
+ resultRow.evidence = { calls: evidence.calls }; resultRow.detail = `one or more Backend API calls failed: readOk=${readOk} listPreOk=${listPreOk} deleteOk=${deleteOk} listPostOk=${listPostOk}; calls=${JSON.stringify(evidence.calls)}`;
191
+ }
192
+ } catch (err) {
193
+ resultRow.detail = `probe threw: ${err && err.message ? err.message : String(err)}`;
194
+ resultRow.evidence = { threw: err && err.message ? err.message : String(err) };
195
+ evidence.threw = err && err.message ? err.message : String(err);
196
+ } finally {
197
+ if (createdUserId) {
198
+ try {
199
+ const teardown = await clerkFetch({ baseUrl, path: `/users/${createdUserId}`, method: 'DELETE', token });
200
+ evidence.teardownDelete = { status: teardown.status, requestId: teardown.requestId };
201
+ if (!teardown.ok) {
202
+ resultRow.verdict = 'fail';
203
+ resultRow.detail = (resultRow.detail ? resultRow.detail + ' ' : '') +
204
+ `TEARDOWN FAILED leaving orphan user ${createdUserId}: DELETE status=${teardown.status} requestId=${teardown.requestId}. This run is FAIL-WITH-ORPHAN.`;
205
+ evidence.orphanUserId = createdUserId;
206
+ }
207
+ } catch (err) {
208
+ resultRow.verdict = 'fail';
209
+ resultRow.detail = (resultRow.detail ? resultRow.detail + ' ' : '') +
210
+ `TEARDOWN THREW: ${err && err.message ? err.message : String(err)} leaving orphan user ${createdUserId}.`;
211
+ evidence.orphanUserId = createdUserId;
212
+ }
213
+ }
214
+ }
215
+ return { results: [resultRow], extra: evidence };
216
+ }
@@ -0,0 +1,260 @@
1
+ // Real-account sign-in-token surface smoke for security-auth-clerk.
2
+ //
3
+ // Scope of observation. The blueprint's session-inventory ACs bind
4
+ // authenticated browser sessions and inventory operations that
5
+ // Clerk's Backend API cannot author from the server side (Sessions
6
+ // are created by Clerk's Frontend API in a browser flow; the
7
+ // Backend API exposes only list/get/revoke/refresh/verify). This
8
+ // probe therefore does not observe the session-inventory
9
+ // properties AC-9112-1, AC-9112-3, AC-9112-4 or AC-9112-5 name;
10
+ // each row is emitted with `anchorAcId: null` and a limitation
11
+ // citing the nearest shipped session-inventory AC whose runtime
12
+ // property the probe does not observe.
13
+ //
14
+ // What THIS probe drives at the Backend API surface. Create a
15
+ // scratch user; mint a sign-in token for that user with
16
+ // `POST /v1/sign_in_tokens`; capture the returned token id; revoke
17
+ // it with `POST /v1/sign_in_tokens/{id}/revoke`; re-fetch the
18
+ // token to observe the `revoked` status flip (or 404). Delete the
19
+ // user in the finally block. Positive evidence per rule 7d is
20
+ // preserved: the Clerk-assigned token id (created-then-revoked
21
+ // resource id in the token's lifecycle state, shape 3), and the
22
+ // HTTP statuses. The probe reads the X-Request-Id header from each
23
+ // response and records it on every call, but Clerk's Backend API
24
+ // did not return that header on the instance these records were
25
+ // captured from, so every request-id field is null; the evidence
26
+ // rests on the token lifecycle transitions and response statuses
27
+ // rather than on request-id capture.
28
+ //
29
+ // engine: clerk-backend-api (live) or skip:CI_HAS_CLERK_ACCOUNT.
30
+ // accountBound: true.
31
+
32
+ import { DECLARED_ENV, SCRATCH_PRINCIPAL_PREFIX, accountBoundSkippedResult } from './probe-utils.mjs';
33
+
34
+ export const anchorAcId = null;
35
+ export const capability = 'sessionInventory';
36
+ export const accountBound = true;
37
+ const LIM_MINT = 'security-auth-clerk-AC-9112-3: probe drives the Backend API sign-in-token mint from a probe process; the AC binds revokeAllExceptCurrent semantics on the project session-inventory interface, which requires a browser-driven runner (the integration harness follow-up).';
38
+ const LIM_REVOKE = 'security-auth-clerk-AC-9112-4: probe drives the Backend API sign-in-token revoke from a probe process; the AC binds SESSION_INVENTORY_UNAUTHENTICATED refusal at the project inventory operations, which requires a browser-driven runner (the integration harness follow-up).';
39
+ const LIM_NOT_OBS_1 = 'security-auth-clerk-AC-9112-1: two shaped active sessions cannot be authored server-side against the Clerk Backend API; the AC needs a browser-driven runner (the integration harness follow-up).';
40
+ const LIM_NOT_OBS_5 = 'security-auth-clerk-AC-9112-5: revoke against an unowned or already-revoked session id cannot be authored server-side against the Backend API; the AC needs a browser-driven runner (the integration harness follow-up).';
41
+
42
+ const BASE_URL_DEFAULT = 'https://api.clerk.com/v1';
43
+
44
+ function shortRandom() {
45
+ return Math.random().toString(36).slice(2, 10);
46
+ }
47
+
48
+ function pickRequestId(headers) {
49
+ return (
50
+ headers.get('x-request-id') ||
51
+ headers.get('cf-request-id') ||
52
+ headers.get('x-clerk-request-id') ||
53
+ null
54
+ );
55
+ }
56
+
57
+ async function clerkFetch({ baseUrl, path, method, body, form, token }) {
58
+ const url = `${baseUrl}${path}`;
59
+ const init = {
60
+ method,
61
+ headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
62
+ };
63
+ if (body !== undefined) {
64
+ init.headers['Content-Type'] = 'application/json';
65
+ init.body = JSON.stringify(body);
66
+ } else if (form !== undefined) {
67
+ init.headers['Content-Type'] = 'application/x-www-form-urlencoded';
68
+ init.body = form.toString();
69
+ }
70
+ const res = await fetch(url, init);
71
+ const requestId = pickRequestId(res.headers);
72
+ let payload = null;
73
+ const text = await res.text();
74
+ if (text.length > 0) {
75
+ try { payload = JSON.parse(text); } catch { payload = { rawText: text.slice(0, 200) }; }
76
+ }
77
+ return { status: res.status, ok: res.ok, requestId, payload };
78
+ }
79
+
80
+ function gateResult(varName, value) {
81
+ if (value === undefined || value === '') return { kind: 'unset', reason: varName };
82
+ if (value !== 'true') return { kind: 'set-not-true', reason: `${varName}_SET_NOT_TRUE`, observedValue: value };
83
+ return { kind: 'true' };
84
+ }
85
+
86
+ export default async function runProbe() {
87
+ const gate = gateResult('CI_HAS_CLERK_ACCOUNT', process.env.CI_HAS_CLERK_ACCOUNT);
88
+ if (gate.kind === 'unset') {
89
+ return {
90
+ results: [accountBoundSkippedResult(null, capability, 'CI_HAS_CLERK_ACCOUNT')],
91
+ extra: { accountBoundSkipped: true, reason: 'CI_HAS_CLERK_ACCOUNT', envDeclared: [...DECLARED_ENV] },
92
+ };
93
+ }
94
+ if (gate.kind === 'set-not-true') {
95
+ return {
96
+ results: [{
97
+ anchorAcId: null, capability, verdict: 'fail',
98
+ conformanceOnly: true, limitation: LIM_MINT,
99
+ detail: `conformance-only: CI_HAS_CLERK_ACCOUNT is set to "${gate.observedValue}" (not the string "true"). Gate refuses this shape; set the variable to the exact string "true" to run the live branch.`,
100
+ evidence: { gate: 'CI_HAS_CLERK_ACCOUNT', observedValue: gate.observedValue, expected: 'true' },
101
+ }],
102
+ extra: { gateMisconfigured: true, gate: 'CI_HAS_CLERK_ACCOUNT', envDeclared: [...DECLARED_ENV] },
103
+ };
104
+ }
105
+ if (!process.env.CLERK_SECRET_KEY) {
106
+ return {
107
+ results: [accountBoundSkippedResult(null, capability, 'CLERK_SECRET_KEY')],
108
+ extra: { accountBoundSkipped: true, reason: 'CLERK_SECRET_KEY', envDeclared: [...DECLARED_ENV] },
109
+ };
110
+ }
111
+
112
+ const baseUrl = process.env.CLERK_API_BASE_URL || BASE_URL_DEFAULT;
113
+ const token = process.env.CLERK_SECRET_KEY;
114
+ const short = shortRandom();
115
+ const emailAddress = `${SCRATCH_PRINCIPAL_PREFIX}sess-${short}+clerk_test@example.com`;
116
+
117
+ const evidence = { envDeclared: [...DECLARED_ENV], baseUrl, scratchEmailAddress: emailAddress, calls: [] };
118
+ const results = [];
119
+ const rowSignIn = { anchorAcId: null, conformanceOnly: true, limitation: LIM_MINT, capability, verdict: 'fail', detail: '' };
120
+ const rowRevoke = { anchorAcId: null, conformanceOnly: true, limitation: LIM_REVOKE, capability, verdict: 'fail', detail: '' };
121
+ const rowNotObservable1 = {
122
+ anchorAcId: null,
123
+ conformanceOnly: true,
124
+ limitation: LIM_NOT_OBS_1,
125
+ capability,
126
+ verdict: 'pass',
127
+ detail:
128
+ 'AC-9112-1 (two shaped active sessions per Backend API list()) is not observable at the Backend API surface: Clerk creates authenticated sessions via the Frontend API in a browser flow, and the Backend API exposes only list/get/revoke/refresh/verify on Sessions (no server-side session-create). Full AC-9112-1 observation requires a shelf-level browser-driven auth harness, tracked as a separate follow-up.',
129
+ evidence: {
130
+ notObservableACs: ['security-auth-clerk-AC-9112-1'],
131
+ notObservableReason: 'Clerk Backend API cannot create authenticated browser sessions from the server side; observation requires a Frontend-API-driven browser flow.',
132
+ docsUrl: 'https://clerk.com/docs/reference/backend-api',
133
+ docsVerifiedOn: '2026-09-11',
134
+ },
135
+ };
136
+ const rowNotObservable5 = {
137
+ anchorAcId: null,
138
+ conformanceOnly: true,
139
+ limitation: LIM_NOT_OBS_5,
140
+ capability,
141
+ verdict: 'pass',
142
+ detail:
143
+ 'AC-9112-5 (revoke against an unowned or already-revoked session id refuses with SESSION_INVENTORY_UNKNOWN_SESSION and audit event) is not observable at the Backend API surface: the AC is bound to the project session-inventory interface driven from an authenticated caller, and the Backend API cannot create such an authenticated caller server-side. Full AC-9112-5 observation requires a shelf-level browser-driven auth harness, tracked as a separate follow-up.',
144
+ evidence: {
145
+ notObservableACs: ['security-auth-clerk-AC-9112-5'],
146
+ notObservableReason: 'AC-9112-5 binds a project session-inventory refusal that requires an authenticated project caller; the Backend API cannot create one server-side.',
147
+ docsUrl: 'https://clerk.com/docs/reference/backend-api',
148
+ docsVerifiedOn: '2026-09-11',
149
+ },
150
+ };
151
+ let createdUserId = null;
152
+ let createdTokenId = null;
153
+
154
+ try {
155
+ const created = await clerkFetch({
156
+ baseUrl, path: '/users', method: 'POST', token,
157
+ body: {
158
+ email_address: [emailAddress],
159
+ first_name: 'ProbeUser', last_name: short,
160
+ username: `probe_clerk_${short}`,
161
+ skip_password_requirement: true,
162
+ },
163
+ });
164
+ evidence.calls.push({ verb: 'POST /users', status: created.status, requestId: created.requestId, resourceId: created.payload && created.payload.id });
165
+ if (!created.ok || !(created.payload && created.payload.id)) {
166
+ rowSignIn.detail = `precondition POST /v1/users failed status=${created.status} requestId=${created.requestId} bodyExcerpt=${JSON.stringify(created.payload).slice(0, 200)}`;
167
+ rowSignIn.evidence = { call: evidence.calls[evidence.calls.length - 1] };
168
+ rowRevoke.detail = 'skipped: precondition POST /users failed';
169
+ rowRevoke.evidence = { skipped: 'precondition failed' };
170
+ results.push(rowSignIn, rowRevoke, rowNotObservable1, rowNotObservable5);
171
+ return { results, extra: evidence };
172
+ }
173
+ createdUserId = created.payload.id;
174
+ evidence.createdUserId = createdUserId;
175
+
176
+ const mint = await clerkFetch({
177
+ baseUrl, path: '/sign_in_tokens', method: 'POST', token,
178
+ body: { user_id: createdUserId, expires_in_seconds: 300 },
179
+ });
180
+ evidence.calls.push({
181
+ verb: 'POST /sign_in_tokens', status: mint.status, requestId: mint.requestId,
182
+ resourceId: mint.payload && mint.payload.id, status_flag: mint.payload && mint.payload.status,
183
+ });
184
+ const mintOk = mint.ok && mint.payload && typeof mint.payload.id === 'string' && mint.payload.status === 'pending';
185
+ createdTokenId = (mint.payload && mint.payload.id) || null;
186
+ rowSignIn.verdict = mintOk ? 'pass' : 'fail';
187
+ rowSignIn.detail = mintOk
188
+ ? `Clerk Backend API sign-in-token mint observed: POST /v1/sign_in_tokens user_id=${createdUserId} status=${mint.status} requestId=${mint.requestId} tokenId=${createdTokenId} tokenStatus=pending.`
189
+ : `Clerk Backend API sign-in-token mint failed: status=${mint.status} requestId=${mint.requestId} bodyExcerpt=${JSON.stringify(mint.payload).slice(0, 200)}`;
190
+ rowSignIn.evidence = {
191
+ requestId: mint.requestId,
192
+ status: mint.status,
193
+ tokenId: createdTokenId,
194
+ tokenStatus: mint.payload && mint.payload.status,
195
+ createdUserId,
196
+ };
197
+
198
+ if (!createdTokenId) {
199
+ rowRevoke.detail = 'skipped: mint did not return a token id';
200
+ rowRevoke.evidence = { skipped: 'no tokenId' };
201
+ results.push(rowSignIn, rowRevoke, rowNotObservable1, rowNotObservable5);
202
+ return { results, extra: evidence };
203
+ }
204
+
205
+ const revoked = await clerkFetch({
206
+ baseUrl, path: `/sign_in_tokens/${createdTokenId}/revoke`, method: 'POST', token,
207
+ });
208
+ evidence.calls.push({
209
+ verb: `POST /sign_in_tokens/${createdTokenId}/revoke`, status: revoked.status, requestId: revoked.requestId,
210
+ status_flag: revoked.payload && revoked.payload.status,
211
+ });
212
+ const readBack = await clerkFetch({
213
+ baseUrl, path: `/sign_in_tokens/${createdTokenId}`, method: 'GET', token,
214
+ });
215
+ evidence.calls.push({
216
+ verb: `GET /sign_in_tokens/${createdTokenId}`, status: readBack.status, requestId: readBack.requestId,
217
+ status_flag: readBack.payload && readBack.payload.status,
218
+ });
219
+ const revokedFlag = readBack.payload && (readBack.payload.status === 'revoked' || readBack.payload.revoked === true);
220
+ const goneAfterRevoke = revokedFlag || readBack.status === 404 || readBack.status === 410;
221
+ const revokeOk = revoked.ok && goneAfterRevoke;
222
+ rowRevoke.verdict = revokeOk ? 'pass' : 'fail';
223
+ rowRevoke.detail = revokeOk
224
+ ? `Clerk Backend API sign-in-token revoke observed: revoke POST status=${revoked.status} requestId=${revoked.requestId}; re-fetch status=${readBack.status} tokenStatus=${readBack.payload && readBack.payload.status || (readBack.status === 404 ? 'gone-404' : 'unknown')}; the created-then-revoked tokenId (${createdTokenId}) records the Backend API lifecycle transition (404 after revoke means the resource no longer resolves).`
225
+ : `Clerk Backend API sign-in-token revoke failed: revokeStatus=${revoked.status} readBackStatus=${readBack.status} readBackStatusFlag=${readBack.payload && readBack.payload.status}`;
226
+ rowRevoke.evidence = {
227
+ revokeStatus: revoked.status,
228
+ revokeRequestId: revoked.requestId,
229
+ readBackStatus: readBack.status,
230
+ readBackRequestId: readBack.requestId,
231
+ readBackTokenStatus: readBack.payload && readBack.payload.status,
232
+ tokenId: createdTokenId,
233
+ createdThenRevokedTokenId: createdTokenId,
234
+ };
235
+
236
+ results.push(rowSignIn, rowRevoke, rowNotObservable1, rowNotObservable5);
237
+ } catch (err) {
238
+ rowSignIn.detail = `probe threw: ${err && err.message ? err.message : String(err)}`;
239
+ rowSignIn.evidence = { threw: err && err.message ? err.message : String(err) };
240
+ rowRevoke.detail = 'skipped: probe threw before completing';
241
+ rowRevoke.evidence = { skipped: 'threw' };
242
+ results.push(rowSignIn, rowRevoke, rowNotObservable1, rowNotObservable5);
243
+ evidence.threw = err && err.message ? err.message : String(err);
244
+ } finally {
245
+ if (createdUserId) {
246
+ try {
247
+ const teardown = await clerkFetch({ baseUrl, path: `/users/${createdUserId}`, method: 'DELETE', token });
248
+ evidence.teardownDelete = { status: teardown.status, requestId: teardown.requestId };
249
+ if (!teardown.ok) {
250
+ for (const r of results) { r.verdict = 'fail'; r.detail = (r.detail || '') + ` TEARDOWN FAILED leaving orphan user ${createdUserId}: status=${teardown.status} requestId=${teardown.requestId}.`; }
251
+ evidence.orphanUserId = createdUserId;
252
+ }
253
+ } catch (err) {
254
+ for (const r of results) { r.verdict = 'fail'; r.detail = (r.detail || '') + ` TEARDOWN THREW: ${err && err.message ? err.message : String(err)} leaving orphan user ${createdUserId}.`; }
255
+ evidence.orphanUserId = createdUserId;
256
+ }
257
+ }
258
+ }
259
+ return { results, extra: evidence };
260
+ }