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,60 @@
1
+ // Magic-link TOKEN entropy shape probe. Conformance-only. Every row
2
+ // records anchorAcId=null with a limitation naming the shipped AC
3
+ // whose route-level token property the fixture-manager sample does
4
+ // not observe. The integration harness follow-up is the surface
5
+ // where the AC-level properties become observable.
6
+ //
7
+ // capability: principalDirectory. engine: fixture. accountBound: false.
8
+
9
+ import { pathToFileURL } from 'node:url';
10
+ import { resolve, dirname } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { deClaim } from './probe-utils.mjs';
13
+
14
+ const HERE = dirname(fileURLToPath(import.meta.url));
15
+ const FIXTURE_SRC = resolve(HERE, '..', '..', '..', '..', 'packages', 'rcf-lite', 'test', 'fixtures', 'security-auth-magic-link', 'src');
16
+
17
+ export const anchorAcId = null;
18
+ export const capability = 'principalDirectory';
19
+ export const accountBound = false;
20
+
21
+ const LIM = 'security-auth-magic-link-AC-3102-1: probe samples fixture-manager tokens for uniqueness and base64url shape at the manager layer; the AC states GET /login/verify consumes each token exactly once, which requires observing the deployed route through the integration harness follow-up.';
22
+
23
+ export default async function runProbe() {
24
+ const { createMagicLinkManager } = await import(pathToFileURL(resolve(FIXTURE_SRC, 'magic-link-manager.mjs')).href);
25
+ const mgr = createMagicLinkManager({ ttlSeconds: 900 });
26
+ const tokens = new Set();
27
+ const N = 1_000;
28
+ const shapeBad = [];
29
+ const jwtShaped = [];
30
+ for (let i = 0; i < N; i++) {
31
+ const { token } = await mgr.issue({ emailAddress: `u${i}@example.com` });
32
+ tokens.add(token);
33
+ if (!/^[A-Za-z0-9_-]+$/.test(token) || token.length < 32) {
34
+ if (shapeBad.length < 3) shapeBad.push({ len: token.length, sample: token.slice(0, 6) });
35
+ }
36
+ if (token.includes('.')) {
37
+ if (jwtShaped.length < 3) jwtShaped.push({ sample: token.slice(0, 12) });
38
+ }
39
+ }
40
+ const results = [];
41
+ results.push(deClaim({
42
+ capability,
43
+ verdict: tokens.size === N ? 'pass' : 'fail',
44
+ detail: `distinct-token sample across ${N} issues: unique=${tokens.size}`,
45
+ evidence: { uniqueCount: tokens.size, requested: N },
46
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM }));
47
+ results.push(deClaim({
48
+ capability,
49
+ verdict: shapeBad.length === 0 ? 'pass' : 'fail',
50
+ detail: `base64url shape sweep at token layer: violations=${JSON.stringify(shapeBad)}`,
51
+ evidence: { shapeBadSample: shapeBad, sampledN: N },
52
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM }));
53
+ results.push(deClaim({
54
+ capability,
55
+ verdict: jwtShaped.length === 0 ? 'pass' : 'fail',
56
+ detail: `JWT-delimiter absence sweep at token layer: violations=${JSON.stringify(jwtShaped)}`,
57
+ evidence: { jwtShapedSample: jwtShaped, sampledN: N },
58
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM }));
59
+ return { results, extra: {} };
60
+ }
@@ -0,0 +1,90 @@
1
+ // Magic-link token issue+verify shape probe. Conformance-only.
2
+ // Every row records anchorAcId=null with a limitation naming the
3
+ // nearest shipped AC whose GET /login/verify runtime property the
4
+ // probe does not observe. The probe drives the fixture manager
5
+ // directly and does not observe the deployed HTTP surface; the
6
+ // integration harness follow-up is where the AC-level properties
7
+ // become observable.
8
+ //
9
+ // capability: principalDirectory. engine: fixture. accountBound: false.
10
+
11
+ import { pathToFileURL } from 'node:url';
12
+ import { resolve, dirname } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { deClaim } from './probe-utils.mjs';
15
+
16
+ const HERE = dirname(fileURLToPath(import.meta.url));
17
+ const FIXTURE_SRC = resolve(HERE, '..', '..', '..', '..', 'packages', 'rcf-lite', 'test', 'fixtures', 'security-auth-magic-link', 'src');
18
+
19
+ export const anchorAcId = null;
20
+ export const capability = 'principalDirectory';
21
+ export const accountBound = false;
22
+
23
+ const LIM_TTL = 'security-auth-magic-link-AC-3102-3: probe checks the config constant on the fixture manager; the AC states the recorded expiresAt is fifteen minutes after the mint clock on issued tokens, which requires observing the deployed manager through the integration harness follow-up.';
24
+ const LIM_ISSUE = 'security-auth-magic-link-AC-3102-1: probe calls the fixture manager.issue directly; the AC states GET /login/verify consumes each token exactly once with no session issued on a second call, which requires observing the deployed route through the integration harness follow-up.';
25
+ const LIM_EMAIL = 'security-auth-magic-link-AC-3102-1: probe calls the fixture manager.verify with a wrong email; the AC states GET /login/verify consumes each token exactly once and returns 401 without a Set-Cookie on refusal, which requires observing the deployed route through the integration harness follow-up.';
26
+ const LIM_HAPPY = 'security-auth-magic-link-AC-3102-1: probe calls the fixture manager.verify happy path; the AC states GET /login/verify issues the session on first use and returns 401 without a Set-Cookie on a second call, which requires observing the deployed route through the integration harness follow-up.';
27
+ const LIM_REPLAY = 'security-auth-magic-link-AC-3102-1: probe calls the fixture manager.verify twice; the AC states GET /login/verify returns 401 with no Set-Cookie on the second call, which requires observing the deployed route through the integration harness follow-up.';
28
+ const LIM_EXPIRED = 'security-auth-magic-link-AC-3102-2: probe calls the fixture manager.verify past expiry; the AC states GET /login/verify returns 401 with no Set-Cookie after the expiry window, which requires observing the deployed route through the integration harness follow-up.';
29
+
30
+ export default async function runProbe() {
31
+ const { createMagicLinkManager } = await import(pathToFileURL(resolve(FIXTURE_SRC, 'magic-link-manager.mjs')).href);
32
+
33
+ const results = [];
34
+ let now = 1_000_000_000_000;
35
+
36
+ const mgrDefault = createMagicLinkManager({ clock: () => now });
37
+ const defaultTtl = typeof mgrDefault.ttlSeconds === 'number' ? mgrDefault.ttlSeconds : mgrDefault.getTtlSeconds && mgrDefault.getTtlSeconds();
38
+ results.push(deClaim({
39
+ capability,
40
+ verdict: defaultTtl === 900 ? 'pass' : 'fail',
41
+ detail: `manager.ttlSeconds default config observation: observed=${defaultTtl}`,
42
+ evidence: { defaultTtlSeconds: defaultTtl, expected: 900 },
43
+ }, { ac: 'security-auth-magic-link-AC-3102-3', limitation: LIM_TTL }));
44
+
45
+ const mgr = createMagicLinkManager({ ttlSeconds: 900, clock: () => now });
46
+
47
+ const issued = await mgr.issue({ emailAddress: 'alice@example.com' });
48
+ results.push(deClaim({
49
+ capability,
50
+ verdict: issued.ok && typeof issued.token === 'string' && issued.token.length >= 32 ? 'pass' : 'fail',
51
+ detail: `manager.issue returned a token: ok=${issued.ok} tokenLen=${issued.token && issued.token.length} expiresAt=${issued.expiresAt}`,
52
+ evidence: { adapterReturn: { ok: issued.ok, tokenLen: issued.token && issued.token.length, expiresAt: issued.expiresAt } },
53
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM_ISSUE }));
54
+
55
+ const wrongEmail = await mgr.verify({ token: issued.token, emailAddress: 'mallory@example.com' });
56
+ results.push(deClaim({
57
+ capability,
58
+ verdict: !wrongEmail.ok && /email does not match/.test(wrongEmail.error) ? 'pass' : 'fail',
59
+ detail: `manager.verify wrong-email refusal: ok=${wrongEmail.ok} error=${JSON.stringify(wrongEmail.error)}`,
60
+ evidence: { adapterReturn: wrongEmail },
61
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM_EMAIL }));
62
+
63
+ const good = await mgr.verify({ token: issued.token, emailAddress: 'alice@example.com' });
64
+ results.push(deClaim({
65
+ capability,
66
+ verdict: good.ok && good.emailAddress === 'alice@example.com' ? 'pass' : 'fail',
67
+ detail: `manager.verify happy path: ok=${good.ok} emailAddress=${good.emailAddress}`,
68
+ evidence: { adapterReturn: good },
69
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM_HAPPY }));
70
+
71
+ const replay = await mgr.verify({ token: issued.token, emailAddress: 'alice@example.com' });
72
+ results.push(deClaim({
73
+ capability,
74
+ verdict: !replay.ok && /already consumed/.test(replay.error) ? 'pass' : 'fail',
75
+ detail: `manager.verify replay refusal: ok=${replay.ok} error=${JSON.stringify(replay.error)}`,
76
+ evidence: { adapterReturn: replay },
77
+ }, { ac: 'security-auth-magic-link-AC-3102-1', limitation: LIM_REPLAY }));
78
+
79
+ const issued2 = await mgr.issue({ emailAddress: 'bob@example.com' });
80
+ now += 901_000;
81
+ const expired = await mgr.verify({ token: issued2.token, emailAddress: 'bob@example.com' });
82
+ results.push(deClaim({
83
+ capability,
84
+ verdict: !expired.ok && /expired/.test(expired.error) ? 'pass' : 'fail',
85
+ detail: `manager.verify past-expiry refusal: ok=${expired.ok} error=${JSON.stringify(expired.error)}`,
86
+ evidence: { adapterReturn: expired, clockAdvancedByMs: 901_000 },
87
+ }, { ac: 'security-auth-magic-link-AC-3102-2', limitation: LIM_EXPIRED }));
88
+
89
+ return { results, extra: {} };
90
+ }
@@ -14,7 +14,7 @@ Rules for new topics (inherited from the application-spa and REST vocabularies,
14
14
 
15
15
  ## Id number bands (registry bootstrap)
16
16
 
17
- AC ids (and therefore US numeric ids, which anchor them) are NOT namespaced by the 0.4.4 schema grammar; the band allocation IS the AC-collision enforcement mechanism. Composing blueprints take a fresh band rather than proposing namespaced AC ids. Band allocation is ratified policy (2026-08-19); this table is the shared registry-bootstrap replicated across every shipped and forthcoming blueprint's `docs/topics.md` until a mechanism-side central registry lands (v1.1 candidate).
17
+ AC ids (and therefore US numeric ids, which anchor them) are NOT namespaced by the 0.4.4 schema grammar; the band allocation IS the AC-collision enforcement mechanism. Composing blueprints take a fresh band rather than proposing namespaced AC ids. Band allocation is policy; this table is the shared registry-bootstrap replicated across every shipped and forthcoming blueprint's `docs/topics.md` until a mechanism-side central registry lands (v1.1 candidate).
18
18
 
19
19
  This table is maintained shelf-wide across every blueprint's `docs/topics.md`. Rows are recorded at ship, never predicted.
20
20
 
@@ -1,8 +1,19 @@
1
1
  # security-auth-oauth2 CHANGELOG
2
2
 
3
- ## 1.3.3
3
+ ## 1.3.6 - 2026-09-11
4
+
5
+ - Criterion-e probe pack refinement: every conformance-only result row now records `anchorAcId: null` alongside a `limitation` that opens with a shipped AC id from the blueprint's user stories (the PKCE length-band row moves from `REQ-002` to `AC-10101-1`). The retained live-branch anchor on `real-account-authorisation-code-flow` (`AC-10110-2`) is unchanged and honest-skips on `CI_HAS_OAUTH2_PROVIDER`; when skipped the row records `engine: oauth2-provider`, not `engine: skip:...`. Detail strings on de-claimed rows describe only what was observed at the fixture-mock surface and no longer claim REQ-002 or an AC as observed end to end. The `real-account-authorisation-code-flow` source header now states plainly that its credential-present branch returns a `NOT IMPLEMENTED` failure record (no live commercial IdP is wired in this estate) rather than describing a real-provider round trip. The anatomy helper enforces conformance-only rows to satisfy `anchorAcId === null`, requires limitations to open with an `AC-<n>-<n>` id that resolves to a shipped acceptance criterion on the blueprint's user stories (REQ-prefixed anchors are refused and fabricated ids are rejected), and does not count pre-delete presence as an absence observation on the inventory-diff shape.
6
+
7
+ ## 1.3.5 - 2026-09-11
8
+
9
+ - Every conformance-only anchor on the criterion-e probe pack is de-claimed to `conformanceOnly` with a limitation naming the shipped AC that is observable only in the integration harness follow-up; the retained live-branch anchor on `real-account-authorisation-code-flow` (`AC-10110-2`) is preserved and honest-skips on `CI_HAS_OAUTH2_PROVIDER`. The mock authorisation server keeps real consumed-code state; `/callback-check` reads that record and callers now observe `preExchange` from the mock's request-order records instead of asserting it as a constant. Fixture README and mock header comment describe the mock as a fixture, not a local engine, and `X-Mock-Request-Id` as a diagnostic side channel rather than a rule 7d shape.
4
10
 
5
- - Closure fix pass (F-4): rewrites the `README.md` shelf-latest line in neutral customer-facing voice with no spec-provenance label.
11
+ ## 1.3.4 - 2026-09-11
12
+
13
+ - Added a criterion-e probe pack (`contributions/probes/`) covering the six declared capabilities via five probes: `pkce-challenge-shape` and `authorisation-code-flow-shape` (authorisationCodeFlow via a local mock RFC 6749 + RFC 7636 server on ports 47400-47449), `provider-adapter-shape` (principalDirectory + credentialSelfService), `session-bridge-shape` (sessionInventory + hostedIdentityUi), and `real-account-authorisation-code-flow` (LIVE; honest-skips on `CI_HAS_OAUTH2_PROVIDER` since this estate has no live commercial IdP). Fixture at `packages/rcf-lite/test/fixtures/security-auth-oauth2/` declares every env var the pack reads; anatomy test at `packages/rcf-lite/test/blueprint/security-auth-oauth2-anatomy.test.js` pins pack shape, fixture manifest completeness and the account-bound skip contract.
14
+ - Iteration on the probe pack labelled every local-mock row `engine: fixture`, adjusted `authorisation-code-flow-shape` so the callback-refusal row observes a consumed authorisation code before any second `/token` request, and settled `aggregate([])` / null-result normalisation to `detail: 'no checks ran'` exactly. `real-account-authorisation-code-flow` honest-skips on `CI_HAS_OAUTH2_PROVIDER`; when skipped the record's `engine.kind` remains `oauth2-provider`. Slug reads AMBER on criterion e.
15
+
16
+ ## 1.3.3
6
17
 
7
18
  ## 1.3.2
8
19
 
@@ -12,10 +23,10 @@
12
23
 
13
24
  - Register: neutral wording in shipped prose (no capability change).
14
25
 
15
- ## 1.3.0 (hardening pass, spec 2026-09-09 section 5.4.2)
26
+ ## 1.3.0 (2026-09-09)
16
27
 
17
- - Adds `REQ-011`/`US-10112` (roleModel: provider-record `roleSources[]`, malformed-claim refusal, enrichPrincipal hook), `REQ-012`/`US-10113` (credentialSelfService: provider-record `accountUrl`, boot-time validation, `getCredentialSelfServiceUrl` helper), `REQ-013`/`US-10114` (sessionInventory: list, revoke-one, revoke-all-except-current, unauthenticated refusal, unknown-session refusal). Extends `TAC-1102` with the `accountUrl` validation responsibility and `TAC-1103` with the roles-population and sessionInventory responsibilities. Adds `deliveredBy` on every `must` requirement and `disposition` on every existing acceptance criterion; adds `ownerRef` on ACs that observe the shared `sessionInventory` interface at owner id `TAC-1003-security-auth-clerk-session-verifier`. Names the `principalDirectory` and `hostedIdentityUi` capabilities on the requirements that carry their runtime clauses. Fixes the pass-1 `OAuth2-only` casing drift on `REQ-008` against `TAC-1102`'s canonical `oauth2-only`. hardening pass (criteria a, b, c on the 2026-09-09 programme).
18
- - Review fix pass (PR #188 findings): adds `authorisationCodeFlow` to `capabilities[]` and names the token verbatim in `REQ-001` with story references (`US-10101` plus refusal siblings), so a machine-readable composition token backs the flow that keycloak now gates on; rewrites `US-10114` `AC-1` to reference the `TAC-1003-security-auth-clerk-session-verifier.interfaces.sessionInventory` `SessionRow` shape rather than restating its fields.
28
+ - Adds `REQ-011`/`US-10112` (roleModel: provider-record `roleSources[]`, malformed-claim refusal, enrichPrincipal hook), `REQ-012`/`US-10113` (credentialSelfService: provider-record `accountUrl`, boot-time validation, `getCredentialSelfServiceUrl` helper), `REQ-013`/`US-10114` (sessionInventory: list, revoke-one, revoke-all-except-current, unauthenticated refusal, unknown-session refusal). Extends `TAC-1102` with the `accountUrl` validation responsibility and `TAC-1103` with the roles-population and sessionInventory responsibilities. Adds `deliveredBy` on every `must` requirement and `disposition` on every existing acceptance criterion; adds `ownerRef` on ACs that observe the shared `sessionInventory` interface at owner id `TAC-1003-security-auth-clerk-session-verifier`. Names the `principalDirectory` and `hostedIdentityUi` capabilities on the requirements that carry their runtime clauses. REQ-008 uses the canonical `oauth2-only` casing that matches `TAC-1102`.
29
+ - Adds `authorisationCodeFlow` to `capabilities[]` and names the token verbatim in `REQ-001` with story references (`US-10101` plus refusal siblings), so a machine-readable composition token backs the flow that keycloak now gates on; rewrites `US-10114` `AC-1` to reference the `TAC-1003-security-auth-clerk-session-verifier.interfaces.sessionInventory` `SessionRow` shape rather than restating its fields.
19
30
 
20
31
  ## 1.2.0 (visual round, spec 2026-09-06 section 5.4.2, operator Q2 default)
21
32
 
@@ -32,9 +32,9 @@ The doc set is contributions (copied into the project tree by `rcf define bluepr
32
32
 
33
33
  ## What it contributes, and what it deliberately does not
34
34
 
35
- Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (ratified decision 5) and no code.
35
+ Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (shipped policy 5) and no code.
36
36
 
37
- No FBS contributions, as a matter of principle (ratified policy 2026-08-19): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the OAuth2 authorisation-code + PKCE flow, the provider-abstraction contract, the CSRF-via-state discipline, the id_token verification path, the session-bridge shape, the refresh-token rotation posture, the sign-out semantics, the multi-provider routing, the accountBound runtime-verify posture); the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
37
+ No FBS contributions, as a matter of principle (policy): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the OAuth2 authorisation-code + PKCE flow, the provider-abstraction contract, the CSRF-via-state discipline, the id_token verification path, the session-bridge shape, the refresh-token rotation posture, the sign-out semantics, the multi-provider routing, the accountBound runtime-verify posture); the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
38
38
 
39
39
  Deliberately not contributed: a specific OAuth2 or OIDC library dependency (Node has several; project chooses); the mock OIDC provider's binary or a full runtime dependency (the blueprint commits the shape a project stands one up against; the tool itself lives on the project); MFA specifics (the IdP owns MFA at the hosted surface; the blueprint delegates); vendor-specific quirks (Google's `hd` claim, GitHub's per-org enforcement, Microsoft's tenant scoping); a specific session store (the session-bridge injects it; in-memory in the reference wiring, table-backed on a persistence-composed project); real IdP client credentials, real tenant identifiers, real callback URLs (placeholders only); a Clerk-webhook consumer (out of scope for OAuth2-generic; the Clerk sibling owns that territory); a Keycloak realm configuration (out of scope; the Keycloak sibling when it ships owns that territory).
40
40
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "slug": "security-auth-oauth2",
3
- "version": "1.3.3",
3
+ "version": "1.3.6",
4
4
  "category": "security",
5
5
  "capabilities": [
6
6
  "principalDirectory",
@@ -198,5 +198,6 @@
198
198
  "kind": "us",
199
199
  "path": "user-stories/security-auth-oauth2-us-10114.json"
200
200
  }
201
- ]
201
+ ],
202
+ "updatedAt": "2026-09-11T15:37:12.000Z"
202
203
  }
@@ -0,0 +1,259 @@
1
+ // Local wire-shape probe for the security-auth-oauth2 authorisation
2
+ // code flow. Boots the fixture's local mock authorisation server
3
+ // (a hand-rolled RFC 6749 / RFC 7636 stub) on a port in the security
4
+ // family's declared 47400-47449 range and drives the full code flow
5
+ // against it end to end. The mock is a fixture, not a live IdP;
6
+ // every row records anchorAcId=null with a limitation naming the
7
+ // shipped AC whose route-level property the fixture-layer
8
+ // observation does not exercise. preExchange is OBSERVED from the
9
+ // mock's requestNo record ordering (callback runs before /token only
10
+ // if the token exchange has not consumed the code yet), not
11
+ // asserted as a constant.
12
+ //
13
+ // capability: authorisationCodeFlow. engine: fixture. accountBound: false.
14
+
15
+ import { pathToFileURL } from 'node:url';
16
+ import { resolve, dirname } from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+ import { randomBytes } from 'node:crypto';
19
+ import { MOCK_PORT_RANGE, deClaim } from './probe-utils.mjs';
20
+
21
+ const HERE = dirname(fileURLToPath(import.meta.url));
22
+ const FIXTURE_SRC = resolve(HERE, '..', '..', '..', '..', 'packages', 'rcf-lite', 'test', 'fixtures', 'security-auth-oauth2', 'src');
23
+
24
+ export const anchorAcId = null;
25
+ export const capability = 'authorisationCodeFlow';
26
+ export const accountBound = false;
27
+
28
+ const LIM_AUTHZ = 'security-auth-oauth2-AC-10101-1: probe calls /authorize on a local mock; the AC states the project sign-in route drives a live IdP through a real browser, needs the integration harness (the auth integration harness follow-up).';
29
+ const LIM_TOKEN = 'security-auth-oauth2-AC-10101-2: probe calls /token on a local mock; the AC states the project session issues on a real IdP exchange, needs the integration harness (the auth integration harness follow-up).';
30
+ const LIM_REPLAY = 'security-auth-oauth2-AC-10102-2: probe observes the mock callback-tier refusing a consumed code; the AC states the project callback controller refuses without issuing a session, needs the integration harness (the auth integration harness follow-up).';
31
+ const LIM_PKCE = 'security-auth-oauth2-AC-10103-2: probe observes the mock /token refusing a tampered verifier; the AC states the project sign-in flow terminates without issuing a session, needs the integration harness (the auth integration harness follow-up).';
32
+
33
+ function pickPort() {
34
+ const override = Number(process.env.OAUTH2_MOCK_PORT);
35
+ if (Number.isFinite(override) && override >= MOCK_PORT_RANGE.min && override <= MOCK_PORT_RANGE.max) return override;
36
+ return MOCK_PORT_RANGE.min + Math.floor(Math.random() * (MOCK_PORT_RANGE.max - MOCK_PORT_RANGE.min + 1));
37
+ }
38
+
39
+ function freshState() {
40
+ return `st_${randomBytes(12).toString('base64url')}`;
41
+ }
42
+
43
+ export default async function runProbe() {
44
+ const { createMockAuthServer, generatePkcePair } = await import(pathToFileURL(resolve(FIXTURE_SRC, 'mock-authorization-server.mjs')).href);
45
+ const port = pickPort();
46
+ const clientId = 'mock-client';
47
+ const redirectUri = 'http://127.0.0.1:47499/callback';
48
+ const server = createMockAuthServer({ port, clientId, redirectUri, oidc: true });
49
+ const evidence = { port, clientId, redirectUri, oidc: true, calls: [], observedStates: [] };
50
+ const results = [];
51
+ let teardownFailed = false;
52
+
53
+ try {
54
+ await server.start();
55
+ const pkce = generatePkcePair();
56
+
57
+ // 1. /authorize
58
+ const state1 = freshState();
59
+ evidence.observedStates.push(state1);
60
+ const authUrl = new URL(`http://127.0.0.1:${port}/authorize`);
61
+ authUrl.searchParams.set('response_type', 'code');
62
+ authUrl.searchParams.set('client_id', clientId);
63
+ authUrl.searchParams.set('redirect_uri', redirectUri);
64
+ authUrl.searchParams.set('code_challenge', pkce.challenge);
65
+ authUrl.searchParams.set('code_challenge_method', 'S256');
66
+ authUrl.searchParams.set('state', state1);
67
+ authUrl.searchParams.set('nonce', `n_${randomBytes(8).toString('base64url')}`);
68
+ const authRes = await fetch(authUrl, { redirect: 'manual' });
69
+ const authRequestId = authRes.headers.get('x-mock-request-id');
70
+ const authText = await authRes.text();
71
+ let authPayload = null; try { authPayload = JSON.parse(authText); } catch {}
72
+ const codeFromRes = authPayload && authPayload.code;
73
+ evidence.calls.push({ verb: 'GET /authorize (1)', status: authRes.status, requestId: authRequestId, resourceId: codeFromRes, state: state1 });
74
+
75
+ if (!(authRes.status === 302 && codeFromRes)) {
76
+ results.push(deClaim({
77
+ capability, verdict: 'fail',
78
+ detail: `/authorize failed: status=${authRes.status} requestId=${authRequestId} bodyExcerpt=${authText.slice(0, 200)}`,
79
+ evidence: { requestId: authRequestId, status: authRes.status, bodyExcerpt: authText.slice(0, 200) },
80
+ }, { ac: 'security-auth-oauth2-AC-10101-1', limitation: LIM_AUTHZ }));
81
+ return { results, extra: evidence };
82
+ }
83
+ results.push(deClaim({
84
+ capability,
85
+ verdict: 'pass',
86
+ detail: `/authorize redirected with S256 code_challenge and distinct state; status=${authRes.status} requestId=${authRequestId} state=${state1}`,
87
+ evidence: { requestId: authRequestId, status: authRes.status, state: state1, codeIssued: codeFromRes, codeChallengeMethod: 'S256' },
88
+ }, { ac: 'security-auth-oauth2-AC-10101-1', limitation: LIM_AUTHZ }));
89
+
90
+ // 2. /callback-check BEFORE any /token exchange , preExchange observed
91
+ // from the mock's consumedCodes record: if the code is not yet in
92
+ // consumedCodes, the callback runs pre-exchange.
93
+ const preCallbackUrl = new URL(`http://127.0.0.1:${port}/callback-check`);
94
+ preCallbackUrl.searchParams.set('code', codeFromRes);
95
+ preCallbackUrl.searchParams.set('state', state1);
96
+ const preCallbackRes = await fetch(preCallbackUrl);
97
+ const preCallbackRequestId = preCallbackRes.headers.get('x-mock-request-id');
98
+ const preCallbackText = await preCallbackRes.text();
99
+ let preCallbackPayload = null; try { preCallbackPayload = JSON.parse(preCallbackText); } catch {}
100
+ const preExchangeObservedTokenCallsAtCallback = server.tokenCallCount;
101
+ evidence.calls.push({
102
+ verb: 'GET /callback-check (pre-token, fresh code)',
103
+ status: preCallbackRes.status, requestId: preCallbackRequestId,
104
+ body: preCallbackPayload,
105
+ observedTokenCallsAtThisPoint: preExchangeObservedTokenCallsAtCallback,
106
+ });
107
+
108
+ // 3. /token
109
+ const tokenBody = new URLSearchParams({
110
+ grant_type: 'authorization_code',
111
+ code: codeFromRes,
112
+ redirect_uri: redirectUri,
113
+ client_id: clientId,
114
+ code_verifier: pkce.verifier,
115
+ });
116
+ const tokenRes = await fetch(`http://127.0.0.1:${port}/token`, {
117
+ method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: tokenBody.toString(),
118
+ });
119
+ const tokenRequestId = tokenRes.headers.get('x-mock-request-id');
120
+ const tokenText = await tokenRes.text();
121
+ let tokenPayload = null; try { tokenPayload = JSON.parse(tokenText); } catch {}
122
+ const idTokenShape = tokenPayload && typeof tokenPayload.id_token === 'string'
123
+ && tokenPayload.id_token.split('.').length === 3;
124
+ evidence.calls.push({
125
+ verb: 'POST /token (valid, OIDC)',
126
+ status: tokenRes.status,
127
+ requestId: tokenRequestId,
128
+ accessTokenPresent: Boolean(tokenPayload && tokenPayload.access_token),
129
+ idTokenPresent: Boolean(tokenPayload && tokenPayload.id_token),
130
+ idTokenSegments: tokenPayload && tokenPayload.id_token ? tokenPayload.id_token.split('.').length : 0,
131
+ tokenType: tokenPayload && tokenPayload.token_type,
132
+ });
133
+ const tokenOk = tokenRes.status === 200
134
+ && tokenPayload
135
+ && typeof tokenPayload.access_token === 'string'
136
+ && tokenPayload.token_type === 'Bearer'
137
+ && idTokenShape;
138
+ results.push(deClaim({
139
+ capability,
140
+ verdict: tokenOk ? 'pass' : 'fail',
141
+ detail: tokenOk
142
+ ? `/token returned access_token AND id_token: status=200 requestId=${tokenRequestId} segments=3`
143
+ : `/token failure: status=${tokenRes.status} requestId=${tokenRequestId}`,
144
+ evidence: {
145
+ requestId: tokenRequestId,
146
+ status: tokenRes.status,
147
+ accessTokenPresent: Boolean(tokenPayload && tokenPayload.access_token),
148
+ idTokenPresent: Boolean(tokenPayload && tokenPayload.id_token),
149
+ idTokenSegments: tokenPayload && tokenPayload.id_token ? tokenPayload.id_token.split('.').length : 0,
150
+ tokenType: tokenPayload && tokenPayload.token_type,
151
+ },
152
+ }, { ac: 'security-auth-oauth2-AC-10101-2', limitation: LIM_TOKEN }));
153
+
154
+ // 4. /callback-check AFTER /token , code now in consumedCodes.
155
+ // The refusal is observed from the mock's records; preExchange
156
+ // for THIS second callback is false (observed, not asserted).
157
+ const postCallbackUrl = new URL(`http://127.0.0.1:${port}/callback-check`);
158
+ postCallbackUrl.searchParams.set('code', codeFromRes);
159
+ postCallbackUrl.searchParams.set('state', state1);
160
+ const postCallbackRes = await fetch(postCallbackUrl);
161
+ const postCallbackRequestId = postCallbackRes.headers.get('x-mock-request-id');
162
+ const postCallbackText = await postCallbackRes.text();
163
+ let postCallbackPayload = null; try { postCallbackPayload = JSON.parse(postCallbackText); } catch {}
164
+ const tokenCallCountAtPostCallback = server.tokenCallCount;
165
+ // Observed preExchange for the FIRST (pre-token) callback: token
166
+ // calls at that point were 0. The mock's consumedCodes for the
167
+ // code was empty when the first callback ran.
168
+ const preExchangeObserved = preExchangeObservedTokenCallsAtCallback === 0
169
+ && preCallbackPayload && preCallbackPayload.ok === true;
170
+ // Observed refusal for the SECOND (post-token) callback: code
171
+ // now recorded as consumed in the mock's consumedCodes map
172
+ // with consumedAtRequestNo < thisRequestNo.
173
+ const consumed = server.consumedCodes.get(codeFromRes);
174
+ const consumedRefusalObserved = postCallbackRes.status >= 400
175
+ && postCallbackPayload
176
+ && postCallbackPayload.error === 'invalid_grant'
177
+ && consumed
178
+ && typeof consumed.consumedAtRequestNo === 'number';
179
+ evidence.calls.push({
180
+ verb: 'GET /callback-check (post-token, consumed code)',
181
+ status: postCallbackRes.status, requestId: postCallbackRequestId,
182
+ body: postCallbackPayload,
183
+ consumedRecord: consumed || null,
184
+ tokenCallCountAtThisPoint: tokenCallCountAtPostCallback,
185
+ });
186
+ results.push(deClaim({
187
+ capability,
188
+ verdict: preExchangeObserved && consumedRefusalObserved ? 'pass' : 'fail',
189
+ detail: `callback-check: pre-token=${preCallbackRes.status} (tokenCalls=${preExchangeObservedTokenCallsAtCallback}, ok=${preCallbackPayload && preCallbackPayload.ok}); post-token=${postCallbackRes.status} error=${postCallbackPayload && postCallbackPayload.error} consumedAtRequestNo=${consumed && consumed.consumedAtRequestNo}`,
190
+ evidence: {
191
+ requestId: postCallbackRequestId,
192
+ status: postCallbackRes.status,
193
+ error: postCallbackPayload && postCallbackPayload.error,
194
+ preExchangeObserved,
195
+ preExchangeTokenCallCount: preExchangeObservedTokenCallsAtCallback,
196
+ consumedAtRequestNo: consumed && consumed.consumedAtRequestNo,
197
+ tokenCallCountAtPostCallback,
198
+ },
199
+ vendorCitation: { url: 'https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2', verifiedOn: '2026-09-11' },
200
+ }, { ac: 'security-auth-oauth2-AC-10102-2', limitation: LIM_REPLAY }));
201
+
202
+ // 5. PKCE-verifier mismatch (fresh code, tampered verifier)
203
+ const state2 = freshState();
204
+ evidence.observedStates.push(state2);
205
+ const authUrl2 = new URL(`http://127.0.0.1:${port}/authorize`);
206
+ for (const [k, v] of authUrl.searchParams) authUrl2.searchParams.set(k, v);
207
+ authUrl2.searchParams.set('state', state2);
208
+ authUrl2.searchParams.set('nonce', `n_${randomBytes(8).toString('base64url')}`);
209
+ const authRes2 = await fetch(authUrl2, { redirect: 'manual' });
210
+ const authRequestId2 = authRes2.headers.get('x-mock-request-id');
211
+ const authText2 = await authRes2.text();
212
+ let authPayload2 = null; try { authPayload2 = JSON.parse(authText2); } catch {}
213
+ evidence.calls.push({ verb: 'GET /authorize (2)', status: authRes2.status, requestId: authRequestId2, resourceId: authPayload2 && authPayload2.code, state: state2 });
214
+ if (!(authRes2.status === 302 && authPayload2 && authPayload2.code)) {
215
+ results.push(deClaim({
216
+ capability, verdict: 'fail',
217
+ detail: `precondition /authorize did not issue a code: status=${authRes2.status} requestId=${authRequestId2}`,
218
+ evidence: { requestId: authRequestId2, status: authRes2.status },
219
+ }, { ac: 'security-auth-oauth2-AC-10103-2', limitation: LIM_PKCE }));
220
+ } else {
221
+ const tamperBody = new URLSearchParams({
222
+ grant_type: 'authorization_code',
223
+ code: authPayload2.code,
224
+ redirect_uri: redirectUri,
225
+ client_id: clientId,
226
+ code_verifier: pkce.verifier + 'X',
227
+ });
228
+ const tamperRes = await fetch(`http://127.0.0.1:${port}/token`, {
229
+ method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: tamperBody.toString(),
230
+ });
231
+ const tamperRequestId = tamperRes.headers.get('x-mock-request-id');
232
+ const tamperText = await tamperRes.text();
233
+ let tamperPayload = null; try { tamperPayload = JSON.parse(tamperText); } catch {}
234
+ evidence.calls.push({ verb: 'POST /token (PKCE mismatch)', status: tamperRes.status, requestId: tamperRequestId, error: tamperPayload && tamperPayload.error });
235
+ results.push(deClaim({
236
+ capability,
237
+ verdict: tamperRes.status === 400 && tamperPayload && tamperPayload.error === 'invalid_grant' ? 'pass' : 'fail',
238
+ detail: `verifier mismatch refused: status=${tamperRes.status} requestId=${tamperRequestId} error=${tamperPayload && tamperPayload.error}`,
239
+ evidence: { requestId: tamperRequestId, status: tamperRes.status, error: tamperPayload && tamperPayload.error, detail: tamperPayload && tamperPayload.detail },
240
+ vendorCitation: { url: 'https://datatracker.ietf.org/doc/html/rfc7636#section-4.6', verifiedOn: '2026-09-11' },
241
+ }, { ac: 'security-auth-oauth2-AC-10103-2', limitation: LIM_PKCE }));
242
+ }
243
+
244
+ } finally {
245
+ try {
246
+ await server.stop();
247
+ } catch (err) {
248
+ teardownFailed = true;
249
+ results.push(deClaim({
250
+ capability, verdict: 'fail',
251
+ detail: `TEARDOWN FAILED: mock server stop threw: ${err && err.message ? err.message : String(err)}`,
252
+ evidence: { teardownError: err && err.message ? err.message : String(err) },
253
+ }, { ac: 'security-auth-oauth2-AC-10101-1', limitation: LIM_AUTHZ }));
254
+ evidence.teardownError = err && err.message ? err.message : String(err);
255
+ }
256
+ }
257
+ evidence.teardownFailed = teardownFailed;
258
+ return { results, extra: evidence };
259
+ }
@@ -0,0 +1,58 @@
1
+ // PKCE challenge-and-verify shape probe. Conformance-only. Every
2
+ // row records anchorAcId=null with a limitation naming the shipped
3
+ // AC whose route-level flow property the local helper derivation
4
+ // does not observe. The integration harness follow-up is the
5
+ // surface where the AC-level properties become observable.
6
+ //
7
+
8
+ import { pathToFileURL } from 'node:url';
9
+ import { resolve, dirname } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { createHash } from 'node:crypto';
12
+ import { deClaim } from './probe-utils.mjs';
13
+
14
+ const HERE = dirname(fileURLToPath(import.meta.url));
15
+ const FIXTURE_SRC = resolve(HERE, '..', '..', '..', '..', 'packages', 'rcf-lite', 'test', 'fixtures', 'security-auth-oauth2', 'src');
16
+
17
+ export const anchorAcId = null;
18
+ export const capability = 'authorisationCodeFlow';
19
+ export const accountBound = false;
20
+
21
+ const LIM_HAPPY = 'security-auth-oauth2-AC-10101-1: probe checks S256 derivation only; the AC states the project sign-in route redirects to the provider /authorize with a valid code_challenge, needs the integration harness (the auth integration harness follow-up).';
22
+ const LIM_MISMATCH = 'security-auth-oauth2-AC-10103-2: probe observes verifier-hash divergence only; the AC states invalid_grant at /token, flow termination, and absence of session issue, needs the integration harness (the auth integration harness follow-up).';
23
+ const LIM_LEN = 'security-auth-oauth2-AC-10101-1: probe checks the local verifier length band against RFC 7636 sec 4.1; the AC states the project sign-in route redirects to the provider /authorize with a valid code_challenge, which requires observing the deployed route through the integration harness follow-up.';
24
+
25
+ export default async function runProbe() {
26
+ const { generatePkcePair } = await import(pathToFileURL(resolve(FIXTURE_SRC, 'mock-authorization-server.mjs')).href);
27
+ const results = [];
28
+
29
+ const pair = generatePkcePair();
30
+ const derived = createHash('sha256').update(pair.verifier).digest('base64url');
31
+ const nonEmptyChallenge = typeof pair.challenge === 'string' && pair.challenge.length > 0;
32
+ results.push(deClaim({
33
+ capability,
34
+ verdict: derived === pair.challenge && pair.method === 'S256' && nonEmptyChallenge ? 'pass' : 'fail',
35
+ detail: `code_challenge_method=${pair.method} code_challenge non-empty=${nonEmptyChallenge} derived==challenge=${derived === pair.challenge}`,
36
+ evidence: { verifierLength: pair.verifier.length, challengePreviewFirst8: pair.challenge.slice(0, 8), method: pair.method, derivationMatched: derived === pair.challenge },
37
+ }, { ac: 'security-auth-oauth2-AC-10101-1', limitation: LIM_HAPPY }));
38
+
39
+ const mutatedVerifier = pair.verifier + 'X';
40
+ const mutatedDerived = createHash('sha256').update(mutatedVerifier).digest('base64url');
41
+ results.push(deClaim({
42
+ capability,
43
+ verdict: mutatedDerived !== pair.challenge ? 'pass' : 'fail',
44
+ detail: `verifier-mutation derivation diverges from original: collided=${mutatedDerived === pair.challenge}`,
45
+ evidence: { mutation: 'verifier+X', collidedWithOriginal: mutatedDerived === pair.challenge },
46
+ }, { ac: 'security-auth-oauth2-AC-10103-2', limitation: LIM_MISMATCH }));
47
+
48
+ const okLen = pair.verifier.length >= 43 && pair.verifier.length <= 128;
49
+ results.push(deClaim({
50
+ capability,
51
+ verdict: okLen ? 'pass' : 'fail',
52
+ detail: `RFC 7636 sec 4.1 verifier length in [43,128]: observed=${pair.verifier.length}.`,
53
+ evidence: { verifierLength: pair.verifier.length, min: 43, max: 128 },
54
+ vendorCitation: { url: 'https://datatracker.ietf.org/doc/html/rfc7636#section-4.1', verifiedOn: '2026-09-11' },
55
+ }, { ac: 'security-auth-oauth2-AC-10101-1', limitation: LIM_LEN }));
56
+
57
+ return { results, extra: {} };
58
+ }