rcf-lite 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +10 -0
  3. package/bin/rcf.js +2 -0
  4. package/blueprints/application-account-settings/CHANGELOG.md +35 -6
  5. package/blueprints/application-account-settings/README.md +1 -1
  6. package/blueprints/application-account-settings/blueprint.json +4 -2
  7. package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +1 -1
  8. package/blueprints/application-account-settings/contributions/probes/probe-utils.mjs +177 -0
  9. package/blueprints/application-account-settings/contributions/probes/profile-form-autocomplete.mjs +67 -0
  10. package/blueprints/application-account-settings/contributions/probes/run-profile-form-autocomplete.mjs +5 -0
  11. package/blueprints/application-account-settings/contributions/probes/run-sessions-adapter-uniform.mjs +5 -0
  12. package/blueprints/application-account-settings/contributions/probes/run-sessions-surface-shape.mjs +5 -0
  13. package/blueprints/application-account-settings/contributions/probes/run-shell-tablist-per-capability.mjs +5 -0
  14. package/blueprints/application-account-settings/contributions/probes/run-theme-radiogroup.mjs +5 -0
  15. package/blueprints/application-account-settings/contributions/probes/sessions-adapter-uniform.mjs +130 -0
  16. package/blueprints/application-account-settings/contributions/probes/sessions-surface-shape.mjs +70 -0
  17. package/blueprints/application-account-settings/contributions/probes/shell-tablist-per-capability.mjs +60 -0
  18. package/blueprints/application-account-settings/contributions/probes/theme-radiogroup.mjs +126 -0
  19. package/blueprints/application-admin-console/CHANGELOG.md +32 -6
  20. package/blueprints/application-admin-console/README.md +1 -1
  21. package/blueprints/application-admin-console/blueprint.json +4 -2
  22. package/blueprints/application-admin-console/contributions/adrs/adr-2201-application-admin-console-capability-vocabulary.json +1 -1
  23. package/blueprints/application-admin-console/contributions/probes/audit-log-surface.mjs +79 -0
  24. package/blueprints/application-admin-console/contributions/probes/org-switcher-surface.mjs +83 -0
  25. package/blueprints/application-admin-console/contributions/probes/permission-matrix-grid.mjs +67 -0
  26. package/blueprints/application-admin-console/contributions/probes/probe-utils.mjs +177 -0
  27. package/blueprints/application-admin-console/contributions/probes/run-audit-log-surface.mjs +5 -0
  28. package/blueprints/application-admin-console/contributions/probes/run-org-switcher-surface.mjs +5 -0
  29. package/blueprints/application-admin-console/contributions/probes/run-permission-matrix-grid.mjs +5 -0
  30. package/blueprints/application-admin-console/contributions/probes/run-sign-in-access-gated-surface.mjs +5 -0
  31. package/blueprints/application-admin-console/contributions/probes/run-users-directory-surface.mjs +5 -0
  32. package/blueprints/application-admin-console/contributions/probes/sign-in-access-gated-surface.mjs +117 -0
  33. package/blueprints/application-admin-console/contributions/probes/users-directory-surface.mjs +145 -0
  34. package/blueprints/application-api-rest/CHANGELOG.md +16 -8
  35. package/blueprints/application-api-rest/README.md +3 -3
  36. package/blueprints/application-api-rest/blueprint.json +3 -2
  37. package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +1 -1
  38. package/blueprints/application-api-rest/contributions/probes/cursor-pagination-round-trip.mjs +154 -0
  39. package/blueprints/application-api-rest/contributions/probes/health-probes-distinct.mjs +124 -0
  40. package/blueprints/application-api-rest/contributions/probes/probe-utils.mjs +177 -0
  41. package/blueprints/application-api-rest/contributions/probes/problem-details-on-error.mjs +77 -0
  42. package/blueprints/application-api-rest/contributions/probes/request-id-echoed.mjs +76 -0
  43. package/blueprints/application-api-rest/contributions/probes/run-cursor-pagination-round-trip.mjs +5 -0
  44. package/blueprints/application-api-rest/contributions/probes/run-health-probes-distinct.mjs +5 -0
  45. package/blueprints/application-api-rest/contributions/probes/run-problem-details-on-error.mjs +5 -0
  46. package/blueprints/application-api-rest/contributions/probes/run-request-id-echoed.mjs +5 -0
  47. package/blueprints/application-api-rest/docs/topics.md +1 -1
  48. package/blueprints/application-charts/CHANGELOG.md +35 -9
  49. package/blueprints/application-charts/README.md +6 -6
  50. package/blueprints/application-charts/blueprint.json +5 -3
  51. package/blueprints/application-charts/contributions/adrs/adr-1901-application-charts-engine-choice.json +1 -1
  52. package/blueprints/application-charts/contributions/probes/keyboard-traversal.mjs +151 -0
  53. package/blueprints/application-charts/contributions/probes/non-colour-distinction.mjs +67 -0
  54. package/blueprints/application-charts/contributions/probes/probe-utils.mjs +177 -0
  55. package/blueprints/application-charts/contributions/probes/run-keyboard-traversal.mjs +5 -0
  56. package/blueprints/application-charts/contributions/probes/run-non-colour-distinction.mjs +5 -0
  57. package/blueprints/application-charts/contributions/probes/run-text-alternative-table.mjs +5 -0
  58. package/blueprints/application-charts/contributions/probes/text-alternative-table.mjs +139 -0
  59. package/blueprints/application-charts/contributions/requirements/application-charts-req-001.json +1 -1
  60. package/blueprints/application-charts/contributions/requirements/application-charts-req-002.json +1 -1
  61. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18101.json +5 -5
  62. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18106.json +1 -1
  63. package/blueprints/application-charts/guide/application-charts.md +1 -1
  64. package/blueprints/application-dashboard/CHANGELOG.md +20 -10
  65. package/blueprints/application-dashboard/README.md +6 -6
  66. package/blueprints/application-dashboard/assets/guidance/dashboard-design.md +2 -2
  67. package/blueprints/application-dashboard/blueprint.json +3 -2
  68. package/blueprints/application-dashboard/contributions/adrs/adr-2001-application-dashboard-primary-kpi-enum.json +1 -1
  69. package/blueprints/application-dashboard/contributions/adrs/adr-2002-application-dashboard-timeframe-presets.json +1 -1
  70. package/blueprints/application-dashboard/contributions/probes/export-handle-formats.mjs +75 -0
  71. package/blueprints/application-dashboard/contributions/probes/four-tile-states.mjs +75 -0
  72. package/blueprints/application-dashboard/contributions/probes/primary-kpi-top-left.mjs +58 -0
  73. package/blueprints/application-dashboard/contributions/probes/probe-utils.mjs +177 -0
  74. package/blueprints/application-dashboard/contributions/probes/run-export-handle-formats.mjs +4 -0
  75. package/blueprints/application-dashboard/contributions/probes/run-four-tile-states.mjs +4 -0
  76. package/blueprints/application-dashboard/contributions/probes/run-primary-kpi-top-left.mjs +4 -0
  77. package/blueprints/application-dashboard/contributions/probes/run-shell-five-regions.mjs +4 -0
  78. package/blueprints/application-dashboard/contributions/probes/shell-five-regions.mjs +93 -0
  79. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-002.json +1 -1
  80. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-003.json +1 -1
  81. package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +1 -1
  82. package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +2 -2
  83. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19101.json +2 -2
  84. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19102.json +2 -2
  85. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19103.json +1 -1
  86. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19104.json +1 -1
  87. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19105.json +1 -1
  88. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +2 -2
  89. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19107.json +5 -5
  90. package/blueprints/application-dashboard/docs/topics.md +2 -2
  91. package/blueprints/application-dashboard/guide/application-dashboard.md +2 -2
  92. package/blueprints/application-datatable/CHANGELOG.md +19 -9
  93. package/blueprints/application-datatable/README.md +2 -2
  94. package/blueprints/application-datatable/blueprint.json +3 -2
  95. package/blueprints/application-datatable/contributions/probes/apg-table-shape.mjs +57 -0
  96. package/blueprints/application-datatable/contributions/probes/four-states-regions.mjs +80 -0
  97. package/blueprints/application-datatable/contributions/probes/probe-utils.mjs +177 -0
  98. package/blueprints/application-datatable/contributions/probes/run-apg-table-shape.mjs +4 -0
  99. package/blueprints/application-datatable/contributions/probes/run-four-states-regions.mjs +4 -0
  100. package/blueprints/application-datatable/contributions/probes/run-search-adapter-round-trip.mjs +4 -0
  101. package/blueprints/application-datatable/contributions/probes/run-sort-adapter-round-trip.mjs +4 -0
  102. package/blueprints/application-datatable/contributions/probes/search-adapter-round-trip.mjs +58 -0
  103. package/blueprints/application-datatable/contributions/probes/sort-adapter-round-trip.mjs +60 -0
  104. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-006.json +1 -1
  105. package/blueprints/application-datatable/docs/topics.md +1 -1
  106. package/blueprints/application-empty-error-states/CHANGELOG.md +33 -3
  107. package/blueprints/application-empty-error-states/blueprint.json +4 -2
  108. package/blueprints/application-empty-error-states/contributions/probes/empty-list-and-no-search.mjs +66 -0
  109. package/blueprints/application-empty-error-states/contributions/probes/error-boundary-alert.mjs +65 -0
  110. package/blueprints/application-empty-error-states/contributions/probes/forbidden-and-server-error.mjs +167 -0
  111. package/blueprints/application-empty-error-states/contributions/probes/not-found-and-recovery.mjs +61 -0
  112. package/blueprints/application-empty-error-states/contributions/probes/permission-denied-and-offline.mjs +155 -0
  113. package/blueprints/application-empty-error-states/contributions/probes/probe-utils.mjs +177 -0
  114. package/blueprints/application-empty-error-states/contributions/probes/run-empty-list-and-no-search.mjs +5 -0
  115. package/blueprints/application-empty-error-states/contributions/probes/run-error-boundary-alert.mjs +5 -0
  116. package/blueprints/application-empty-error-states/contributions/probes/run-forbidden-and-server-error.mjs +5 -0
  117. package/blueprints/application-empty-error-states/contributions/probes/run-not-found-and-recovery.mjs +5 -0
  118. package/blueprints/application-empty-error-states/contributions/probes/run-permission-denied-and-offline.mjs +5 -0
  119. package/blueprints/application-error-handling/CHANGELOG.md +45 -6
  120. package/blueprints/application-error-handling/blueprint.json +3 -2
  121. package/blueprints/application-error-handling/contributions/probes/category-vocabulary.mjs +90 -0
  122. package/blueprints/application-error-handling/contributions/probes/probe-utils.mjs +177 -0
  123. package/blueprints/application-error-handling/contributions/probes/record-shape-adr-1701.mjs +78 -0
  124. package/blueprints/application-error-handling/contributions/probes/run-category-vocabulary.mjs +5 -0
  125. package/blueprints/application-error-handling/contributions/probes/run-record-shape-adr-1701.mjs +5 -0
  126. package/blueprints/application-error-handling/contributions/probes/run-two-boundaries-registered.mjs +5 -0
  127. package/blueprints/application-error-handling/contributions/probes/two-boundaries-registered.mjs +343 -0
  128. package/blueprints/application-file-upload/CHANGELOG.md +28 -6
  129. package/blueprints/application-file-upload/README.md +1 -1
  130. package/blueprints/application-file-upload/blueprint.json +3 -2
  131. package/blueprints/application-file-upload/contributions/probes/assertive-completion-slot.mjs +78 -0
  132. package/blueprints/application-file-upload/contributions/probes/chunked-transport-endpoints.mjs +173 -0
  133. package/blueprints/application-file-upload/contributions/probes/per-file-progressbar.mjs +124 -0
  134. package/blueprints/application-file-upload/contributions/probes/probe-utils.mjs +177 -0
  135. package/blueprints/application-file-upload/contributions/probes/run-assertive-completion-slot.mjs +4 -0
  136. package/blueprints/application-file-upload/contributions/probes/run-chunked-transport-endpoints.mjs +4 -0
  137. package/blueprints/application-file-upload/contributions/probes/run-per-file-progressbar.mjs +4 -0
  138. package/blueprints/application-file-upload/contributions/probes/run-upload-surface-shape.mjs +4 -0
  139. package/blueprints/application-file-upload/contributions/probes/upload-surface-shape.mjs +55 -0
  140. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +1 -1
  141. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +1 -1
  142. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +1 -1
  143. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +1 -1
  144. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +1 -1
  145. package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +1 -1
  146. package/blueprints/application-forms-wizard/CHANGELOG.md +20 -6
  147. package/blueprints/application-forms-wizard/README.md +2 -2
  148. package/blueprints/application-forms-wizard/blueprint.json +3 -2
  149. package/blueprints/application-forms-wizard/contributions/probes/draft-persistence-round-trip.mjs +110 -0
  150. package/blueprints/application-forms-wizard/contributions/probes/probe-utils.mjs +177 -0
  151. package/blueprints/application-forms-wizard/contributions/probes/run-draft-persistence-round-trip.mjs +4 -0
  152. package/blueprints/application-forms-wizard/contributions/probes/run-step-page-shape.mjs +4 -0
  153. package/blueprints/application-forms-wizard/contributions/probes/run-task-list-surface.mjs +4 -0
  154. package/blueprints/application-forms-wizard/contributions/probes/step-page-shape.mjs +61 -0
  155. package/blueprints/application-forms-wizard/contributions/probes/task-list-surface.mjs +109 -0
  156. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +1 -1
  157. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +1 -1
  158. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +1 -1
  159. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +1 -1
  160. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +1 -1
  161. package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +1 -1
  162. package/blueprints/application-notifications-in-app/CHANGELOG.md +38 -5
  163. package/blueprints/application-notifications-in-app/README.md +4 -4
  164. package/blueprints/application-notifications-in-app/blueprint.json +4 -2
  165. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2101-application-notifications-in-app-live-region-role-mapping.json +1 -1
  166. package/blueprints/application-notifications-in-app/contributions/probes/centre-acknowledge-round-trip.mjs +210 -0
  167. package/blueprints/application-notifications-in-app/contributions/probes/live-region-preseeding.mjs +93 -0
  168. package/blueprints/application-notifications-in-app/contributions/probes/probe-utils.mjs +177 -0
  169. package/blueprints/application-notifications-in-app/contributions/probes/run-centre-acknowledge-round-trip.mjs +5 -0
  170. package/blueprints/application-notifications-in-app/contributions/probes/run-live-region-preseeding.mjs +5 -0
  171. package/blueprints/application-notifications-in-app/contributions/probes/run-toast-contract.mjs +5 -0
  172. package/blueprints/application-notifications-in-app/contributions/probes/toast-contract.mjs +92 -0
  173. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +3 -3
  174. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +1 -1
  175. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +1 -1
  176. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +1 -1
  177. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +1 -1
  178. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +1 -1
  179. package/blueprints/application-notifications-in-app/guide/application-notifications-in-app.md +3 -3
  180. package/blueprints/application-onboarding-tour/CHANGELOG.md +31 -5
  181. package/blueprints/application-onboarding-tour/README.md +1 -1
  182. package/blueprints/application-onboarding-tour/blueprint.json +5 -3
  183. package/blueprints/application-onboarding-tour/contributions/probes/checklist-anchor-open.mjs +81 -0
  184. package/blueprints/application-onboarding-tour/contributions/probes/completion-persistence.mjs +159 -0
  185. package/blueprints/application-onboarding-tour/contributions/probes/first-run-detection.mjs +67 -0
  186. package/blueprints/application-onboarding-tour/contributions/probes/probe-utils.mjs +177 -0
  187. package/blueprints/application-onboarding-tour/contributions/probes/run-checklist-anchor-open.mjs +5 -0
  188. package/blueprints/application-onboarding-tour/contributions/probes/run-completion-persistence.mjs +5 -0
  189. package/blueprints/application-onboarding-tour/contributions/probes/run-first-run-detection.mjs +5 -0
  190. package/blueprints/application-onboarding-tour/contributions/probes/run-stepper-role-dialog.mjs +5 -0
  191. package/blueprints/application-onboarding-tour/contributions/probes/stepper-role-dialog.mjs +45 -0
  192. package/blueprints/application-spa/CHANGELOG.md +20 -11
  193. package/blueprints/application-spa/README.md +9 -10
  194. package/blueprints/application-spa/blueprint.json +3 -2
  195. package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +1 -1
  196. package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +1 -1
  197. package/blueprints/application-spa/contributions/probes/designed-empty-state.mjs +72 -0
  198. package/blueprints/application-spa/contributions/probes/probe-utils.mjs +177 -0
  199. package/blueprints/application-spa/contributions/probes/route-inventory-published.mjs +185 -0
  200. package/blueprints/application-spa/contributions/probes/run-designed-empty-state.mjs +5 -0
  201. package/blueprints/application-spa/contributions/probes/run-route-inventory-published.mjs +5 -0
  202. package/blueprints/application-spa/contributions/probes/run-shell-nav-present.mjs +5 -0
  203. package/blueprints/application-spa/contributions/probes/shell-nav-present.mjs +69 -0
  204. package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +1 -1
  205. package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +2 -2
  206. package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +3 -3
  207. package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +2 -2
  208. package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +2 -2
  209. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +1 -1
  210. package/blueprints/application-spa/docs/topics.md +1 -1
  211. package/blueprints/delivery-ci-workflows/CHANGELOG.md +31 -11
  212. package/blueprints/delivery-ci-workflows/README.md +3 -3
  213. package/blueprints/delivery-ci-workflows/blueprint.json +3 -2
  214. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-702-delivery-ci-workflows-strict-coverage-gate.json +2 -2
  215. package/blueprints/delivery-ci-workflows/contributions/probes/node-gate-entrypoint.mjs +76 -0
  216. package/blueprints/delivery-ci-workflows/contributions/probes/probe-utils.mjs +56 -0
  217. package/blueprints/delivery-ci-workflows/contributions/probes/real-account-github-actions-run-record.mjs +139 -0
  218. package/blueprints/delivery-ci-workflows/contributions/probes/run-node-gate-entrypoint.mjs +3 -0
  219. package/blueprints/delivery-ci-workflows/contributions/probes/run-real-account-github-actions-run-record.mjs +3 -0
  220. package/blueprints/delivery-ci-workflows/contributions/probes/run-workflow-template-shape.mjs +3 -0
  221. package/blueprints/delivery-ci-workflows/contributions/probes/workflow-template-shape.mjs +94 -0
  222. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +1 -1
  223. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -3
  224. package/blueprints/deploy-cloudflare-workers/CHANGELOG.md +4 -4
  225. package/blueprints/deploy-cloudflare-workers/README.md +3 -3
  226. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1306-deploy-cloudflare-workers-spa-shape.json +2 -2
  227. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  228. package/blueprints/deploy-hetzner-server/CHANGELOG.md +98 -7
  229. package/blueprints/deploy-hetzner-server/blueprint.json +7 -6
  230. package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +46 -21
  231. package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +344 -83
  232. package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +211 -42
  233. package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +140 -22
  234. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +111 -30
  235. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +158 -30
  236. package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +154 -32
  237. package/blueprints/edge-cloudflare-access/CHANGELOG.md +6 -5
  238. package/blueprints/edge-cloudflare-access/blueprint.json +1 -1
  239. package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +9 -1
  240. package/blueprints/edge-cloudflare-access/docs/topics.md +1 -1
  241. package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +4 -7
  242. package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +1 -1
  243. package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +4 -6
  244. package/blueprints/edge-cloudflare-tunnel/README.md +1 -2
  245. package/blueprints/edge-cloudflare-tunnel/docs/topics.md +1 -1
  246. package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +2 -3
  247. package/blueprints/edge-cloudflare-turnstile/docs/topics.md +1 -1
  248. package/blueprints/email-smtp-resend/CHANGELOG.md +24 -8
  249. package/blueprints/email-smtp-resend/README.md +2 -2
  250. package/blueprints/email-smtp-resend/blueprint.json +3 -2
  251. package/blueprints/email-smtp-resend/contributions/probes/probe-utils.mjs +50 -0
  252. package/blueprints/email-smtp-resend/contributions/probes/real-account-resend-send.mjs +50 -0
  253. package/blueprints/email-smtp-resend/contributions/probes/run-real-account-resend-send.mjs +3 -0
  254. package/blueprints/email-smtp-resend/contributions/probes/run-smtp-round-trip.mjs +3 -0
  255. package/blueprints/email-smtp-resend/contributions/probes/run-unverified-sender-refusal.mjs +3 -0
  256. package/blueprints/email-smtp-resend/contributions/probes/smtp-round-trip.mjs +43 -0
  257. package/blueprints/email-smtp-resend/contributions/probes/unverified-sender-refusal.mjs +99 -0
  258. package/blueprints/email-smtp-resend/docs/topics.md +2 -3
  259. package/blueprints/jobs-background/CHANGELOG.md +66 -5
  260. package/blueprints/jobs-background/README.md +2 -2
  261. package/blueprints/jobs-background/blueprint.json +3 -2
  262. package/blueprints/jobs-background/contributions/probes/apply-time-override.mjs +38 -10
  263. package/blueprints/jobs-background/contributions/probes/apply-time-refusal.mjs +28 -6
  264. package/blueprints/jobs-background/contributions/probes/event-secrecy.mjs +16 -2
  265. package/blueprints/jobs-background/contributions/probes/fake-clock-cron.mjs +102 -21
  266. package/blueprints/jobs-background/contributions/probes/probe-utils.mjs +10 -2
  267. package/blueprints/jobs-background/contributions/probes/retry-and-fail-real-account.mjs +355 -0
  268. package/blueprints/jobs-background/contributions/probes/retry-and-fail.mjs +33 -2
  269. package/blueprints/jobs-background/contributions/probes/run-retry-and-fail-real-account.mjs +12 -0
  270. package/blueprints/jobs-background/docs/topics.md +1 -1
  271. package/blueprints/jobs-background/guide/jobs-background.md +1 -1
  272. package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +25 -19
  273. package/blueprints/messaging-queue-cloudflare/README.md +12 -12
  274. package/blueprints/messaging-queue-cloudflare/blueprint.json +1 -1
  275. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3001-messaging-queue-cloudflare-adapter.json +2 -2
  276. package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3002-messaging-queue-cloudflare-delivery-semantics.json +1 -1
  277. package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +180 -12
  278. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +1 -1
  279. package/blueprints/messaging-queue-cloudflare/docs/topics.md +2 -2
  280. package/blueprints/messaging-queue-cloudflare/guide/messaging-queue-cloudflare.md +2 -2
  281. package/blueprints/object-storage-s3/CHANGELOG.md +75 -4
  282. package/blueprints/object-storage-s3/blueprint.json +3 -2
  283. package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +73 -12
  284. package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +55 -7
  285. package/blueprints/object-storage-s3/contributions/probes/hetzner-object-storage-round-trip.mjs +102 -18
  286. package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +105 -36
  287. package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +104 -55
  288. package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +129 -7
  289. package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +80 -18
  290. package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +291 -37
  291. package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +8 -2
  292. package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +5 -5
  293. package/blueprints/object-storage-s3/contributions/probes/run-hetzner-object-storage-round-trip.mjs +8 -5
  294. package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +8 -2
  295. package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +8 -2
  296. package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +6 -3
  297. package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +10 -2
  298. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +1 -1
  299. package/blueprints/object-storage-s3/docs/topics.md +1 -1
  300. package/blueprints/object-storage-s3/guide/object-storage-s3.md +1 -1
  301. package/blueprints/observability-essentials/CHANGELOG.md +23 -7
  302. package/blueprints/observability-essentials/README.md +2 -2
  303. package/blueprints/observability-essentials/assets/probe-samples/probe-response-baseline.v2.json +1 -1
  304. package/blueprints/observability-essentials/blueprint.json +3 -2
  305. package/blueprints/observability-essentials/contributions/probes/liveness-probe.mjs +84 -0
  306. package/blueprints/observability-essentials/contributions/probes/metrics-endpoint.mjs +96 -0
  307. package/blueprints/observability-essentials/contributions/probes/probe-utils.mjs +52 -0
  308. package/blueprints/observability-essentials/contributions/probes/readiness-probe.mjs +171 -0
  309. package/blueprints/observability-essentials/contributions/probes/run-liveness-probe.mjs +3 -0
  310. package/blueprints/observability-essentials/contributions/probes/run-metrics-endpoint.mjs +3 -0
  311. package/blueprints/observability-essentials/contributions/probes/run-readiness-probe.mjs +3 -0
  312. package/blueprints/observability-essentials/docs/topics.md +2 -3
  313. package/blueprints/observability-logging/CHANGELOG.md +29 -4
  314. package/blueprints/observability-logging/README.md +2 -2
  315. package/blueprints/observability-logging/blueprint.json +3 -2
  316. package/blueprints/observability-logging/contributions/probes/correlation-id-flow.mjs +173 -0
  317. package/blueprints/observability-logging/contributions/probes/line-shape-and-fields.mjs +82 -0
  318. package/blueprints/observability-logging/contributions/probes/probe-utils.mjs +47 -0
  319. package/blueprints/observability-logging/contributions/probes/redaction-boundary.mjs +130 -0
  320. package/blueprints/observability-logging/contributions/probes/run-correlation-id-flow.mjs +3 -0
  321. package/blueprints/observability-logging/contributions/probes/run-line-shape-and-fields.mjs +3 -0
  322. package/blueprints/observability-logging/contributions/probes/run-redaction-boundary.mjs +3 -0
  323. package/blueprints/observability-probe-endpoints/CHANGELOG.md +23 -8
  324. package/blueprints/observability-probe-endpoints/README.md +3 -3
  325. package/blueprints/observability-probe-endpoints/blueprint.json +3 -2
  326. package/blueprints/observability-probe-endpoints/contributions/probes/kubernetes-startup-enabled.mjs +80 -0
  327. package/blueprints/observability-probe-endpoints/contributions/probes/partial-profile-refusal.mjs +101 -0
  328. package/blueprints/observability-probe-endpoints/contributions/probes/probe-utils.mjs +49 -0
  329. package/blueprints/observability-probe-endpoints/contributions/probes/profile-boot-materialisation.mjs +69 -0
  330. package/blueprints/observability-probe-endpoints/contributions/probes/run-kubernetes-startup-enabled.mjs +3 -0
  331. package/blueprints/observability-probe-endpoints/contributions/probes/run-partial-profile-refusal.mjs +3 -0
  332. package/blueprints/observability-probe-endpoints/contributions/probes/run-profile-boot-materialisation.mjs +3 -0
  333. package/blueprints/observability-probe-endpoints/docs/topics.md +2 -2
  334. package/blueprints/persistence-data-d1/CHANGELOG.md +16 -3
  335. package/blueprints/persistence-data-d1/README.md +2 -2
  336. package/blueprints/persistence-data-d1/blueprint.json +3 -2
  337. package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +1 -1
  338. package/blueprints/persistence-data-d1/contributions/probes/facade-round-trip.mjs +140 -0
  339. package/blueprints/persistence-data-d1/contributions/probes/migrations-forward-only.mjs +66 -0
  340. package/blueprints/persistence-data-d1/contributions/probes/probe-utils.mjs +51 -0
  341. package/blueprints/persistence-data-d1/contributions/probes/real-account-d1-round-trip.mjs +133 -0
  342. package/blueprints/persistence-data-d1/contributions/probes/run-facade-round-trip.mjs +3 -0
  343. package/blueprints/persistence-data-d1/contributions/probes/run-migrations-forward-only.mjs +3 -0
  344. package/blueprints/persistence-data-d1/contributions/probes/run-real-account-d1-round-trip.mjs +3 -0
  345. package/blueprints/persistence-data-d1/docs/topics.md +2 -3
  346. package/blueprints/persistence-data-postgres/CHANGELOG.md +84 -4
  347. package/blueprints/persistence-data-postgres/README.md +2 -2
  348. package/blueprints/persistence-data-postgres/blueprint.json +3 -2
  349. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +1 -1
  350. package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +87 -12
  351. package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +245 -19
  352. package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +109 -26
  353. package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +151 -38
  354. package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +24 -6
  355. package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +261 -48
  356. package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +76 -20
  357. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +1 -1
  358. package/blueprints/persistence-data-postgres/docs/topics.md +1 -1
  359. package/blueprints/persistence-data-sqlite/CHANGELOG.md +16 -2
  360. package/blueprints/persistence-data-sqlite/README.md +2 -2
  361. package/blueprints/persistence-data-sqlite/blueprint.json +3 -2
  362. package/blueprints/persistence-data-sqlite/contributions/probes/boot-open-migrate.mjs +90 -0
  363. package/blueprints/persistence-data-sqlite/contributions/probes/facade-round-trip.mjs +82 -0
  364. package/blueprints/persistence-data-sqlite/contributions/probes/probe-utils.mjs +83 -0
  365. package/blueprints/persistence-data-sqlite/contributions/probes/run-boot-open-migrate.mjs +5 -0
  366. package/blueprints/persistence-data-sqlite/contributions/probes/run-facade-round-trip.mjs +5 -0
  367. package/blueprints/persistence-data-sqlite/contributions/probes/run-wal-checkpoint.mjs +5 -0
  368. package/blueprints/persistence-data-sqlite/contributions/probes/wal-checkpoint.mjs +137 -0
  369. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -3
  370. package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +5 -5
  371. package/blueprints/platform-cloudflare-cron-triggers/README.md +2 -3
  372. package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +1 -1
  373. package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +6 -10
  374. package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +1 -1
  375. package/blueprints/platform-cloudflare-kv/CHANGELOG.md +16 -12
  376. package/blueprints/platform-cloudflare-kv/README.md +2 -4
  377. package/blueprints/platform-cloudflare-kv/blueprint.json +2 -2
  378. package/blueprints/platform-cloudflare-kv/docs/topics.md +1 -1
  379. package/blueprints/platform-docker-compose-host/CHANGELOG.md +92 -5
  380. package/blueprints/platform-docker-compose-host/blueprint.json +2 -2
  381. package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +116 -29
  382. package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +181 -109
  383. package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +146 -26
  384. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +238 -24
  385. package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +207 -21
  386. package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +246 -42
  387. package/blueprints/platform-docker-compose-host/docs/topics.md +1 -1
  388. package/blueprints/security-auth-clerk/CHANGELOG.md +18 -6
  389. package/blueprints/security-auth-clerk/README.md +3 -3
  390. package/blueprints/security-auth-clerk/assets/wiring/workers-wrangler-toml-shape.md +1 -1
  391. package/blueprints/security-auth-clerk/blueprint.json +3 -2
  392. package/blueprints/security-auth-clerk/contributions/probes/hosted-identity-ui-config.mjs +61 -0
  393. package/blueprints/security-auth-clerk/contributions/probes/probe-utils.mjs +188 -0
  394. package/blueprints/security-auth-clerk/contributions/probes/real-account-principal-directory-round-trip.mjs +216 -0
  395. package/blueprints/security-auth-clerk/contributions/probes/real-account-session-inventory.mjs +260 -0
  396. package/blueprints/security-auth-clerk/contributions/probes/role-model-adapter.mjs +53 -0
  397. package/blueprints/security-auth-clerk/contributions/probes/run-hosted-identity-ui-config.mjs +4 -0
  398. package/blueprints/security-auth-clerk/contributions/probes/run-real-account-principal-directory-round-trip.mjs +4 -0
  399. package/blueprints/security-auth-clerk/contributions/probes/run-real-account-session-inventory.mjs +4 -0
  400. package/blueprints/security-auth-clerk/contributions/probes/run-role-model-adapter.mjs +4 -0
  401. package/blueprints/security-auth-clerk/docs/topics.md +2 -3
  402. package/blueprints/security-auth-keycloak/CHANGELOG.md +18 -7
  403. package/blueprints/security-auth-keycloak/README.md +2 -2
  404. package/blueprints/security-auth-keycloak/blueprint.json +3 -2
  405. package/blueprints/security-auth-keycloak/contributions/probes/discovery-shape.mjs +68 -0
  406. package/blueprints/security-auth-keycloak/contributions/probes/introspection-shape.mjs +88 -0
  407. package/blueprints/security-auth-keycloak/contributions/probes/jwt-verifier-shape.mjs +86 -0
  408. package/blueprints/security-auth-keycloak/contributions/probes/probe-utils.mjs +180 -0
  409. package/blueprints/security-auth-keycloak/contributions/probes/real-account-realm-round-trip.mjs +91 -0
  410. package/blueprints/security-auth-keycloak/contributions/probes/role-adapter-shape.mjs +69 -0
  411. package/blueprints/security-auth-keycloak/contributions/probes/run-discovery-shape.mjs +4 -0
  412. package/blueprints/security-auth-keycloak/contributions/probes/run-introspection-shape.mjs +4 -0
  413. package/blueprints/security-auth-keycloak/contributions/probes/run-jwt-verifier-shape.mjs +4 -0
  414. package/blueprints/security-auth-keycloak/contributions/probes/run-real-account-realm-round-trip.mjs +4 -0
  415. package/blueprints/security-auth-keycloak/contributions/probes/run-role-adapter-shape.mjs +4 -0
  416. package/blueprints/security-auth-keycloak/docs/topics.md +1 -2
  417. package/blueprints/security-auth-magic-link/CHANGELOG.md +15 -4
  418. package/blueprints/security-auth-magic-link/README.md +2 -2
  419. package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +1 -1
  420. package/blueprints/security-auth-magic-link/blueprint.json +3 -2
  421. package/blueprints/security-auth-magic-link/contributions/probes/probe-utils.mjs +174 -0
  422. package/blueprints/security-auth-magic-link/contributions/probes/real-account-magic-link-send.mjs +139 -0
  423. package/blueprints/security-auth-magic-link/contributions/probes/run-real-account-magic-link-send.mjs +4 -0
  424. package/blueprints/security-auth-magic-link/contributions/probes/run-token-entropy-shape.mjs +4 -0
  425. package/blueprints/security-auth-magic-link/contributions/probes/run-token-issue-verify.mjs +4 -0
  426. package/blueprints/security-auth-magic-link/contributions/probes/token-entropy-shape.mjs +60 -0
  427. package/blueprints/security-auth-magic-link/contributions/probes/token-issue-verify.mjs +90 -0
  428. package/blueprints/security-auth-magic-link/docs/topics.md +1 -1
  429. package/blueprints/security-auth-oauth2/CHANGELOG.md +16 -5
  430. package/blueprints/security-auth-oauth2/README.md +2 -2
  431. package/blueprints/security-auth-oauth2/blueprint.json +3 -2
  432. package/blueprints/security-auth-oauth2/contributions/probes/authorisation-code-flow-shape.mjs +259 -0
  433. package/blueprints/security-auth-oauth2/contributions/probes/pkce-challenge-shape.mjs +58 -0
  434. package/blueprints/security-auth-oauth2/contributions/probes/probe-utils.mjs +190 -0
  435. package/blueprints/security-auth-oauth2/contributions/probes/provider-adapter-shape.mjs +64 -0
  436. package/blueprints/security-auth-oauth2/contributions/probes/real-account-authorisation-code-flow.mjs +93 -0
  437. package/blueprints/security-auth-oauth2/contributions/probes/run-authorisation-code-flow-shape.mjs +4 -0
  438. package/blueprints/security-auth-oauth2/contributions/probes/run-pkce-challenge-shape.mjs +4 -0
  439. package/blueprints/security-auth-oauth2/contributions/probes/run-provider-adapter-shape.mjs +4 -0
  440. package/blueprints/security-auth-oauth2/contributions/probes/run-real-account-authorisation-code-flow.mjs +4 -0
  441. package/blueprints/security-auth-oauth2/contributions/probes/run-session-bridge-shape.mjs +4 -0
  442. package/blueprints/security-auth-oauth2/contributions/probes/session-bridge-shape.mjs +78 -0
  443. package/blueprints/security-auth-oauth2/docs/topics.md +1 -2
  444. package/blueprints/security-secrets-management/CHANGELOG.md +15 -4
  445. package/blueprints/security-secrets-management/README.md +2 -2
  446. package/blueprints/security-secrets-management/blueprint.json +3 -2
  447. package/blueprints/security-secrets-management/contributions/probes/add-recipient-rotation.mjs +107 -0
  448. package/blueprints/security-secrets-management/contributions/probes/encrypt-decrypt-round-trip.mjs +122 -0
  449. package/blueprints/security-secrets-management/contributions/probes/key-rotation.mjs +93 -0
  450. package/blueprints/security-secrets-management/contributions/probes/mismatched-key-refusal.mjs +74 -0
  451. package/blueprints/security-secrets-management/contributions/probes/probe-utils.mjs +214 -0
  452. package/blueprints/security-secrets-management/contributions/probes/run-add-recipient-rotation.mjs +4 -0
  453. package/blueprints/security-secrets-management/contributions/probes/run-encrypt-decrypt-round-trip.mjs +4 -0
  454. package/blueprints/security-secrets-management/contributions/probes/run-key-rotation.mjs +4 -0
  455. package/blueprints/security-secrets-management/contributions/probes/run-mismatched-key-refusal.mjs +4 -0
  456. package/blueprints/security-secrets-management/docs/topics.md +2 -3
  457. package/fixtures/canary-manifest.json +9 -9
  458. package/guidance/harness-template.md +25 -0
  459. package/guidance/managed/agent-instructions-block.hash +1 -1
  460. package/guidance/managed/agent-instructions-block.md +25 -0
  461. package/package.json +2 -2
  462. package/rcf/adrs/adr-4101-feedback-store-gitignored.json +20 -0
  463. package/rcf/adrs/adr-4102-fingerprint-and-labels.json +25 -0
  464. package/rcf/adrs/adr-4103-redaction-rule-based.json +20 -0
  465. package/rcf/adrs/adr-4104-destination-on-library.json +25 -0
  466. package/rcf/adrs/adr-4105-gh-ambient-auth.json +20 -0
  467. package/rcf/adrs/adr-4106-bundled-entries-terminal.json +20 -0
  468. package/rcf/adrs/adr-4107-stop-is-ask-event.json +30 -0
  469. package/rcf/adrs/adr-4108-hooks-in-committed-config.json +25 -0
  470. package/rcf/adrs/adr-4109-referee-validate-adr-crosslinks.json +25 -0
  471. package/rcf/adrs/adr-4110-referee-coverage-strict-by-default.json +25 -0
  472. package/rcf/adrs/adr-4111-referee-finalise-refusals.json +20 -0
  473. package/rcf/adrs/adr-4112-referee-finalise-verified-invariant.json +30 -0
  474. package/rcf/code-nodes/cn-600.json +45 -0
  475. package/rcf/code-nodes/cn-601.json +18 -0
  476. package/rcf/code-nodes/cn-602.json +15 -0
  477. package/rcf/code-nodes/cn-603.json +12 -0
  478. package/rcf/code-nodes/cn-604.json +14 -0
  479. package/rcf/code-nodes/cn-605.json +17 -0
  480. package/rcf/code-nodes/cn-606.json +12 -0
  481. package/rcf/code-nodes/cn-607.json +12 -0
  482. package/rcf/code-nodes/cn-608.json +14 -0
  483. package/rcf/code-nodes/cn-609.json +17 -0
  484. package/rcf/code-nodes/cn-620.json +18 -0
  485. package/rcf/code-nodes/cn-621.json +14 -0
  486. package/rcf/code-nodes/cn-622.json +15 -0
  487. package/rcf/code-nodes/cn-623.json +16 -0
  488. package/rcf/code-nodes/cn-624.json +14 -0
  489. package/rcf/code-nodes/cn-625.json +15 -0
  490. package/rcf/code-nodes/cn-626.json +13 -0
  491. package/rcf/code-nodes/cn-627.json +13 -0
  492. package/rcf/code-nodes/cn-628.json +14 -0
  493. package/rcf/code-nodes/cn-629.json +12 -0
  494. package/rcf/code-nodes/cn-630.json +12 -0
  495. package/rcf/code-nodes/cn-631.json +13 -0
  496. package/rcf/code-nodes/cn-632.json +13 -0
  497. package/rcf/fbs/fbs-180.json +45 -0
  498. package/rcf/fbs/fbs-181.json +45 -0
  499. package/rcf/fbs/fbs-182.json +42 -0
  500. package/rcf/fbs/fbs-183.json +50 -0
  501. package/rcf/fbs/fbs-184.json +49 -0
  502. package/rcf/fbs/fbs-185.json +34 -0
  503. package/rcf/fbs/fbs-186.json +16 -0
  504. package/rcf/fbs/fbs-187.json +17 -0
  505. package/rcf/fbs/fbs-188.json +17 -0
  506. package/rcf/fbs/fbs-189.json +17 -0
  507. package/rcf/requirements/req-155.json +13 -0
  508. package/rcf/requirements/req-156.json +13 -0
  509. package/rcf/requirements/req-157.json +13 -0
  510. package/rcf/requirements/req-158.json +13 -0
  511. package/rcf/requirements/req-159.json +13 -0
  512. package/rcf/requirements/req-160.json +13 -0
  513. package/rcf/requirements/req-161.json +13 -0
  514. package/rcf/requirements/req-162.json +13 -0
  515. package/rcf/requirements/req-163.json +13 -0
  516. package/rcf/requirements/req-164.json +13 -0
  517. package/rcf/requirements/req-165.json +13 -0
  518. package/rcf/tacs/tac-4101-feedback-cli.json +77 -0
  519. package/rcf/tacs/tac-4102-feedback-store.json +50 -0
  520. package/rcf/tacs/tac-4103-feedback-redact.json +39 -0
  521. package/rcf/tacs/tac-4104-feedback-fingerprint.json +33 -0
  522. package/rcf/tacs/tac-4105-feedback-render.json +45 -0
  523. package/rcf/tacs/tac-4106-feedback-destination.json +39 -0
  524. package/rcf/tacs/tac-4107-feedback-gh.json +43 -0
  525. package/rcf/tacs/tac-4108-feedback-hook.json +46 -0
  526. package/rcf/tacs/tac-4109-referee-validate-adr-crosslinks.json +20 -0
  527. package/rcf/tacs/tac-4110-referee-coverage-mode-selector.json +21 -0
  528. package/rcf/tacs/tac-4111-referee-finalise-per-ac-refusals.json +21 -0
  529. package/rcf/tacs/tac-4112-referee-finalise-verified-invariant.json +22 -0
  530. package/rcf/test-suites/ts-140.json +9 -9
  531. package/rcf/test-suites/ts-150.json +9 -9
  532. package/rcf/test-suites/ts-185.json +54 -0
  533. package/rcf/test-suites/ts-186.json +58 -0
  534. package/rcf/test-suites/ts-187.json +44 -0
  535. package/rcf/test-suites/ts-188.json +166 -0
  536. package/rcf/test-suites/ts-189.json +38 -0
  537. package/rcf/test-suites/ts-190.json +30 -0
  538. package/rcf/test-suites/ts-191.json +51 -0
  539. package/rcf/test-suites/ts-192.json +37 -0
  540. package/rcf/test-suites/ts-193.json +60 -0
  541. package/rcf/test-suites/ts-194.json +67 -0
  542. package/rcf/test-suites/ts-195.json +52 -0
  543. package/rcf/test-suites/ts-196.json +58 -0
  544. package/rcf/test-suites/ts-197.json +66 -0
  545. package/rcf/test-suites/ts-198.json +87 -0
  546. package/rcf/test-suites/ts-199.json +51 -0
  547. package/rcf/test-suites/ts-200.json +30 -0
  548. package/rcf/test-suites/ts-201.json +38 -0
  549. package/rcf/test-suites/ts-202.json +38 -0
  550. package/rcf/test-suites/ts-203.json +38 -0
  551. package/rcf/user-stories/us-15501.json +60 -0
  552. package/rcf/user-stories/us-15502.json +33 -0
  553. package/rcf/user-stories/us-15503.json +33 -0
  554. package/rcf/user-stories/us-15601.json +51 -0
  555. package/rcf/user-stories/us-15701.json +42 -0
  556. package/rcf/user-stories/us-15801.json +42 -0
  557. package/rcf/user-stories/us-15802.json +33 -0
  558. package/rcf/user-stories/us-15901.json +33 -0
  559. package/rcf/user-stories/us-15902.json +51 -0
  560. package/rcf/user-stories/us-16001.json +51 -0
  561. package/rcf/user-stories/us-16101.json +42 -0
  562. package/rcf/user-stories/us-16102.json +33 -0
  563. package/rcf/user-stories/us-16103.json +42 -0
  564. package/rcf/user-stories/us-16104.json +42 -0
  565. package/rcf/user-stories/us-16201.json +33 -0
  566. package/rcf/user-stories/us-16301.json +36 -0
  567. package/rcf/user-stories/us-16401.json +45 -0
  568. package/rcf/user-stories/us-16501.json +45 -0
  569. package/rcf/user-stories/us-16502.json +45 -0
  570. package/releases/releases.yaml +11 -1
  571. package/src/blueprint/library-loader.js +48 -0
  572. package/src/blueprint/library-registry.js +13 -0
  573. package/src/browser-verify/pack-runner.js +7 -12
  574. package/src/build/mark.js +1 -1
  575. package/src/cli/blueprint-library.js +149 -0
  576. package/src/cli/coverage.js +49 -24
  577. package/src/cli/doctor.js +195 -7
  578. package/src/cli/feedback.js +2204 -0
  579. package/src/cli/finalise.js +158 -1
  580. package/src/cli/help.js +6 -0
  581. package/src/cli/init.js +63 -0
  582. package/src/cli/update.js +21 -1
  583. package/src/core/store/walker.js +33 -0
  584. package/src/core/store/writer.js +23 -0
  585. package/src/feedback/destination.js +361 -0
  586. package/src/feedback/fingerprint.js +132 -0
  587. package/src/feedback/gh.js +376 -0
  588. package/src/feedback/hook.js +183 -0
  589. package/src/feedback/labels.js +87 -0
  590. package/src/feedback/redact-allowlist.json +14 -0
  591. package/src/feedback/redact.js +1108 -0
  592. package/src/feedback/render.js +267 -0
  593. package/src/feedback/store.js +604 -0
  594. package/src/finalise/index.js +4 -0
  595. package/src/finalise/ingest.js +61 -0
  596. package/src/finalise/ship-without-eval.js +19 -7
  597. package/src/mcp/tools.js +8 -2
  598. package/src/setup/feedback-hooks.js +397 -0
  599. package/src/setup/managed-gitignore.js +3 -0
  600. package/src/view/html-page.js +5 -5
  601. package/src/view/style.css +2 -2
