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,376 @@
1
+ // Feedback gh adapter (TAC-4107-feedback-gh, ADR-4105). The one place
2
+ // that shells out to gh. Slice 4 (FBS-183) ships:
3
+ //
4
+ // - ghAuthStatus({ host }) probe gh auth for a host
5
+ // - ghLabelList({ repo }) list existing label names
6
+ // - ghRepoView({ repo }) visibility + viewerPermission + hasIssuesEnabled
7
+ // - ghIssueSearch({ repo, query, state, limit }) dedupe search
8
+ // - ghIssueCreate({ repo, title, body, labels }) create one issue
9
+ // - ghIssueComment({ repo, number, body }) +1 comment
10
+ // - ghLabelCreate({ repo, name, description, color }) bootstrap only
11
+ //
12
+ // Every function returns a typed result. Errors are classified into
13
+ // { kind: 'network' | 'notFound' | 'ratelimit' | 'client' | 'server' |
14
+ // 'auth' | 'notInstalled' | 'unknown', message, exitCode? }. The
15
+ // tool never spawns `gh auth login`, never reads GH_TOKEN or
16
+ // GITHUB_TOKEN, never mutates process.env.
17
+ //
18
+ // The RCF_FEEDBACK_GH_MODULE env var names an alternative module the
19
+ // caller can import in place of this file; tests use it to record
20
+ // calls without touching gh. This mirrors the verifier launchAgent
21
+ // override in src/verify/engine/launcher.js.
22
+
23
+ import { spawn } from 'node:child_process';
24
+ import process from 'node:process';
25
+
26
+ /**
27
+ * @typedef {object} GhOk
28
+ * @property {true} ok
29
+ * @property {any} value
30
+ */
31
+
32
+ /**
33
+ * @typedef {object} GhErr
34
+ * @property {false} ok
35
+ * @property {'network' | 'notFound' | 'ratelimit' | 'client' | 'server' | 'auth' | 'notInstalled' | 'search-unavailable' | 'unknown'} kind
36
+ * @property {string} message
37
+ * @property {number} [exitCode]
38
+ */
39
+
40
+ /** @typedef {GhOk | GhErr} GhResult */
41
+
42
+ const DEFAULT_HOST = 'github.com';
43
+
44
+ /**
45
+ * Load the gh adapter. When RCF_FEEDBACK_GH_MODULE is set, import that
46
+ * module and return it; otherwise return this module's own default
47
+ * exports. The consumer (`src/cli/feedback.js:handleSubmit`) calls
48
+ * this once per invocation.
49
+ *
50
+ * @param {NodeJS.ProcessEnv} [env]
51
+ * @returns {Promise<GhAdapter>}
52
+ */
53
+ export async function loadGhAdapter(env = process.env) {
54
+ const override = env.RCF_FEEDBACK_GH_MODULE;
55
+ if (typeof override === 'string' && override.length > 0) {
56
+ const mod = await import(override);
57
+ return normaliseAdapter(mod);
58
+ }
59
+ return DEFAULT_ADAPTER;
60
+ }
61
+
62
+ /**
63
+ * Adapter shape (also what a test fake must provide). Every function
64
+ * takes an options object and returns a Promise<GhResult>.
65
+ *
66
+ * @typedef {object} GhAdapter
67
+ * @property {(opts?: { host?: string }) => Promise<GhResult>} ghAuthStatus
68
+ * @property {(opts: { repo: string }) => Promise<GhResult>} ghLabelList
69
+ * @property {(opts: { repo: string }) => Promise<GhResult>} ghRepoView
70
+ * @property {(opts: { repo: string, query: string, state?: 'open' | 'closed', limit?: number }) => Promise<GhResult>} ghIssueSearch
71
+ * @property {(opts: { repo: string, title: string, body: string, labels: string[] }) => Promise<GhResult>} ghIssueCreate
72
+ * @property {(opts: { repo: string, number: number, body: string }) => Promise<GhResult>} ghIssueComment
73
+ * @property {(opts: { repo: string, name: string, description?: string, color?: string }) => Promise<GhResult>} ghLabelCreate
74
+ * @property {() => Promise<GhResult>} [ghOnPath]
75
+ */
76
+
77
+ /**
78
+ * Return an { ok: true, value: { present: boolean } } result naming
79
+ * whether the `gh` binary is on PATH. The default adapter shells out
80
+ * to `gh --version`; a test fake overrides through the seam.
81
+ *
82
+ * @returns {Promise<GhResult>}
83
+ */
84
+ export async function ghOnPath() {
85
+ const r = await runGh(['--version']);
86
+ if (r.ok) return { ok: true, value: { present: true } };
87
+ if (r.kind === 'notInstalled') return { ok: true, value: { present: false } };
88
+ return r;
89
+ }
90
+
91
+ /**
92
+ * `gh auth status --hostname <host>` exit 0 means logged in on that
93
+ * host. gh writes the status to stderr; a non-zero exit is the auth
94
+ * failure the design section 7 fallback keys off.
95
+ *
96
+ * @param {{ host?: string }} [opts]
97
+ * @returns {Promise<GhResult>}
98
+ */
99
+ export async function ghAuthStatus(opts = {}) {
100
+ const host = opts.host ?? DEFAULT_HOST;
101
+ const r = await runGh(['auth', 'status', '--hostname', host]);
102
+ if (r.ok) return { ok: true, value: { authed: true, host } };
103
+ if (r.kind === 'notInstalled') return r;
104
+ return { ok: false, kind: 'auth', message: `not logged in to ${host}`, exitCode: r.exitCode };
105
+ }
106
+
107
+ /**
108
+ * `gh label list --repo <repo> --json name` returns [{ name }, ...].
109
+ * A repo without labels returns []. A repo you cannot see returns
110
+ * an auth or notFound error; the caller treats either as "labels
111
+ * unknown" and drops all label requests.
112
+ *
113
+ * @param {{ repo: string }} opts
114
+ * @returns {Promise<GhResult>}
115
+ */
116
+ export async function ghLabelList(opts) {
117
+ const r = await runGh(['label', 'list', '--repo', opts.repo, '--json', 'name', '--limit', '100']);
118
+ if (!r.ok) return r;
119
+ try {
120
+ const parsed = JSON.parse(r.value.stdout);
121
+ const names = Array.isArray(parsed) ? parsed.map((row) => row?.name).filter((n) => typeof n === 'string') : [];
122
+ return { ok: true, value: { names } };
123
+ } catch (err) {
124
+ return { ok: false, kind: 'unknown', message: `label list parse failed: ${err.message}` };
125
+ }
126
+ }
127
+
128
+ /**
129
+ * `gh repo view <repo> --json visibility,viewerPermission,hasIssuesEnabled`.
130
+ *
131
+ * @param {{ repo: string }} opts
132
+ * @returns {Promise<GhResult>}
133
+ */
134
+ export async function ghRepoView(opts) {
135
+ const r = await runGh(['repo', 'view', opts.repo, '--json', 'visibility,viewerPermission,hasIssuesEnabled']);
136
+ if (!r.ok) return r;
137
+ try {
138
+ const parsed = JSON.parse(r.value.stdout);
139
+ return {
140
+ ok: true,
141
+ value: {
142
+ visibility: parsed?.visibility ?? null,
143
+ viewerPermission: parsed?.viewerPermission ?? null,
144
+ hasIssuesEnabled: parsed?.hasIssuesEnabled ?? null,
145
+ },
146
+ };
147
+ } catch (err) {
148
+ return { ok: false, kind: 'unknown', message: `repo view parse failed: ${err.message}` };
149
+ }
150
+ }
151
+
152
+ /**
153
+ * `gh search issues <query> --repo <repo> --state <state> --json
154
+ * number,url,title --limit <n>`. Slice 4 uses `--match body` via the
155
+ * query syntax "in:body <query>" so the dedupe search hits the
156
+ * fingerprint line. Search may be off on GHES and rate-limited on
157
+ * github.com; both fold to a search-unavailable error the caller
158
+ * treats as "fall through to create".
159
+ *
160
+ * @param {{ repo: string, query: string, state?: 'open' | 'closed', limit?: number }} opts
161
+ * @returns {Promise<GhResult>}
162
+ */
163
+ export async function ghIssueSearch(opts) {
164
+ const state = opts.state ?? 'open';
165
+ const limit = String(opts.limit ?? 5);
166
+ const args = [
167
+ 'search', 'issues',
168
+ `in:body ${opts.query}`,
169
+ '--repo', opts.repo,
170
+ '--state', state,
171
+ '--json', 'number,url,title',
172
+ '--limit', limit,
173
+ ];
174
+ const r = await runGh(args);
175
+ if (!r.ok) {
176
+ if (r.kind === 'ratelimit' || r.kind === 'server') {
177
+ return { ok: false, kind: 'search-unavailable', message: r.message, exitCode: r.exitCode };
178
+ }
179
+ return r;
180
+ }
181
+ try {
182
+ const parsed = JSON.parse(r.value.stdout);
183
+ const matches = Array.isArray(parsed)
184
+ ? parsed.filter((m) => m && typeof m.number === 'number')
185
+ : [];
186
+ return { ok: true, value: { matches } };
187
+ } catch (err) {
188
+ return { ok: false, kind: 'search-unavailable', message: `search parse failed: ${err.message}` };
189
+ }
190
+ }
191
+
192
+ /**
193
+ * `gh issue create --repo <repo> --title <t> --body-file - --label
194
+ * <l1> --label <l2>...` reads the body from stdin so a long body is
195
+ * safe across every shell. Returns { url, number }.
196
+ *
197
+ * @param {{ repo: string, title: string, body: string, labels: string[] }} opts
198
+ * @returns {Promise<GhResult>}
199
+ */
200
+ export async function ghIssueCreate(opts) {
201
+ const args = ['issue', 'create', '--repo', opts.repo, '--title', opts.title, '--body-file', '-'];
202
+ for (const l of opts.labels ?? []) args.push('--label', l);
203
+ const r = await runGh(args, { stdin: opts.body });
204
+ if (!r.ok) return r;
205
+ const url = extractIssueUrl(r.value.stdout);
206
+ const number = extractIssueNumber(url);
207
+ return { ok: true, value: { url, number } };
208
+ }
209
+
210
+ /**
211
+ * `gh issue comment <number> --repo <repo> --body-file -`. Returns
212
+ * { url }.
213
+ *
214
+ * @param {{ repo: string, number: number, body: string }} opts
215
+ * @returns {Promise<GhResult>}
216
+ */
217
+ export async function ghIssueComment(opts) {
218
+ const args = ['issue', 'comment', String(opts.number), '--repo', opts.repo, '--body-file', '-'];
219
+ const r = await runGh(args, { stdin: opts.body });
220
+ if (!r.ok) return r;
221
+ const url = (r.value.stdout || '').trim().split(/\s+/).pop() || '';
222
+ return { ok: true, value: { url } };
223
+ }
224
+
225
+ /**
226
+ * `gh label create <name> --repo <repo> --description <d> --color <c>`.
227
+ * Only used by scripts/bootstrap-feedback-labels.mjs; the tool proper
228
+ * never creates labels on submit.
229
+ *
230
+ * @param {{ repo: string, name: string, description?: string, color?: string }} opts
231
+ * @returns {Promise<GhResult>}
232
+ */
233
+ export async function ghLabelCreate(opts) {
234
+ const args = ['label', 'create', opts.name, '--repo', opts.repo];
235
+ if (opts.description) args.push('--description', opts.description);
236
+ if (opts.color) args.push('--color', opts.color);
237
+ const r = await runGh(args);
238
+ if (!r.ok) return r;
239
+ return { ok: true, value: { name: opts.name } };
240
+ }
241
+
242
+ // -- helpers --------------------------------------------------------------
243
+
244
+ /**
245
+ * Spawn gh with the given args, capture stdout/stderr, and classify
246
+ * failures. We pass a filtered environment (no synthesised TOKEN keys)
247
+ * so a test can assert the tool never invents credentials.
248
+ *
249
+ * @param {string[]} args
250
+ * @param {{ stdin?: string, env?: NodeJS.ProcessEnv }} [opts]
251
+ * @returns {Promise<GhResult>}
252
+ */
253
+ async function runGh(args, opts = {}) {
254
+ return new Promise((resolvePromise) => {
255
+ let child;
256
+ try {
257
+ child = spawn('gh', args, {
258
+ env: opts.env ?? process.env,
259
+ stdio: ['pipe', 'pipe', 'pipe'],
260
+ });
261
+ } catch (err) {
262
+ resolvePromise({ ok: false, kind: classifySpawnError(err), message: err.message });
263
+ return;
264
+ }
265
+ let stdout = '';
266
+ let stderr = '';
267
+ child.stdout.on('data', (chunk) => { stdout += chunk.toString('utf8'); });
268
+ child.stderr.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
269
+ child.on('error', (err) => {
270
+ resolvePromise({ ok: false, kind: classifySpawnError(err), message: err.message });
271
+ });
272
+ child.on('close', (code) => {
273
+ if (code === 0) {
274
+ resolvePromise({ ok: true, value: { stdout, stderr } });
275
+ return;
276
+ }
277
+ resolvePromise({
278
+ ok: false,
279
+ kind: classifyExit(code, stderr),
280
+ message: stderr.trim() || `gh exited with code ${code}`,
281
+ exitCode: code ?? undefined,
282
+ });
283
+ });
284
+ if (typeof opts.stdin === 'string') {
285
+ child.stdin.end(opts.stdin);
286
+ } else {
287
+ child.stdin.end();
288
+ }
289
+ });
290
+ }
291
+
292
+ /**
293
+ * Classify a spawn-time error. ENOENT means gh is not on PATH.
294
+ *
295
+ * @param {NodeJS.ErrnoException} err
296
+ * @returns {GhErr['kind']}
297
+ */
298
+ function classifySpawnError(err) {
299
+ if (err && err.code === 'ENOENT') return 'notInstalled';
300
+ return 'unknown';
301
+ }
302
+
303
+ /**
304
+ * Classify a non-zero gh exit into one of the error kinds the caller
305
+ * keys off. Uses stderr substrings because gh does not emit machine
306
+ * codes; the shapes below are stable across recent gh versions.
307
+ *
308
+ * @param {number | null} code
309
+ * @param {string} stderr
310
+ * @returns {GhErr['kind']}
311
+ */
312
+ function classifyExit(code, stderr) {
313
+ const s = (stderr || '').toLowerCase();
314
+ if (/(rate limit|abuse|secondary rate)/.test(s)) return 'ratelimit';
315
+ if (/(not found|could not resolve|http 404)/.test(s)) return 'notFound';
316
+ if (/(unauthorised|unauthorized|http 401|not logged in|authentication)/.test(s)) return 'auth';
317
+ if (/(http 5\d\d|internal server error)/.test(s)) return 'server';
318
+ if (/(http 4\d\d)/.test(s)) return 'client';
319
+ if (/(network|econnrefused|etimedout|dial tcp|dns)/.test(s)) return 'network';
320
+ return 'unknown';
321
+ }
322
+
323
+ /**
324
+ * Extract the issue url from gh's `issue create` stdout (which is
325
+ * usually just the URL on its own line, possibly followed by a
326
+ * trailing newline).
327
+ *
328
+ * @param {string} stdout
329
+ * @returns {string}
330
+ */
331
+ function extractIssueUrl(stdout) {
332
+ const m = (stdout || '').match(/https?:\/\/[^\s]+/);
333
+ return m ? m[0] : '';
334
+ }
335
+
336
+ /**
337
+ * Extract the issue number from a gh issue url.
338
+ *
339
+ * @param {string} url
340
+ * @returns {number | null}
341
+ */
342
+ function extractIssueNumber(url) {
343
+ const m = (url || '').match(/\/issues\/(\d+)/);
344
+ return m ? Number(m[1]) : null;
345
+ }
346
+
347
+ /**
348
+ * Normalise an override module: allow either a default export or
349
+ * per-name exports; a partial module falls back to the default
350
+ * implementations here for anything it does not override.
351
+ *
352
+ * @param {any} mod
353
+ * @returns {GhAdapter}
354
+ */
355
+ function normaliseAdapter(mod) {
356
+ const base = { ...DEFAULT_ADAPTER };
357
+ const src = mod && typeof mod === 'object' && mod.default && typeof mod.default === 'object'
358
+ ? { ...mod, ...mod.default }
359
+ : mod;
360
+ for (const key of Object.keys(base)) {
361
+ if (typeof src?.[key] === 'function') base[key] = src[key];
362
+ }
363
+ return base;
364
+ }
365
+
366
+ /** Default adapter (this module's own implementations). */
367
+ export const DEFAULT_ADAPTER = Object.freeze({
368
+ ghOnPath,
369
+ ghAuthStatus,
370
+ ghLabelList,
371
+ ghRepoView,
372
+ ghIssueSearch,
373
+ ghIssueCreate,
374
+ ghIssueComment,
375
+ ghLabelCreate,
376
+ });
@@ -0,0 +1,183 @@
1
+ // Feedback harness hook (TAC-4108). Slice 5 (FBS-184): the ask.
2
+ //
3
+ // Two exports are the load-bearing surface:
4
+ // - `shouldAsk(state)` is a pure function over the design 3.5 inputs
5
+ // that returns 'ask' or 'silent'; every quiet-rule branch runs
6
+ // through it and every unit-test truth table drives it directly.
7
+ // - `emit(harness, decision, message)` writes the per-harness output
8
+ // shape (Claude Code: exit 2 + stderr; Codex: stdout JSON block)
9
+ // and returns the exit code the CLI wrapper propagates.
10
+ //
11
+ // The CLI wrapper (`rcf feedback hook stop|session-end|session-start`
12
+ // dispatched from `src/cli/feedback.js`) reads the harness JSON from
13
+ // stdin, gathers the store inputs (settings, pending entries, ask
14
+ // ledger, prior sessionId), calls `shouldAsk` and then `emit`, and
15
+ // (crucially) APPENDS the asked ledger record BEFORE the emit so a
16
+ // crash between emit and reply cannot cause a second ask.
17
+ //
18
+ // Design references: sections 3.5 (quiet rule + per-harness shape),
19
+ // 8 (settings and env vars), 9 (Stop is the ask event ADR), 10.3
20
+ // (quietMinutes default 15).
21
+
22
+ /**
23
+ * Reason text the hook feeds Claude Code (stderr) or Codex (JSON
24
+ * `reason`). Exported so a caller can assemble a locally augmented
25
+ * variant (e.g. prefixing the outbox path from a carried-over session)
26
+ * without re-typing the four verb names. Kept STATIC so the managed
27
+ * block's hash-verified RULE 17 slice 6 text can pin the same verbs
28
+ * once, in one place.
29
+ *
30
+ * @param {number} pendingCount
31
+ * @returns {string}
32
+ */
33
+ export function buildAskReason(pendingCount) {
34
+ const n = Math.max(1, Number(pendingCount) || 1);
35
+ const noun = n === 1 ? 'entry' : 'entries';
36
+ return `rcf feedback: ${n} unsubmitted ${noun} on this project. `
37
+ + "Run 'rcf feedback preview', show the operator the titles, "
38
+ + 'bodies and destination it prints, ask once whether to send '
39
+ + "them, then run 'rcf feedback submit --yes', "
40
+ + "'rcf feedback defer' or 'rcf feedback opt-out'. "
41
+ + 'Do not ask again this session.';
42
+ }
43
+
44
+ /**
45
+ * Reason text the SessionStart hook injects on either harness when
46
+ * one or more pending entries carried over from a prior session. The
47
+ * wording mirrors RULE 17's ask contract without prescribing verbs
48
+ * (SessionStart runs before any operator prompt; the ask itself
49
+ * arrives on Stop).
50
+ *
51
+ * @param {number} pendingCount
52
+ * @returns {string}
53
+ */
54
+ export function buildCarryOverLine(pendingCount) {
55
+ const n = Math.max(1, Number(pendingCount) || 1);
56
+ const noun = n === 1 ? 'entry' : 'entries';
57
+ return `rcf feedback: ${n} unsubmitted ${noun} carried over `
58
+ + 'from an earlier session; ask the operator once at a natural '
59
+ + 'pause (RULE 17).';
60
+ }
61
+
62
+ /**
63
+ * @typedef {object} QuietRuleState
64
+ * @property {boolean} optedOut file `ask: false` or env silence
65
+ * @property {number} pendingCount pending entries visible to the
66
+ * hook right now
67
+ * @property {boolean} askedThisSession `state.json` already recorded
68
+ * an `asked` entry for the
69
+ * incoming sessionId
70
+ * @property {boolean} stopHookActive Claude Code / Codex loop guard
71
+ * @property {boolean} anyAskNow one or more pending entries
72
+ * carry askNow: true
73
+ * @property {number | null} newestPendingAgeMs
74
+ * milliseconds since the newest
75
+ * pending entry was recorded, or
76
+ * null when nothing is pending
77
+ * @property {number} quietMinutes operator-configurable gate; the
78
+ * caller resolves the default (15)
79
+ * @property {boolean} queueComplete `.rcf/feedback/state.json`
80
+ * `queueStateAt` cached
81
+ * complete / nothing-actionable
82
+ * @property {boolean} anyCarriedOver one or more pending entries were
83
+ * recorded under a prior sessionId
84
+ */
85
+
86
+ /**
87
+ * Pure quiet-rule decision (design 3.5, ADR-4107).
88
+ *
89
+ * Ask on `stop` when ALL hold:
90
+ * - not opted out (per-project file OR per-user env);
91
+ * - pending entries exist;
92
+ * - no `asked` record for this session_id in `state.json`;
93
+ * - `stop_hook_active` is false (Claude Code loop guard; Codex
94
+ * sends the same field);
95
+ * - AND one of: an entry carries askNow; the newest pending entry
96
+ * is older than quietMinutes; queue-state cache reports complete
97
+ * or nothing-actionable; the entry was carried over from an
98
+ * earlier session.
99
+ *
100
+ * Otherwise, exit silent. The function is total, deterministic, and
101
+ * has no side effects; unit tests drive it directly from a truth
102
+ * table and the wrapper only calls it once per invocation.
103
+ *
104
+ * @param {QuietRuleState} state
105
+ * @returns {'ask' | 'silent'}
106
+ */
107
+ export function shouldAsk(state) {
108
+ if (!state) return 'silent';
109
+ if (state.optedOut) return 'silent';
110
+ if (!Number.isFinite(state.pendingCount) || state.pendingCount <= 0) return 'silent';
111
+ if (state.askedThisSession) return 'silent';
112
+ if (state.stopHookActive) return 'silent';
113
+
114
+ const quietMinutes = Number.isFinite(state.quietMinutes) && state.quietMinutes >= 0
115
+ ? state.quietMinutes
116
+ : 15;
117
+ const ageMs = typeof state.newestPendingAgeMs === 'number'
118
+ ? state.newestPendingAgeMs
119
+ : null;
120
+ const olderThanQuiet = ageMs !== null && ageMs >= quietMinutes * 60_000;
121
+
122
+ const triggerAny = Boolean(state.anyAskNow)
123
+ || olderThanQuiet
124
+ || Boolean(state.queueComplete)
125
+ || Boolean(state.anyCarriedOver);
126
+ return triggerAny ? 'ask' : 'silent';
127
+ }
128
+
129
+ /**
130
+ * Per-harness emit shape. Writes to the passed streams and returns
131
+ * the exit code the wrapper should propagate. The reason is written
132
+ * VERBATIM; callers pass the text `buildAskReason` (or their own
133
+ * augmented variant) produced. On `silent` no bytes are written on
134
+ * either stream and the exit code is 0 on both harnesses.
135
+ *
136
+ * @param {'claude-code' | 'codex'} harness
137
+ * @param {'ask' | 'silent'} decision
138
+ * @param {string} reason
139
+ * @param {{ stdout: NodeJS.WritableStream, stderr: NodeJS.WritableStream }} streams
140
+ * @returns {number} exit code the wrapper propagates
141
+ */
142
+ export function emit(harness, decision, reason, streams) {
143
+ if (decision !== 'ask') return 0;
144
+ const stdout = streams?.stdout;
145
+ const stderr = streams?.stderr;
146
+ if (harness === 'codex') {
147
+ // Codex requires JSON on stdout with { decision: 'block', reason };
148
+ // plain text is invalid. The wrapper still exits 0 (Codex reads
149
+ // the decision, not the exit code, on Stop).
150
+ const payload = { decision: 'block', reason };
151
+ stdout?.write(`${JSON.stringify(payload)}\n`);
152
+ return 0;
153
+ }
154
+ // Claude Code default: exit 2 with the reason on stderr. Claude
155
+ // Code feeds the reason back to Claude, which speaks to the user.
156
+ stderr?.write(`${reason}\n`);
157
+ return 2;
158
+ }
159
+
160
+ /**
161
+ * SessionStart emit: one plain line for Claude Code (harness picks it
162
+ * up as context), a JSON `additionalContext` shape for Codex. Both
163
+ * return exit 0; the ledger is NOT touched on SessionStart (ask still
164
+ * runs on Stop). If the Codex build in use does not accept a
165
+ * SessionStart additionalContext, the RULE 17 fallback ("check
166
+ * `rcf feedback status` at session start") carries the same posture;
167
+ * the wrapper falls back gracefully.
168
+ *
169
+ * @param {'claude-code' | 'codex'} harness
170
+ * @param {string} line
171
+ * @param {{ stdout: NodeJS.WritableStream }} streams
172
+ * @returns {number} exit code the wrapper propagates
173
+ */
174
+ export function emitSessionStart(harness, line, streams) {
175
+ const stdout = streams?.stdout;
176
+ if (!line) return 0;
177
+ if (harness === 'codex') {
178
+ stdout?.write(`${JSON.stringify({ additionalContext: line })}\n`);
179
+ return 0;
180
+ }
181
+ stdout?.write(`${line}\n`);
182
+ return 0;
183
+ }
@@ -0,0 +1,87 @@
1
+ // Feedback label catalogue (TAC-4105-feedback-render, AC-15902-4). The
2
+ // six labels the tool asks GitHub to apply on create, and the same
3
+ // six the maintainer bootstrap script creates on a destination repo.
4
+ //
5
+ // F-6 gate finding: keep the catalogue as a single exported constant
6
+ // so the label pre-check on submit, the render.js default-labels
7
+ // helper, and the bootstrap script all consume one source of truth.
8
+ // A grep test (test/feedback/labels-catalogue.test.js) refuses bare
9
+ // literals for these names anywhere else under src/ or scripts/.
10
+
11
+ /**
12
+ * The six bootstrap labels (ADR-4102). Frozen so a downstream mutation
13
+ * would throw rather than silently drift.
14
+ *
15
+ * @type {readonly [string, string, string, string, string, string]}
16
+ */
17
+ export const FEEDBACK_LABELS = Object.freeze([
18
+ 'rcf-feedback',
19
+ 'severity:blocker',
20
+ 'severity:major',
21
+ 'severity:minor',
22
+ 'area:blueprint',
23
+ 'area:core',
24
+ ]);
25
+
26
+ /**
27
+ * Machine-readable description of each label (for the bootstrap
28
+ * script's `gh label create` call, which wants a `--description` and
29
+ * a `--color`). Same order as `FEEDBACK_LABELS`.
30
+ */
31
+ export const FEEDBACK_LABEL_DEFINITIONS = Object.freeze([
32
+ { name: 'rcf-feedback', description: 'Filed by rcf-lite feedback verb', color: '5319E7' },
33
+ { name: 'severity:blocker', description: 'Blocks a workflow with no workaround', color: 'B60205' },
34
+ { name: 'severity:major', description: 'Significant impact, workaround exists', color: 'D93F0B' },
35
+ { name: 'severity:minor', description: 'Small friction or cosmetic', color: 'FBCA04' },
36
+ { name: 'area:blueprint', description: 'About a blueprint (shelf or library)', color: '0E8A16' },
37
+ { name: 'area:core', description: 'About the rcf-lite core CLI or docs', color: '1D76DB' },
38
+ ]);
39
+
40
+ /**
41
+ * The three labels the tool asks for on a given entry (subset of the
42
+ * six above). `severity:<sev>` and `area:<blueprint|core>` are picked
43
+ * per entry; `rcf-feedback` is always requested.
44
+ *
45
+ * Callers pass the severity and the kind; the returned array is the
46
+ * request, before the label pre-check narrows it to what exists on
47
+ * the destination repo.
48
+ *
49
+ * @param {'blocker' | 'major' | 'minor'} severity
50
+ * @param {'blueprint' | 'core'} kind
51
+ * @returns {string[]}
52
+ */
53
+ export function labelsForEntry(severity, kind) {
54
+ const out = [FEEDBACK_LABELS[0]];
55
+ const sevLabel = severityLabel(severity);
56
+ if (sevLabel) out.push(sevLabel);
57
+ const areaLabel = areaLabelForKind(kind);
58
+ if (areaLabel) out.push(areaLabel);
59
+ return out;
60
+ }
61
+
62
+ /**
63
+ * `severity:<blocker|major|minor>` from the entry's severity, or null
64
+ * if it is not one of the three (defensive; the enum is fixed).
65
+ *
66
+ * @param {string | undefined | null} severity
67
+ * @returns {string | null}
68
+ */
69
+ export function severityLabel(severity) {
70
+ if (severity === 'blocker') return FEEDBACK_LABELS[1];
71
+ if (severity === 'major') return FEEDBACK_LABELS[2];
72
+ if (severity === 'minor') return FEEDBACK_LABELS[3];
73
+ return null;
74
+ }
75
+
76
+ /**
77
+ * `area:blueprint` or `area:core` from the entry's kind, or null on
78
+ * anything else.
79
+ *
80
+ * @param {string | undefined | null} kind
81
+ * @returns {string | null}
82
+ */
83
+ export function areaLabelForKind(kind) {
84
+ if (kind === 'blueprint') return FEEDBACK_LABELS[4];
85
+ if (kind === 'core') return FEEDBACK_LABELS[5];
86
+ return null;
87
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "hosts": [
3
+ "github.com",
4
+ "npmjs.com",
5
+ "nodejs.org",
6
+ "stravica.ai",
7
+ "developers.cloudflare.com",
8
+ "cloudflare.com",
9
+ "docs.github.com",
10
+ "developer.mozilla.org",
11
+ "localhost",
12
+ "127.0.0.1"
13
+ ]
14
+ }