@@ -1,28 +1,72 @@
1
- // Probe: real-account cloud-init hardened.
1
+ // Probe: real-account cloud-init hardened (v1.1.5).
2
2
  //
3
3
  // anchorAcId: AC-37105-1. accountBound: true.
4
4
  //
5
- // Without CI_HAS_HETZNER_ACCOUNT the probe records
6
- // accountBoundSkipped: true and the aggregate flips to pass.
7
- //
8
- // With the env var set the probe:
9
- // - provisions the throwaway server via the fixture provision.mjs;
10
- // - shells cloud-init status --wait over ssh to the throwaway server;
11
- // - runs the six baseline checks over ssh (grep for the marker per
12
- // baseline block); FAILS naming the first missing block on any
13
- // defect.
14
- // - always() calls destroy.mjs regardless of verdict.
5
+ // Contract:
6
+ // - First-tier gate CI_HAS_HETZNER_ACCOUNT must equal exactly the
7
+ // string "true"; anything else records an honest skip row.
8
+ // - Second-tier HCLOUD_TOKEN missing carries its own honest skip row.
9
+ // - The pass row carries an `evidence` object with the created
10
+ // server id, the ssh readiness result, the cloud-init status exit
11
+ // code and every baseline block's stdout excerpt (bounded).
12
+ // - A non-zero exit from `cloud-init status --wait` FAILS the
13
+ // verdict; the six baseline checks that follow are diagnostic in
14
+ // that case rather than the verdict.
15
+ // - Teardown lives in a finally block and its failure FAILS the
16
+ // verdict (the shape rule).
15
17
 
16
- import { accountBoundSkippedResult, FIXTURE_DIR } from './probe-utils.mjs';
18
+ import { spawn } from 'node:child_process';
17
19
  import { resolve } from 'node:path';
20
+ import {
21
+ firstTierGateSkipResult, secondTierMissingSkipResult, FIXTURE_DIR,
22
+ } from './probe-utils.mjs';
18
23
 
19
24
  export const anchorAcId = 'AC-37105-1';
20
25
  export const accountBound = true;
21
26
 
27
+ function hcloudJson(argv, { timeoutMs = 60_000 } = {}) {
28
+ return new Promise((resolvePromise, reject) => {
29
+ const p = spawn('hcloud', argv, { stdio: ['ignore', 'pipe', 'pipe'] });
30
+ let stdout = '';
31
+ let stderr = '';
32
+ const timer = setTimeout(() => { try { p.kill('SIGKILL'); } catch (_) {} reject(new Error(`hcloud ${argv.join(' ')} timed out after ${timeoutMs}ms`)); }, timeoutMs);
33
+ p.stdout.on('data', (d) => { stdout += d.toString(); });
34
+ p.stderr.on('data', (d) => { stderr += d.toString(); });
35
+ p.on('error', (err) => { clearTimeout(timer); reject(err); });
36
+ p.on('close', (code) => {
37
+ clearTimeout(timer);
38
+ if (code !== 0) return reject(new Error(`hcloud ${argv.join(' ')} exited ${code}: ${stderr}`));
39
+ const trimmed = stdout.trim();
40
+ if (trimmed.length === 0) return resolvePromise([]);
41
+ try {
42
+ const parsed = JSON.parse(trimmed);
43
+ resolvePromise(Array.isArray(parsed) ? parsed : (parsed.servers || []));
44
+ } catch (err) {
45
+ reject(new Error(`hcloud stdout not JSON: ${err.message}`));
46
+ }
47
+ });
48
+ });
49
+ }
50
+
22
51
  export default async function runProbe() {
23
52
  if (process.env.CI_HAS_HETZNER_ACCOUNT !== 'true') {
24
53
  return {
25
- results: [accountBoundSkippedResult(anchorAcId, 'real-account cloud-init hardened check skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise the six ssh baseline checks against a throwaway cx23.')],
54
+ results: [firstTierGateSkipResult(
55
+ anchorAcId,
56
+ 'CI_HAS_HETZNER_ACCOUNT',
57
+ 'real-account cloud-init hardened check skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise the six ssh baseline checks against a throwaway cx23.',
58
+ )],
59
+ extra: { skipped: true, missingEnv: ['CI_HAS_HETZNER_ACCOUNT'] },
60
+ };
61
+ }
62
+ if (!process.env.HCLOUD_TOKEN) {
63
+ return {
64
+ results: [secondTierMissingSkipResult(
65
+ anchorAcId,
66
+ 'HCLOUD_TOKEN',
67
+ 'the throwaway server cannot be provisioned without HCLOUD_TOKEN.',
68
+ )],
69
+ extra: { skipped: true, missingEnv: ['HCLOUD_TOKEN'] },
26
70
  };
27
71
  }
28
72
  const provisionPath = resolve(FIXTURE_DIR, 'provision.mjs');
@@ -31,34 +75,71 @@ export default async function runProbe() {
31
75
  const { provisionThrowawayServer } = await import(provisionPath);
32
76
  const { destroyThrowawayServer } = await import(destroyPath);
33
77
  const { runSshBaselineChecks } = await import(sshCheckPath);
78
+
79
+ const evidence = {};
80
+ const resultRow = { anchorAcId, verdict: 'fail', detail: '', evidence };
34
81
  let provisioned;
35
82
  try {
36
83
  provisioned = await provisionThrowawayServer({ runId: process.env.GITHUB_RUN_ID ?? 'local' });
84
+ evidence.serverId = provisioned.id;
85
+ evidence.serverName = provisioned.name;
86
+ evidence.primaryIpv4 = provisioned.primaryIpv4;
37
87
  const report = await runSshBaselineChecks(provisioned);
88
+ evidence.sshReadiness = report.readiness;
89
+ evidence.cloudInit = report.cloudInit;
90
+ evidence.baselineChecks = report.checks.map((c) => ({
91
+ id: c.id,
92
+ verdict: c.verdict,
93
+ stdoutExcerpt: (c.detail || '').slice(0, 200),
94
+ }));
95
+ // Rule 6 of the fix list: cloud-init non-zero FAILS the verdict.
96
+ if (!report.cloudInit || report.cloudInit.code !== 0) {
97
+ resultRow.verdict = 'fail';
98
+ resultRow.detail = `cloud-init status --wait exited ${report.cloudInit ? report.cloudInit.code : 'null'} on server ${provisioned.id}; the ssh baseline checks are diagnostic and do not carry the verdict when cloud-init did not reach a terminal success state. stderr: ${(report.cloudInit && report.cloudInit.stderr) || ''}`;
99
+ return { results: [resultRow], extra: evidence };
100
+ }
38
101
  const failed = report.checks.filter((c) => c.verdict === 'fail');
39
102
  if (failed.length > 0) {
40
- return {
41
- results: failed.map((c) => ({
42
- anchorAcId,
43
- verdict: 'fail',
44
- detail: `cloud-init baseline block "${c.label}" failed on server ${provisioned.id}: ${c.detail}`,
45
- })),
46
- };
103
+ // Fail with per-block detail on the FIRST failing block so the
104
+ // result row carries a specific failure locus; the full check
105
+ // list is in evidence.baselineChecks.
106
+ const first = failed[0];
107
+ resultRow.verdict = 'fail';
108
+ resultRow.detail = `cloud-init baseline block "${first.label}" failed on server ${provisioned.id}: ${first.detail}`;
109
+ return { results: [resultRow], extra: evidence };
47
110
  }
48
111
  const blocks = report.checks.filter((c) => c.verdict === 'pass').map((c) => c.id);
49
- return {
50
- results: [{
51
- anchorAcId,
52
- verdict: 'pass',
53
- detail: `cloud-init reached terminal state on server ${provisioned.id} (cloud-init status --wait exit ${report.cloudInit ? report.cloudInit.code : 'skipped'}); six baseline hardening blocks observed: ${blocks.join(', ')}.`,
54
- }],
55
- extra: report,
56
- };
112
+ resultRow.verdict = 'pass';
113
+ resultRow.detail = `cloud-init reached terminal state on server ${provisioned.id} (cloud-init status --wait exit 0); six baseline hardening blocks observed: ${blocks.join(', ')}.`;
57
114
  } catch (err) {
58
- return { results: [{ anchorAcId, verdict: 'fail', detail: `check failed: ${err.message}` }] };
115
+ resultRow.verdict = 'fail';
116
+ resultRow.detail = `check failed: ${err.message}`;
117
+ evidence.checkError = err.message;
118
+ return { results: [resultRow], extra: evidence };
59
119
  } finally {
60
120
  if (provisioned && provisioned.id) {
61
- try { await destroyThrowawayServer(provisioned); } catch (_) { /* swept by orphan cron */ }
121
+ try {
122
+ await destroyThrowawayServer(provisioned);
123
+ evidence.teardown = { destroyed: provisioned.id };
124
+ try {
125
+ const finalList = await hcloudJson(['server', 'list', '--output', 'json']);
126
+ evidence.postTeardownServerIds = finalList.map((s) => s.id);
127
+ if (finalList.some((s) => s.id === provisioned.id)) {
128
+ resultRow.verdict = 'fail';
129
+ resultRow.detail = `${resultRow.detail} TEARDOWN INCOMPLETE: server ${provisioned.id} still present in hcloud server list.`;
130
+ }
131
+ } catch (err) {
132
+ evidence.postTeardownListError = err.message;
133
+ resultRow.verdict = 'fail';
134
+ resultRow.detail = `${resultRow.detail} TEARDOWN CONFIRMATION FAILED: post-teardown hcloud server list threw (${err.message}); cannot confirm server ${provisioned.id} was removed.`;
135
+ }
136
+ } catch (err) {
137
+ resultRow.verdict = 'fail';
138
+ resultRow.detail = `${resultRow.detail} TEARDOWN FAILED for server ${provisioned.id}: ${err.message}.`;
139
+ evidence.teardownError = err.message;
140
+ evidence.orphanServerId = provisioned.id;
141
+ }
62
142
  }
63
143
  }
144
+ return { results: [resultRow], extra: evidence };
64
145
  }
@@ -1,30 +1,72 @@
1
- // Probe: real-account snapshot on demand.
1
+ // Probe: real-account snapshot on demand (v1.1.5).
2
2
  //
3
3
  // anchorAcId: AC-37108-1. accountBound: true.
4
4
  //
5
- // Without CI_HAS_HETZNER_ACCOUNT the probe records
6
- // accountBoundSkipped: true and the aggregate flips to pass.
7
- //
8
- // With the env var set the probe:
9
- // - provisions the throwaway server via provision.mjs;
10
- // - fires the snapshot verb on the provisioner facade;
11
- // - asserts hcloud image list --type=snapshot --output json shows a
12
- // snapshot with the server name and current wall-clock time in the
13
- // labels;
14
- // - always() calls destroy.mjs regardless of verdict; the snapshot is
15
- // deleted as part of destroy.mjs so the run leaves no orphaned
16
- // image behind.
5
+ // Contract:
6
+ // - First-tier gate CI_HAS_HETZNER_ACCOUNT must equal exactly the
7
+ // string "true"; anything else records an honest skip row.
8
+ // - Second-tier HCLOUD_TOKEN missing carries its own honest skip row.
9
+ // - The pass row carries an `evidence` object with the created
10
+ // server id, the pre- and post-snapshot inventory (proving the
11
+ // snapshot id was created then deleted), the snapshot id, the
12
+ // hetznerSnapshotTaken event shape (serverName, snapshotId, ts),
13
+ // and the label-match evidence.
14
+ // - Teardown failure FAILS the verdict (the shape rule); the
15
+ // evidence tree carries the orphan snapshot id and server id when
16
+ // the destroy leaks.
17
17
 
18
- import { accountBoundSkippedResult, FIXTURE_DIR } from './probe-utils.mjs';
18
+ import { spawn } from 'node:child_process';
19
19
  import { resolve } from 'node:path';
20
+ import {
21
+ firstTierGateSkipResult, secondTierMissingSkipResult, FIXTURE_DIR,
22
+ } from './probe-utils.mjs';
20
23
 
21
24
  export const anchorAcId = 'AC-37108-1';
22
25
  export const accountBound = true;
23
26
 
27
+ function hcloudJson(argv, { timeoutMs = 60_000 } = {}) {
28
+ return new Promise((resolvePromise, reject) => {
29
+ const p = spawn('hcloud', argv, { stdio: ['ignore', 'pipe', 'pipe'] });
30
+ let stdout = '';
31
+ let stderr = '';
32
+ const timer = setTimeout(() => { try { p.kill('SIGKILL'); } catch (_) {} reject(new Error(`hcloud ${argv.join(' ')} timed out after ${timeoutMs}ms`)); }, timeoutMs);
33
+ p.stdout.on('data', (d) => { stdout += d.toString(); });
34
+ p.stderr.on('data', (d) => { stderr += d.toString(); });
35
+ p.on('error', (err) => { clearTimeout(timer); reject(err); });
36
+ p.on('close', (code) => {
37
+ clearTimeout(timer);
38
+ if (code !== 0) return reject(new Error(`hcloud ${argv.join(' ')} exited ${code}: ${stderr}`));
39
+ const trimmed = stdout.trim();
40
+ if (trimmed.length === 0) return resolvePromise([]);
41
+ try {
42
+ const parsed = JSON.parse(trimmed);
43
+ resolvePromise(Array.isArray(parsed) ? parsed : (parsed.images || parsed.servers || []));
44
+ } catch (err) {
45
+ reject(new Error(`hcloud stdout not JSON: ${err.message}`));
46
+ }
47
+ });
48
+ });
49
+ }
50
+
24
51
  export default async function runProbe() {
25
52
  if (process.env.CI_HAS_HETZNER_ACCOUNT !== 'true') {
26
53
  return {
27
- results: [accountBoundSkippedResult(anchorAcId, 'real-account snapshot on-demand skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise the hcloud image create-image path.')],
54
+ results: [firstTierGateSkipResult(
55
+ anchorAcId,
56
+ 'CI_HAS_HETZNER_ACCOUNT',
57
+ 'real-account snapshot on-demand skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise the hcloud server create-image path.',
58
+ )],
59
+ extra: { skipped: true, missingEnv: ['CI_HAS_HETZNER_ACCOUNT'] },
60
+ };
61
+ }
62
+ if (!process.env.HCLOUD_TOKEN) {
63
+ return {
64
+ results: [secondTierMissingSkipResult(
65
+ anchorAcId,
66
+ 'HCLOUD_TOKEN',
67
+ 'the snapshot verb cannot be issued without HCLOUD_TOKEN.',
68
+ )],
69
+ extra: { skipped: true, missingEnv: ['HCLOUD_TOKEN'] },
28
70
  };
29
71
  }
30
72
  const provisionPath = resolve(FIXTURE_DIR, 'provision.mjs');
@@ -33,28 +75,114 @@ export default async function runProbe() {
33
75
  const { provisionThrowawayServer } = await import(provisionPath);
34
76
  const { destroyThrowawayServer } = await import(destroyPath);
35
77
  const { takeAndVerifySnapshot } = await import(snapshotPath);
78
+
79
+ const evidence = {};
80
+ const resultRow = { anchorAcId, verdict: 'fail', detail: '', evidence };
36
81
  let provisioned;
82
+ // Observed events on injected sinks (defect): the snapshot
83
+ // verb emits hetznerSnapshotTaken; the provision emits
84
+ // hetznerServerProvisioned. Both are OBSERVED, not constructed here.
85
+ const observedEvents = [];
86
+ const eventSink = (body) => observedEvents.push(body);
37
87
  try {
38
- provisioned = await provisionThrowawayServer({ runId: process.env.GITHUB_RUN_ID ?? 'local' });
39
- const outcome = await takeAndVerifySnapshot(provisioned);
88
+ // Pre-snapshot inventory: capture the snapshot ids present before
89
+ // the run so the inventory-diff evidence shape is honest.
90
+ try {
91
+ const baseline = await hcloudJson(['image', 'list', '--type=snapshot', '--output', 'json']);
92
+ evidence.baselineSnapshotIds = baseline.map((s) => s.id);
93
+ } catch (err) {
94
+ evidence.baselineListError = err.message;
95
+ }
96
+ provisioned = await provisionThrowawayServer({
97
+ runId: process.env.GITHUB_RUN_ID ?? 'local',
98
+ eventSink,
99
+ });
100
+ evidence.serverId = provisioned.id;
101
+ evidence.serverName = provisioned.name;
102
+ const outcome = await takeAndVerifySnapshot(provisioned, { eventSink });
103
+ evidence.snapshotId = outcome.snapshotId;
104
+ evidence.wallClockTime = outcome.wallClockTime;
105
+ evidence.labelMatch = outcome.match ? {
106
+ id: outcome.match.id,
107
+ serverNameLabel: (outcome.match.labels || {}).serverName,
108
+ } : null;
109
+ // OBSERVE the hetznerSnapshotTaken event from the sink. The event
110
+ // body is derived by snapshot-verb.mjs after the vendor list call
111
+ // confirmed the id landed (defect: was constructed here
112
+ // in v1.1.4; now observed from the sink emit).
113
+ evidence.observedEvents = observedEvents.map((e) => ({ event: e.event, keys: Object.keys(e).sort() }));
114
+ const snapshotEvent = observedEvents.find((e) => e && e.event === 'hetznerSnapshotTaken');
115
+ if (outcome.snapshotId && !snapshotEvent) {
116
+ resultRow.verdict = 'fail';
117
+ resultRow.detail = `snapshot verb returned snapshotId ${outcome.snapshotId} but no hetznerSnapshotTaken event was observed on the injected sink; AC-37108-3 event-shape observation is missing.`;
118
+ evidence.eventName = 'hetznerSnapshotTaken';
119
+ evidence.eventObserved = false;
120
+ return { results: [resultRow], extra: evidence };
121
+ }
122
+ evidence.hetznerSnapshotTakenEvent = snapshotEvent ?? null;
123
+ // Post-create inventory: prove the id appears in the vendor
124
+ // snapshot list so the AC's inventory-diff evidence is real.
125
+ try {
126
+ const afterCreate = await hcloudJson(['image', 'list', '--type=snapshot', '--output', 'json']);
127
+ evidence.postCreateSnapshotIds = afterCreate.map((s) => s.id);
128
+ evidence.postCreateSnapshotCarriedId = !!(outcome.snapshotId && afterCreate.some((s) => s.id === outcome.snapshotId));
129
+ } catch (err) {
130
+ evidence.postCreateListError = err.message;
131
+ }
40
132
  if (!outcome.snapshotId) {
41
- return {
42
- results: [{ anchorAcId, verdict: 'fail', detail: `snapshot verb ran but no matching snapshot appeared in hcloud image list.` }],
43
- };
133
+ resultRow.verdict = 'fail';
134
+ resultRow.detail = `snapshot verb ran but no matching snapshot appeared in hcloud image list; the AC's inventory-diff evidence is missing.`;
135
+ return { results: [resultRow], extra: evidence };
44
136
  }
45
- return {
46
- results: [{
47
- anchorAcId,
48
- verdict: 'pass',
49
- detail: `snapshot ${outcome.snapshotId} tagged with server name ${provisioned.name} and time ${outcome.wallClockTime} on server ${provisioned.id}.`,
50
- }],
51
- extra: outcome,
52
- };
137
+ resultRow.verdict = 'pass';
138
+ resultRow.detail = `snapshot ${outcome.snapshotId} created against server ${provisioned.id} (${provisioned.name}); hcloud image list --type=snapshot carries the id; hetznerSnapshotTaken event shape {serverName, snapshotId, ts} confirmed.`;
53
139
  } catch (err) {
54
- return { results: [{ anchorAcId, verdict: 'fail', detail: `snapshot verb threw: ${err.message}` }] };
140
+ resultRow.verdict = 'fail';
141
+ resultRow.detail = `snapshot verb threw: ${err.message}`;
142
+ evidence.snapshotError = err.message;
143
+ return { results: [resultRow], extra: evidence };
55
144
  } finally {
56
145
  if (provisioned && provisioned.id) {
57
- try { await destroyThrowawayServer(provisioned); } catch (_) { /* swept by orphan cron */ }
146
+ try {
147
+ await destroyThrowawayServer(provisioned);
148
+ evidence.teardown = { destroyed: provisioned.id };
149
+ // Confirm the snapshot AND the server were both removed;
150
+ // destroy.mjs sweeps snapshots that carry the server-name
151
+ // label in the same call, so the post-teardown snapshot list
152
+ // must NOT carry the id.
153
+ try {
154
+ const finalSnaps = await hcloudJson(['image', 'list', '--type=snapshot', '--output', 'json']);
155
+ evidence.postTeardownSnapshotIds = finalSnaps.map((s) => s.id);
156
+ if (evidence.snapshotId && finalSnaps.some((s) => s.id === evidence.snapshotId)) {
157
+ resultRow.verdict = 'fail';
158
+ resultRow.detail = `${resultRow.detail} TEARDOWN INCOMPLETE: snapshot ${evidence.snapshotId} still present.`;
159
+ evidence.orphanSnapshotId = evidence.snapshotId;
160
+ }
161
+ } catch (err) {
162
+ evidence.postTeardownListError = err.message;
163
+ resultRow.verdict = 'fail';
164
+ resultRow.detail = `${resultRow.detail} TEARDOWN CONFIRMATION FAILED: post-teardown snapshot list threw (${err.message}); cannot confirm snapshot ${evidence.snapshotId || 'n/a'} was deleted.`;
165
+ }
166
+ try {
167
+ const finalServers = await hcloudJson(['server', 'list', '--output', 'json']);
168
+ evidence.postTeardownServerIds = finalServers.map((s) => s.id);
169
+ if (finalServers.some((s) => s.id === provisioned.id)) {
170
+ resultRow.verdict = 'fail';
171
+ resultRow.detail = `${resultRow.detail} TEARDOWN INCOMPLETE: server ${provisioned.id} still present.`;
172
+ }
173
+ } catch (err) {
174
+ evidence.postTeardownServerListError = err.message;
175
+ resultRow.verdict = 'fail';
176
+ resultRow.detail = `${resultRow.detail} TEARDOWN CONFIRMATION FAILED: post-teardown server list threw (${err.message}); cannot confirm server ${provisioned.id} was removed.`;
177
+ }
178
+ } catch (err) {
179
+ resultRow.verdict = 'fail';
180
+ resultRow.detail = `${resultRow.detail} TEARDOWN FAILED for server ${provisioned.id}: ${err.message}.`;
181
+ evidence.teardownError = err.message;
182
+ evidence.orphanServerId = provisioned.id;
183
+ if (evidence.snapshotId) evidence.orphanSnapshotId = evidence.snapshotId;
184
+ }
58
185
  }
59
186
  }
187
+ return { results: [resultRow], extra: evidence };
60
188
  }
@@ -1,58 +1,180 @@
1
- // Probe: real-account throwaway-server provision.
1
+ // Probe: real-account throwaway-server provision (v1.1.5).
2
2
  //
3
3
  // anchorAcId: AC-37103-1. accountBound: true.
4
4
  //
5
- // Without CI_HAS_HETZNER_ACCOUNT the probe records
6
- // accountBoundSkipped: true and the aggregate flips to pass per
7
- // hetzner-round-7-spec-2026-09-07.md section 3.5.
8
- //
9
- // With the env var set the probe:
10
- // - runs the fixture's provision.mjs against the ci-throwaway manifest;
11
- // - asserts a new server appears in `hcloud server list --output json`
12
- // whose id matches the scratch-file-written id;
13
- // - asserts the fixture's captured hetznerServerProvisioned event
14
- // carries id, primaryIpv4, location=fsn1, serverType=cx23;
15
- // - always() calls destroy.mjs so the throwaway server is torn down
16
- // regardless of verdict.
5
+ // Contract:
6
+ // - First-tier gate CI_HAS_HETZNER_ACCOUNT must equal exactly the
7
+ // string "true"; anything else records an honest skip row naming
8
+ // the variable (set-but-not-true distinguished from unset).
9
+ // - Second-tier HCLOUD_TOKEN must be set once past the first-tier
10
+ // gate; missing carries its own honest skip row naming HCLOUD_TOKEN.
11
+ // - The pass row carries an `evidence` object with the created
12
+ // server id, the pre-provision inventory count, the post-provision
13
+ // inventory entry proving the id landed, the primaryIpv4, location
14
+ // and serverType observed on the vendor payload, plus the emitted
15
+ // `hetznerServerProvisioned` event shape (event names only, no
16
+ // token bytes).
17
+ // - Teardown lives in a finally block and its failure FAILS the
18
+ // verdict; the evidence carries the surviving orphan id so a
19
+ // later sweep-orphans run can find it.
17
20
 
18
- import { accountBoundSkippedResult, FIXTURE_DIR } from './probe-utils.mjs';
21
+ import { spawn } from 'node:child_process';
19
22
  import { resolve } from 'node:path';
23
+ import {
24
+ firstTierGateSkipResult, secondTierMissingSkipResult, FIXTURE_DIR,
25
+ } from './probe-utils.mjs';
20
26
 
21
27
  export const anchorAcId = 'AC-37103-1';
22
28
  export const accountBound = true;
23
29
 
30
+ function hcloudJson(argv, { timeoutMs = 60_000 } = {}) {
31
+ return new Promise((resolvePromise, reject) => {
32
+ const p = spawn('hcloud', argv, { stdio: ['ignore', 'pipe', 'pipe'] });
33
+ let stdout = '';
34
+ let stderr = '';
35
+ const timer = setTimeout(() => { try { p.kill('SIGKILL'); } catch (_) {} reject(new Error(`hcloud ${argv.join(' ')} timed out after ${timeoutMs}ms`)); }, timeoutMs);
36
+ p.stdout.on('data', (d) => { stdout += d.toString(); });
37
+ p.stderr.on('data', (d) => { stderr += d.toString(); });
38
+ p.on('error', (err) => { clearTimeout(timer); reject(err); });
39
+ p.on('close', (code) => {
40
+ clearTimeout(timer);
41
+ if (code !== 0) return reject(new Error(`hcloud ${argv.join(' ')} exited ${code}: ${stderr}`));
42
+ const trimmed = stdout.trim();
43
+ if (trimmed.length === 0) return resolvePromise([]);
44
+ try {
45
+ const parsed = JSON.parse(trimmed);
46
+ resolvePromise(Array.isArray(parsed) ? parsed : (parsed.servers || []));
47
+ } catch (err) {
48
+ reject(new Error(`hcloud stdout not JSON: ${err.message}`));
49
+ }
50
+ });
51
+ });
52
+ }
53
+
24
54
  export default async function runProbe() {
25
55
  if (process.env.CI_HAS_HETZNER_ACCOUNT !== 'true') {
26
56
  return {
27
- results: [accountBoundSkippedResult(anchorAcId, 'real-account throwaway-server provision skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise.')],
57
+ results: [firstTierGateSkipResult(
58
+ anchorAcId,
59
+ 'CI_HAS_HETZNER_ACCOUNT',
60
+ 'real-account throwaway-server provision skipped; run with CI_HAS_HETZNER_ACCOUNT=true to exercise.',
61
+ )],
62
+ extra: { skipped: true, missingEnv: ['CI_HAS_HETZNER_ACCOUNT'] },
63
+ };
64
+ }
65
+ if (!process.env.HCLOUD_TOKEN) {
66
+ return {
67
+ results: [secondTierMissingSkipResult(
68
+ anchorAcId,
69
+ 'HCLOUD_TOKEN',
70
+ 'the shared hetzner-throwaway-server provisioner cannot open without HCLOUD_TOKEN.',
71
+ )],
72
+ extra: { skipped: true, missingEnv: ['HCLOUD_TOKEN'] },
28
73
  };
29
74
  }
30
75
  const provisionPath = resolve(FIXTURE_DIR, 'provision.mjs');
31
76
  const destroyPath = resolve(FIXTURE_DIR, 'destroy.mjs');
32
77
  const { provisionThrowawayServer } = await import(provisionPath);
33
78
  const { destroyThrowawayServer } = await import(destroyPath);
79
+
80
+ const evidence = {};
34
81
  let provisioned;
82
+ const resultRow = { anchorAcId, verdict: 'fail', detail: '', evidence };
83
+ // Observed event sink (defect). We OBSERVE the emitted
84
+ // hetznerServerProvisioned event rather than constructing one from
85
+ // the return value.
86
+ const observedEvents = [];
87
+ const eventSink = (body) => observedEvents.push(body);
35
88
  try {
36
- provisioned = await provisionThrowawayServer({ runId: process.env.GITHUB_RUN_ID ?? 'local' });
37
- return {
38
- results: [{
39
- anchorAcId,
40
- verdict: 'pass',
41
- detail: `throwaway server ${provisioned.id} provisioned; hetznerServerProvisioned event captured; primaryIpv4=${provisioned.primaryIpv4} location=${provisioned.location} serverType=${provisioned.serverType}.`,
42
- }],
43
- extra: { serverId: provisioned.id, primaryIpv4: provisioned.primaryIpv4 },
44
- };
89
+ let baselineList = [];
90
+ try {
91
+ baselineList = await hcloudJson(['server', 'list', '--output', 'json']);
92
+ evidence.baselineServerIds = baselineList.map((s) => s.id);
93
+ } catch (err) {
94
+ // Baseline list is diagnostic; capture error but do not fail.
95
+ evidence.baselineListError = err.message;
96
+ }
97
+ provisioned = await provisionThrowawayServer({
98
+ runId: process.env.GITHUB_RUN_ID ?? 'local',
99
+ eventSink,
100
+ });
101
+ evidence.serverId = provisioned.id;
102
+ evidence.serverName = provisioned.name;
103
+ evidence.primaryIpv4 = provisioned.primaryIpv4;
104
+ evidence.location = provisioned.location;
105
+ evidence.serverType = provisioned.serverType;
106
+ // OBSERVE the emitted event from the sink; do not manufacture it.
107
+ const provisionedEvent = observedEvents.find((e) => e && e.event === 'hetznerServerProvisioned');
108
+ evidence.observedEvents = observedEvents.map((e) => ({ event: e.event, keys: Object.keys(e).sort() }));
109
+ if (!provisionedEvent) {
110
+ resultRow.verdict = 'fail';
111
+ resultRow.detail = `hetznerServerProvisioned event was not observed on the injected sink after provisionThrowawayServer returned id ${provisioned.id}.`;
112
+ evidence.eventName = 'hetznerServerProvisioned';
113
+ evidence.eventObserved = false;
114
+ return { results: [resultRow], extra: evidence };
115
+ }
116
+ evidence.hetznerServerProvisionedEvent = provisionedEvent;
117
+ // Observe the server-list AFTER provision to prove the id landed.
118
+ // A list failure at this step FAILS the row (defect:
119
+ // the new list failure is no longer allowed to continue to pass).
120
+ let postListError = null;
121
+ try {
122
+ const postList = await hcloudJson(['server', 'list', '--output', 'json']);
123
+ evidence.postProvisionServerIds = postList.map((s) => s.id);
124
+ const match = postList.find((s) => s.id === provisioned.id);
125
+ evidence.postProvisionMatch = match ? { id: match.id, name: match.name, status: match.status } : null;
126
+ if (!match) {
127
+ resultRow.verdict = 'fail';
128
+ resultRow.detail = `provisionThrowawayServer returned id ${provisioned.id} but the post-provision hcloud server list did not carry it; the AC's inventory-diff evidence is missing.`;
129
+ return { results: [resultRow], extra: evidence };
130
+ }
131
+ } catch (err) {
132
+ postListError = err.message;
133
+ evidence.postProvisionListError = postListError;
134
+ resultRow.verdict = 'fail';
135
+ resultRow.detail = `hcloud server list after provision failed (${postListError}); AC-37103-1 requires the live inventory-diff evidence, which could not be observed.`;
136
+ return { results: [resultRow], extra: evidence };
137
+ }
138
+ if (!provisioned.primaryIpv4 || provisioned.location !== 'fsn1' || provisioned.serverType !== 'cx23') {
139
+ resultRow.verdict = 'fail';
140
+ resultRow.detail = `hetznerServerProvisioned payload malformed: expected primaryIpv4, location=fsn1, serverType=cx23; observed ${JSON.stringify(evidence.hetznerServerProvisionedEvent)}.`;
141
+ return { results: [resultRow], extra: evidence };
142
+ }
143
+ resultRow.verdict = 'pass';
144
+ resultRow.detail = `throwaway server ${provisioned.id} provisioned in fsn1; hetznerServerProvisioned event OBSERVED on the injected sink (id ${provisioned.id}, primaryIpv4 ${provisioned.primaryIpv4}, serverType cx23); post-provision hcloud server list carries the id.`;
45
145
  } catch (err) {
46
- return {
47
- results: [{
48
- anchorAcId,
49
- verdict: 'fail',
50
- detail: `provision failed: ${err.message}`,
51
- }],
52
- };
146
+ resultRow.verdict = 'fail';
147
+ resultRow.detail = `provision failed: ${err.message}`;
148
+ evidence.provisionError = err.message;
149
+ return { results: [resultRow], extra: evidence };
53
150
  } finally {
54
151
  if (provisioned && provisioned.id) {
55
- try { await destroyThrowawayServer(provisioned); } catch (_) { /* swept by orphan cron */ }
152
+ try {
153
+ await destroyThrowawayServer(provisioned);
154
+ evidence.teardown = { destroyed: provisioned.id };
155
+ // Confirm absence by re-listing. Failure to confirm FAILS the
156
+ // row ( Item on partly-fixed teardown: post-teardown
157
+ // inventory failures were being swallowed).
158
+ try {
159
+ const finalList = await hcloudJson(['server', 'list', '--output', 'json']);
160
+ evidence.postTeardownServerIds = finalList.map((s) => s.id);
161
+ if (finalList.some((s) => s.id === provisioned.id)) {
162
+ resultRow.verdict = 'fail';
163
+ resultRow.detail = `${resultRow.detail} TEARDOWN INCOMPLETE: server ${provisioned.id} still present in hcloud server list; sweep-orphans must collect.`;
164
+ }
165
+ } catch (err) {
166
+ evidence.postTeardownListError = err.message;
167
+ resultRow.verdict = 'fail';
168
+ resultRow.detail = `${resultRow.detail} TEARDOWN CONFIRMATION FAILED: post-teardown hcloud server list threw (${err.message}); cannot confirm server ${provisioned.id} was removed.`;
169
+ }
170
+ } catch (err) {
171
+ // Teardown failure fails the verdict (the shape rule).
172
+ resultRow.verdict = 'fail';
173
+ resultRow.detail = `${resultRow.detail} TEARDOWN FAILED for server ${provisioned.id}: ${err.message}. Orphan surfaced through sweep-orphans on next run.`;
174
+ evidence.teardownError = err.message;
175
+ evidence.orphanServerId = provisioned.id;
176
+ }
56
177
  }
57
178
  }
179
+ return { results: [resultRow], extra: evidence };
58
180
  }
@@ -1,12 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.4 - 2026-09-12
4
+
5
+ - The application-admin-console fixture now refuses unauthenticated requests on gated sign-in paths (AC-21815-2), so the admin-console-gate-surface probe supplies a fixture Authorization header when the applied capability set includes zeroTrustGate; the fallback (non-gated) request is unchanged.
6
+
3
7
  ## 1.1.3 - 2026-09-10
4
8
 
5
9
  Positive-evidence rule alignment on the probe pack skip path (authoring standard section 7d); register tidy in shipped prose (no capability change).
6
10
 
7
11
  - Probes and fixture: the account-bound skip return on `contributions/probes/real-account-gated-url.mjs` now carries a `reason` field naming the exact env var(s) that were unset; the same fixture README (`packages/rcf-lite/test/fixtures/cf-edge/README.md`) gains a "Declared env vars" section covering the access-side env-var surface, per authoring standard section 7d. Skip-path probe reports regenerated so the shipped shape carries the new field.
8
- - Closes F-8: README compose bullet and consumer note stripped of internal pattern label.
9
- - Closes F-9: REQ-006 description stripped of internal mechanism label.
10
12
 
11
13
  ## 1.1.2 - 2026-09-10
12
14
 
@@ -21,8 +23,7 @@ Single-mechanism story legality notes; owner reference for the audit-record shap
21
23
 
22
24
  ## 1.1.0 - 2026-09-09
23
25
 
24
- hardening pass edge (criterion a REQ-layer backing; criterion b AC-set sufficiency; criterion c chain consistency lint-zero on pass 1 and pass 2).
25
-
26
+ Adds REQ-007 with its US-34110 binding, and adds failure-path ACs to US-34102, US-34104 and US-34107.
26
27
  - Added REQ-007 and US-34110: the shipped guide names, per policy-shape option, the required dashboard-owned inputs (email domain, group name, identity provider, application-vs-path scope) and every shipped elicit alongside its runtime effect (closes F-1).
27
28
  - Added failure-path ACs to US-34102 (AC-34102-2..5 close F-2: wrong audience, malformed JWT, unknown kid after refresh, JWKS-unavailable fail-closed); US-34104 (AC-34104-2..3 close F-3: neither and both application identifiers refuse apply); US-34107 (AC-34107-2..5 close F-4: break-glass disabled, wrong id, wrong secret via constant-time compare, and partial-pair fall-through).
28
29
  - Every REQ now carries `deliveredBy`; every AC carries `disposition`; ACs referencing owner-owned literals carry `ownerRef`.
@@ -31,7 +32,7 @@ hardening pass edge (criterion a REQ-layer backing; criterion b AC-set sufficien
31
32
 
32
33
 
33
34
  All notable changes to `edge-cloudflare-access` are recorded here. The shape follows Keep a Changelog and Semantic Versioning per the blueprint authoring standard.
34
- - Review fix pass (2026-09-09): split US-34103 into canonical-pass and SIMULATE_NON_VALIDATOR_HEADER-fail ACs, each with a concrete oracle (probe verdict + named field) and an `ownerRef` into TAC-3501. Re-marked ACs per section 7b: mechanism-invariant refusal reasons (`aud-mismatch`, `jwt-malformed`, `kid-unknown`, `jwks-unavailable`, `bypass-id-mismatch`, `bypass-secret-mismatch`, `jwt-missing`), audit-record shapes, guide-section presence assertions and the JWT validator happy path stay `fixed`; US-34104 AC-34104-1 (elicit shape recording), US-34107 AC-34107-1/-3/-4/-5 (bypass id/secret pair) and US-34109 AC-34109-1 (CF_ACCESS_HOST) re-marked `template` naming the values the applying agent sets (access-application-host or access-selfhosted-app-id, access-audience, access-jwks-url, access-policy-shape enum, access-bypass-service-auth-id + paired secret, CF_ACCESS_HOST). Vendor citations added on US-34101 (Cf-Access-Jwt-Assertion header), US-34105 (Zero Trust dashboard docs), US-34107 AC-34107-1 (service-tokens docs) and US-34109 (Access policies docs). Genuinely single-mechanism stories (US-34101, US-34105, US-34106, US-34108, US-34109, US-34110) carry the section-7a note inside the story `description` field, not in a schema-illegal new field.
35
+ - split US-34103 into canonical-pass and SIMULATE_NON_VALIDATOR_HEADER-fail ACs, each with a concrete oracle (probe verdict + named field) and an `ownerRef` into TAC-3501. Re-marked ACs per section 7b: mechanism-invariant refusal reasons (`aud-mismatch`, `jwt-malformed`, `kid-unknown`, `jwks-unavailable`, `bypass-id-mismatch`, `bypass-secret-mismatch`, `jwt-missing`), audit-record shapes, guide-section presence assertions and the JWT validator happy path stay `fixed`; US-34104 AC-34104-1 (elicit shape recording), US-34107 AC-34107-1/-3/-4/-5 (bypass id/secret pair) and US-34109 AC-34109-1 (CF_ACCESS_HOST) re-marked `template` naming the values the applying agent sets (access-application-host or access-selfhosted-app-id, access-audience, access-jwks-url, access-policy-shape enum, access-bypass-service-auth-id + paired secret, CF_ACCESS_HOST). Vendor citations added on US-34101 (Cf-Access-Jwt-Assertion header), US-34105 (Zero Trust dashboard docs), US-34107 AC-34107-1 (service-tokens docs) and US-34109 (Access policies docs). Genuinely single-mechanism stories (US-34101, US-34105, US-34106, US-34108, US-34109, US-34110) carry the section-7a note inside the story `description` field, not in a schema-illegal new field.
35
36
 
36
37
 
37
38
  ## 1.0.0 (2026-09-07)