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,38 @@
1
+ {
2
+ "createdAt": "2026-09-16T22:38:04Z",
3
+ "updatedAt": "2026-09-16T22:38:04Z",
4
+ "purpose": "Cover AC-16502-1 (writer refuses executionStatus=verified without allowVerifiedOverride, C-22), AC-16502-2 (writer accepts when allowVerifiedOverride:true, C-22 opt-out seam), and AC-16502-3 (finalise refuses on a non-default branch, --allow-pre-merge is the opt-out, C-26). AC-16502-1 and AC-16502-2 drive the writer directly through updateDocument; AC-16502-3 drives the finalise CLI end-to-end with a spawn seam that returns the branch name.",
5
+ "testLevel": "integration",
6
+ "acIds": [
7
+ "AC-16502-1",
8
+ "AC-16502-2",
9
+ "AC-16502-3"
10
+ ],
11
+ "id": "TS-203",
12
+ "usId": "US-16502",
13
+ "title": "finalise verified-invariant: writer refusal and merge-state precondition",
14
+ "testCases": [
15
+ {
16
+ "id": "TC-203-writer-refuses-manual-verified",
17
+ "acId": "AC-16502-1",
18
+ "description": "Fresh project via initProject with FBS-001 at complete; call updateDocument with sets=[{path:'executionStatus', value:'verified'}] and options={}; assert result is RcfError kind='usage' matching /verified is written only by the finalise gate/; FBS on disk still at complete.",
19
+ "status": "pending",
20
+ "testPointer": "test/cli/finalise-referee-refusals.test.js::define update FBS.executionStatus=verified is refused without --acknowledge-verified-override (referee-guarantees C-22)"
21
+ },
22
+ {
23
+ "id": "TC-203-writer-accepts-with-override",
24
+ "acId": "AC-16502-2",
25
+ "description": "Same scaffold; call updateDocument with options={allowVerifiedOverride:true}; assert result carries an id and FBS on disk reads status verified.",
26
+ "status": "pending",
27
+ "testPointer": "test/cli/finalise-referee-refusals.test.js::define update FBS.executionStatus=verified proceeds with allowVerifiedOverride:true (finalise seam, C-22 opt-out)"
28
+ },
29
+ {
30
+ "id": "TC-203-merge-state-refusal-and-opt-out",
31
+ "acId": "AC-16502-3",
32
+ "description": "Fresh scaffold with a stub verify subprocess and a spawn seam that returns 'feature/x' as the git branch. First invocation: rcf build finalise <fbs> --url ...; assert exit 4 and stderr matches /git working tree is on branch 'feature\\/x'/. Second invocation: add --allow-pre-merge; assert exit 0, FBS at verified, and stdout matches /Referee-guarantees claim C-26 records the pre-merge decision here/.",
33
+ "status": "pending",
34
+ "testPointer": "test/cli/finalise-referee-refusals.test.js::finalise refuses promotion when git is not on a default branch (referee-guarantees C-26)"
35
+ }
36
+ ],
37
+ "status": "approved"
38
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "usId": "US-15501",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-155",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Agent records a finding with one command",
8
+ "asA": "agent that has just seen a blueprint or rcf-lite misbehave",
9
+ "iWant": "to record the finding with a single rcf feedback add call whose flags cover kind, target, anchor, symptom class, severity, title, body and evidence pointers, and to be told nothing was sent",
10
+ "soThat": "a finding is captured at the moment I see it, without any user-facing interruption and without any network traffic",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15501-1",
14
+ "description": "rcf feedback add with the required flags (--kind, --target, --anchor, --class, --severity, --title, --body or --body-file, --evidence at least once, optional --harness and --ask-now) writes exactly one JSONL line to .rcf/feedback/entries.jsonl, stamps environment (harness, rcf-lite version, node version, platform) on the entry, prints \"recorded <id> (<n> pending). Nothing sent.\" on stdout, and exits 0. No network syscall is made (assertable by a stubbed submit path and by absence of gh calls).",
15
+ "given": "a fixture project whose .gitignore covers .rcf/feedback/",
16
+ "when": "the agent runs rcf feedback add with every required flag",
17
+ "then": "entries.jsonl has one line whose fields match the flags and the environment stamp; stdout carries the \"recorded\" line; exit code is 0; the network seam has not been touched",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15501-2",
23
+ "description": "rcf feedback add refuses when the project .gitignore does not cover .rcf/feedback/ and no --force flag is passed. The error names the missing gitignore entry and points at rcf doctor --fix. Exit code is 2. No file is created under .rcf/feedback/.",
24
+ "given": "a fixture project whose .gitignore lacks the .rcf/feedback/ entry",
25
+ "when": "the agent runs rcf feedback add without --force",
26
+ "then": "the command exits 2, stderr names the missing gitignore entry and the rcf doctor --fix remedy, and .rcf/feedback/ is not created",
27
+ "testable": true,
28
+ "scope": "runtime"
29
+ },
30
+ {
31
+ "id": "AC-15501-3",
32
+ "description": "Ruling R1 (Dave 2026-09-16): --kind blueprint exits 3 ONLY when the target is absent from rcf/manifest.json:blueprints[] (unknown target). A KNOWN blueprint whose registered library carries no resolvable feedback destination (no issuesRepo and no derivable github sourceRef) is exit 0 with the entry stamped destination: unresolved; slice 4 writes the bundle at submit time (design section 7 case 5 wins). In both cases the entry is recorded; stdout carries the recorded line. On the exit-3 branch stderr carries \"destination unresolved: <target>\"; on the exit-0 unresolved branch stderr carries a one-line note naming the library.",
33
+ "given": "a fixture project whose manifest carries no matching blueprint (exit 3), and a second project whose manifest holds a blueprint from a library with no issuesRepo (exit 0)",
34
+ "when": "the agent runs rcf feedback add --kind blueprint --target <ref> ... against each",
35
+ "then": "the unknown-target invocation writes the entry with destination.reason=unresolved, exit code 3, stderr names the target; the known-target-no-destination invocation writes the entry with destination.reason=unresolved, exit code 0, stderr names the library",
36
+ "testable": true,
37
+ "scope": "runtime"
38
+ },
39
+ {
40
+ "id": "AC-15501-4",
41
+ "description": "Symptom class must be one of the closed enum (docs-mismatch, validate-fails, apply-fails, internal-contradiction, stale-citation, missing-scenario, verb-error, verb-hang, wrong-output, other). Any other value exits 2 with a usage error naming the enum. Severity must be one of blocker, major, minor. Title is capped at 120 chars, body at 8 KB (either --body or --body-file); over-cap inputs exit 2 with a size error.",
42
+ "given": "a fixture project whose gitignore is set up correctly",
43
+ "when": "the agent runs rcf feedback add with an invalid class or severity, an oversize title, or an oversize body",
44
+ "then": "each invalid invocation exits 2, stderr names the specific violation and the enum or size limit; no entry is written",
45
+ "testable": true,
46
+ "scope": "library"
47
+ },
48
+ {
49
+ "id": "AC-15501-5",
50
+ "description": "When --kind blueprint is passed and the target resolves to a known blueprint in rcf/manifest.json:blueprints[], the recorded entry additionally stamps blueprintVersion, libraryPrefix, libraryRef and resolvedSha (or tarballSha256 when the pin is a tarball) on target, sourced from the manifest record and the matching rcf/blueprint-libraries.json registry entry. Core entries (kind core) carry none of these fields. A shelf blueprint (no libraryPrefix on the manifest record) carries blueprintVersion and resolvedSha but leaves libraryPrefix and libraryRef unset.",
51
+ "given": "a fixture project with three applied blueprints: one shelf, one library (git pin) and one library (tarball pin), plus one core entry",
52
+ "when": "the agent runs rcf feedback add --kind blueprint for each blueprint target and --kind core for the core entry",
53
+ "then": "each blueprint entry carries the expected blueprint-specific stamps sourced from manifest + registry (shelf omits libraryPrefix and libraryRef; git-pin carries resolvedSha; tarball-pin carries tarballSha256); the core entry carries none of the four fields",
54
+ "testable": true,
55
+ "scope": "library"
56
+ }
57
+ ],
58
+ "createdAt": "2026-09-16T13:45:23.000Z",
59
+ "updatedAt": "2026-09-16T14:14:36Z"
60
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "usId": "US-15502",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-155",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator lists and inspects what has been recorded",
8
+ "asA": "operator who wants to see what the agent has logged this session",
9
+ "iWant": "to run rcf feedback list (and rcf feedback status) to see pending entries and their state without triggering any submission",
10
+ "soThat": "I can decide by hand what to do with the log, and doctor can report the same counts on demand",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15502-1",
14
+ "description": "rcf feedback list prints one line per pending entry (id, target, symptom class, severity, one-line title) sorted by recordedAt ascending; --all includes submitted, deferred, discarded, bundled entries with their status column; --json emits a stable machine-readable shape. Neither invocation touches the network or writes to entries.jsonl.",
15
+ "given": "a fixture project with three entries of mixed status",
16
+ "when": "the operator runs rcf feedback list and then rcf feedback list --all --json",
17
+ "then": "default output shows only pending entries in order; --all includes every state; --json parses to an array whose length equals total entries; no file mutation, no network calls",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15502-2",
23
+ "description": "rcf feedback status prints counts by status, the opt-out state (from rcf/feedback-settings.json or RCF_FEEDBACK_ASK env), a destination table for every applied blueprint (rows: target, resolved repo or unresolved with reason, visibility hint), and gh availability (present, authed, absent, unknown). --json emits the same as machine-readable object. The status shape is the one the SessionStart hook and doctor both consume.",
24
+ "given": "a fixture project with several blueprints applied and gh present",
25
+ "when": "the operator runs rcf feedback status --json",
26
+ "then": "the JSON carries counts, optOut boolean, destinations[] with target/repo/visibility, and gh { present, authed } fields; the text form prints the same as a readable summary",
27
+ "testable": true,
28
+ "scope": "runtime"
29
+ }
30
+ ],
31
+ "createdAt": "2026-09-16T13:45:23.000Z",
32
+ "updatedAt": "2026-09-16T13:45:23.000Z"
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "usId": "US-15503",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-155",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator defers or discards recorded findings",
8
+ "asA": "operator who has decided not to submit some findings",
9
+ "iWant": "to mark the pending batch deferred for this session, or discard specific entries entirely, without any network activity",
10
+ "soThat": "a \"not now\" or \"never for this one\" answer is honoured immediately and the state is durable across the next boot",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15503-1",
14
+ "description": "rcf feedback defer appends a state line for every currently pending entry stamping status: deferredUntilSession with the current sessionId; the entries stay in the log so the next session sees them; the current session-end hook does not re-ask. Exit 0. Nothing is sent.",
15
+ "given": "a fixture project with two pending entries and a known sessionId",
16
+ "when": "the operator runs rcf feedback defer",
17
+ "then": "entries.jsonl grows by two lines each carrying the deferred status and sessionId; a folded read shows both entries at status deferredUntilSession; no network call was made",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15503-2",
23
+ "description": "rcf feedback discard <id> marks only the named entries discarded (kept in the log for 30 days, then pruned on the next add). --all discards every pending entry. Discarded entries are excluded from list default output, hidden from the SessionStart carry-over count, and never appear in a submit or bundle. Exit 0.",
24
+ "given": "a fixture project with three pending entries",
25
+ "when": "the operator runs rcf feedback discard fb-<a> fb-<b> then rcf feedback list",
26
+ "then": "the two named entries are folded to status discarded; list shows only the remaining entry; the next add older than 30 days prunes them",
27
+ "testable": true,
28
+ "scope": "runtime"
29
+ }
30
+ ],
31
+ "createdAt": "2026-09-16T13:45:23.000Z",
32
+ "updatedAt": "2026-09-16T13:45:23.000Z"
33
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "usId": "US-15601",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-156",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator sees the exact issue text and what was stripped before consenting",
8
+ "asA": "operator being asked to submit findings",
9
+ "iWant": "rcf feedback preview to print the exact rendered issue title and body, the destination repo and its visibility, and a redaction ledger that lists every rule-triggered replacement so I can see what was stripped",
10
+ "soThat": "my yes is informed and nothing surprising leaves the machine",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15601-1",
14
+ "description": "rcf feedback preview renders each pending entry as the title and body that would be filed on GitHub (using src/feedback/render.js templates from section 4.3 of the design), lists the destination repo and its declared visibility (public, private, or unresolved), and prints the redaction ledger as diff-style lines (\"- before + after\") with the rule name. --json emits the same as a machine-readable object per entry. No network calls. The kv-secret rule (design section 5 rule 5) is driven by the shared SECRET_KEY_VOCABULARY constant exported from src/feedback/redact.js (design amendment R3a) so the first-pass redactor, the residual safeguard pass and the rule-9 URL-credential scanner cover exactly the same open vocabulary of key stems (secret, token, password, passwd, passphrase, pw, pwd, pass, key, apikey/api_key/api-key, privatekey/private_key/private-key, accesskey/access_key/access-key, clientsecret/client_secret/client-secret, bearer, credential/credentials/cred/creds, session, cookie, signature, sig, salt; hash carries a 16+-value length guard); the match is right-bounded at a word edge so `keyword` and `authors` do not fold but `dbpassword` still does. Design amendment R4 (round 5) extends the rule-5 pass so a vocabulary key labelling a value-shape token of 8+ chars with any separator (markdown table pipes, whitespace runs, tabs, hyphens, arrows, HTML numeric entities, or the prose bridges is / was / set to) also folds, with a mixed-classes gate on the value that keeps ordinary prose (`the password is required`, `the password field is required`) intact.",
15
+ "given": "a fixture project with one entry whose body contains an absolute path, an email, a non-allowlisted hostname, a token-shaped string, a private IPv4 (10.0.5.7), an em-dash, an oversize body block, an operator name that matches a seeded rcf/.identity/profile.md ## Name line, AND at least one shortname-key secret (`pw=`), one URL-embedded credential (a Slack webhook path), one markdown-table row with a vocabulary key and a mixed-class value (`| password | Sup3rSecretV@lue!! |`) and one prose bridge (`the password Sup3rSecretV@lue1234 is bad`)",
16
+ "when": "the operator runs rcf feedback preview --json",
17
+ "then": "the JSON output carries titleRendered, bodyRendered, destination { repo, visibility }, and ledger[] entries whose rule names include project-root, absolute-path, email, hostname, secret-token, private-ip, operator-identity, size-shape and url-credential; the rendered body contains none of the original secret substrings (including the shortname-key value, the webhook path segment, the markdown-table value and the prose-bridge value), none of the private IP, none of the operator-name tokens, no em-dash, and is at most 8 KB",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15601-2",
23
+ "description": "When a body still matches a rule-5 secret pattern on the second redaction pass, preview marks the entry as \"residual secret at line N\" and submit refuses that entry. Other pending entries are unaffected. The exact refusing line is shown to the operator so the agent can rewrite the body.",
24
+ "given": "a fixture project with two entries, one containing a token that survives the first pass through obfuscation and one clean",
25
+ "when": "the operator runs rcf feedback preview then rcf feedback submit --yes",
26
+ "then": "the tainted entry is shown with the residual-secret line; submit does not send the tainted entry; the clean entry is submitted (or fallbacks to bundle if that path applies); exit code is 3 while any residual-secret entry is still pending",
27
+ "testable": true,
28
+ "scope": "runtime"
29
+ },
30
+ {
31
+ "id": "AC-15601-3",
32
+ "description": "The stored entries.jsonl body is never mutated by preview. A byte-for-byte comparison of entries.jsonl before and after preview is identical; the redaction lives only in the rendered output.",
33
+ "given": "a fixture project with entries whose bodies contain redactable content",
34
+ "when": "the operator runs rcf feedback preview repeatedly",
35
+ "then": "a sha-256 of entries.jsonl before and after each preview run matches",
36
+ "testable": true,
37
+ "scope": "library"
38
+ },
39
+ {
40
+ "id": "AC-15601-4",
41
+ "description": "After rendering and normalising the fully assembled issue body (and, for the bundle path, each bundle file), a final whole-text residual-secret pass runs findResidualSecrets over the whole text with multiline patterns. Any hit means the entry stays pending (preview marks it refused-residual and submit refuses that entry with exit 3) and no create/comment/bundle-write occurs for it. The safeguard is defence-in-depth: it catches multiline shapes (e.g. an em-dash-delimited PEM block that survives per-field redaction of a slice-2-style body) that a per-line scan could not see. The safeguard shares the SECRET_KEY_VOCABULARY constant with the first-pass redactor and the rule-9 URL-credential scanner (design amendment R3a), so a shortname-key value (`pw=...`, `pwd=...`) or a webhook-path shape (`/services/<token>`, `/api/webhooks/<token>`, `/bot<token>/method`) that reappears after per-field normalisation is caught by the same set the first pass used.",
42
+ "given": "a fixture project with an entry whose body assembles into a rendered issue body containing a shape a per-line residual scan would miss (a multiline PEM block or a token buried inside a longer identifier)",
43
+ "when": "the operator runs rcf feedback preview then rcf feedback submit --yes",
44
+ "then": "preview surfaces the residual line and the tainted entry stays pending; submit exits 3 without a create/comment for that entry and without writing a bundle whose text carries the residual shape",
45
+ "testable": true,
46
+ "scope": "runtime"
47
+ }
48
+ ],
49
+ "createdAt": "2026-09-16T13:45:23.000Z",
50
+ "updatedAt": "2026-09-17T00:36:18Z"
51
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "usId": "US-15701",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-157",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "The same finding from many reporters folds into one issue",
8
+ "asA": "blueprint maintainer receiving reports",
9
+ "iWant": "ten reporters hitting the same defect on the same anchor to land as one issue with nine +1 comments carrying their environments, not ten separate issues",
10
+ "soThat": "triage is cheap and duplicate storms do not swamp the tracker",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15701-1",
14
+ "description": "fingerprint(entry) returns the first 12 hex chars of sha-256 over \"<kind>|<targetKey>|<anchor>|<symptomClass>\" where targetKey is the effective slug for blueprints (no version) or the verb path for core, anchor is upper-cased or \"-\" when absent, and symptomClass is one of the closed enum. Same fingerprint across two entries whose blueprint versions differ; different fingerprint when the anchor or class differs.",
15
+ "given": "a fixture corpus of five entries: same-defect different-version, same-defect different-anchor, same-defect different-class, missing-anchor pair (title-only fallback), and one clean",
16
+ "when": "fingerprint() is called on each entry",
17
+ "then": "the versioned pair yields identical fingerprints; the anchor and class variants yield different fingerprints; the missing-anchor pair uses the \"<kind>|<targetKey>|<symptomClass>|<normalisedTitle>\" fallback (first eight tokens, punctuation and stop-words stripped, lower-case)",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-15701-2",
23
+ "description": "On submit, per pending entry, gh search issues is called for the destination repo with query \"rcf-feedback-fingerprint: <fp>\", --match body, --state open, --limit 5. Exactly one hit: gh issue comment on that number, comment body carries \"+1 from another reporter\" plus the Environment table and the redacted body only when it differs from the original by more than the environment lines. Zero hits: gh issue create. More than one hit: comment on the lowest number and mention the others.",
24
+ "given": "a fake gh module (via RCF_FEEDBACK_GH_MODULE) whose search stub yields zero, one and two hits in three sequential invocations, and one pending entry per case",
25
+ "when": "rcf feedback submit --yes runs three times",
26
+ "then": "the zero-hit case calls gh issue create; the one-hit case calls gh issue comment on the returned number; the two-hit case calls gh issue comment on the smaller number and includes \"also see #<other>\" in the comment body",
27
+ "testable": true,
28
+ "scope": "runtime"
29
+ },
30
+ {
31
+ "id": "AC-15701-3",
32
+ "description": "When gh search issues is unavailable or errors (rate-limit, GHES search off, non-zero exit), submit falls through to gh issue create for that entry and the state line stamps dedupe: unchecked. Closed issues are never matched; if --state closed search finds an issue with the same fingerprint the created new issue body carries \"previously reported and closed as #<n>\".",
33
+ "given": "a fake gh module whose search stub throws for one call and returns a closed match for the next",
34
+ "when": "rcf feedback submit --yes runs twice with one pending entry each",
35
+ "then": "the first entry is created with dedupe: unchecked in state; the second is created with a body reference to the previously closed issue number",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "createdAt": "2026-09-16T13:45:23.000Z",
41
+ "updatedAt": "2026-09-16T13:45:23.000Z"
42
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "usId": "US-15801",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-158",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Library owner declares where feedback issues go",
8
+ "asA": "library owner shipping a blueprint library",
9
+ "iWant": "to name the reports destination in one field on library.json, snapshotted into the consuming project registry on library add, so every project using my library files reports on my repo",
10
+ "soThat": "I hear about defects on my library without every consuming project having to be told separately",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15801-1",
14
+ "description": "library.json accepts an optional issues object with { repo: \"OWNER/REPO\" (host-qualified HOST/OWNER/REPO permitted for GHES), visibility: \"public\" | \"private\" }. Absence is valid; the presence-with-shape is schema-checked (documented in docs/library-authoring.md field table). On rcf library add the value is snapshotted onto the registry entry as issuesRepo and issuesVisibility, alongside publisher. rcf library refresh re-snapshots.",
15
+ "given": "a fixture library.json with { issues: { repo: \"wsd-team-dev/rcf-lite-blueprints\", visibility: \"private\" } }",
16
+ "when": "rcf library add is run against the fixture",
17
+ "then": "rcf/blueprint-libraries.json:entries[] for the library carries issuesRepo and issuesVisibility with the exact values; the review-on-add card prints \"Feedback destination: wsd-team-dev/rcf-lite-blueprints (private)\"",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15801-2",
23
+ "description": "The destination resolver (src/feedback/destination.js) walks: entry.target -> rcf/manifest.json:blueprints[] -> if libraryPrefix present, the registry entry issuesRepo; absent on the entry, derives from the library sourceRef when it parses as git+https://github.com/OWNER/REPO(.git)#ref (marked derived: true); otherwise unresolved. Shelf blueprints (no libraryPrefix) and --kind core route to a constant read from package.json:bugs.url (Stravica/rcf-lite).",
24
+ "given": "a fixture with three applied blueprints: one shelf, one library with explicit issues, one library with a github git source and no issues",
25
+ "when": "destination.resolve() is called for each",
26
+ "then": "the shelf entry resolves to Stravica/rcf-lite; the explicit-issues library resolves to its declared repo, derived false; the git-source library resolves to the OWNER/REPO parsed from the URL, derived true; a fourth library with no issues and no github source is returned as unresolved",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-15801-3",
32
+ "description": "rcf doctor gains a warn-only check feedback-destinations that lists every registered library without a resolvable destination (no issues field and no derivable git source) and every applied blueprint whose destination the resolver returns unresolved. --fix does not touch destinations; the fix is for the library owner or the consuming operator.",
33
+ "given": "a fixture with two registered libraries: one with issues, one with neither issues nor a github source",
34
+ "when": "rcf doctor is run",
35
+ "then": "doctor output carries one feedback-destinations warn row naming the second library, --fix is not offered on that row, exit code stays 0",
36
+ "testable": true,
37
+ "scope": "runtime"
38
+ }
39
+ ],
40
+ "createdAt": "2026-09-16T13:45:23.000Z",
41
+ "updatedAt": "2026-09-16T13:45:23.000Z"
42
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "usId": "US-15802",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-158",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Findings on shelf blueprints and on rcf-lite itself go to rcf-lite",
8
+ "asA": "operator whose agent has logged a finding on a shelf blueprint or on rcf-lite core",
9
+ "iWant": "those findings routed to Stravica/rcf-lite by default without any per-project configuration",
10
+ "soThat": "reports about shelf content and core verbs reach the maintainers who own them",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15802-1",
14
+ "description": "A pending entry with kind blueprint and a target that resolves in the manifest without a libraryPrefix (a shelf blueprint) has destination.repo Stravica/rcf-lite on preview and submit. The constant is sourced from packages/rcf-lite/package.json:bugs.url so a rename ripples through one file. A test pins the constant to the current package.json value.",
15
+ "given": "a fixture project applying application-forms-wizard (shelf blueprint) with one pending entry",
16
+ "when": "rcf feedback preview is run",
17
+ "then": "the rendered destination row is \"Stravica/rcf-lite (public)\"; a unit test asserts the constant equals bugs.url from package.json",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-15802-2",
23
+ "description": "A pending entry with kind core (target is a verb path like \"define validate\" or \"docs\") has destination.repo Stravica/rcf-lite regardless of any library manifest content; the entry cannot be routed to a library repo even if a library declares the verb name as a target.",
24
+ "given": "a fixture with a library declaring \"define validate\" as a target and one pending core entry",
25
+ "when": "rcf feedback preview is run",
26
+ "then": "the destination.repo is Stravica/rcf-lite for the core entry; the library declaration is ignored for kind core; a warning is not emitted (this is by design)",
27
+ "testable": true,
28
+ "scope": "library"
29
+ }
30
+ ],
31
+ "createdAt": "2026-09-16T13:45:23.000Z",
32
+ "updatedAt": "2026-09-16T13:45:23.000Z"
33
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "usId": "US-15901",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-159",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator yes files issues under the reporter GitHub login",
8
+ "asA": "operator saying yes to the ask",
9
+ "iWant": "the tool to call gh under my ambient login and file each pending entry as a GitHub issue or +1 comment, mark each entry submitted with the URL, and print the URLs so the agent can relay them",
10
+ "soThat": "reports are visibly mine, with no relay in between and no token handling in the tool",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15901-1",
14
+ "description": "rcf feedback submit --yes runs section-7 preflight, section-6 dedupe search, then gh issue create or gh issue comment per entry (through src/feedback/gh.js, or its RCF_FEEDBACK_GH_MODULE stand-in). Each entry state line records status submitted with issueUrl and dedupe (new|comment|unchecked). Stdout prints one line per entry: \"<id> -> <url> (<dedupe>)\". Exit 0 when every entry ended submitted or bundled; exit 3 when any entry stayed pending (residual secret).",
15
+ "given": "a fixture project with two pending entries and a fake gh module whose create returns an issue URL and whose search returns zero hits",
16
+ "when": "the operator runs rcf feedback submit --yes",
17
+ "then": "both entries fold to status submitted with the returned URL and dedupe new; stdout carries two \"<id> -> <url> (new)\" lines; entries.jsonl is not rewritten (only appended)",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-15901-2",
23
+ "description": "rcf feedback submit without --yes refuses on a non-TTY (exit 2, stderr names the --yes requirement); on a TTY it prompts once and only proceeds on a y answer. The tool never reads GH_TOKEN or GITHUB_TOKEN itself, never asks for a token, and never spawns gh auth login. A test asserts the process env passed to gh is a copy without any TOKEN mutation.",
24
+ "given": "a fixture project with one pending entry, run under a non-TTY child process",
25
+ "when": "rcf feedback submit is run without --yes",
26
+ "then": "exit code 2, stderr names --yes as required; no gh invocation is made; process.env passed through to the fake gh has no synthesised TOKEN key",
27
+ "testable": true,
28
+ "scope": "library"
29
+ }
30
+ ],
31
+ "createdAt": "2026-09-16T13:45:23.000Z",
32
+ "updatedAt": "2026-09-16T13:45:23.000Z"
33
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "usId": "US-15902",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-159",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Labels are applied where the reporter may set them",
8
+ "asA": "maintainer triaging inbound issues",
9
+ "iWant": "rcf-feedback plus severity:<...> plus area:<...> labels applied by the tool when the destination repo carries them and the reporter has push or triage access",
10
+ "soThat": "triage queues sort correctly for reporters who have the right, while outside reporters on a public repo still land readable issues (title prefix and body fingerprint remain the load-bearing handles).",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15902-1",
14
+ "description": "Before create, the tool calls gh label list --json name on the destination repo and intersects the requested labels (\"rcf-feedback\", \"severity:<sev>\", \"area:<blueprint|core>\") with the returned set. Missing labels are dropped from the create call and recorded on the entry state as droppedLabels[] and in the preview ledger.",
15
+ "given": "a fake gh module whose label list returns { rcf-feedback, severity:major } but not area:blueprint",
16
+ "when": "submit --yes is run with one pending major-severity blueprint entry",
17
+ "then": "gh issue create is called with labels rcf-feedback, severity:major only; the entry state carries droppedLabels: [\"area:blueprint\"]",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-15902-2",
23
+ "description": "scripts/bootstrap-feedback-labels.mjs is a one-shot script a repo admin runs to create the six labels in one destination repo: rcf-feedback, severity:blocker, severity:major, severity:minor, area:blueprint, area:core. Idempotent: existing labels are left alone; missing ones are created via gh label create. The script is a maintainer aid, not called from init or doctor.",
24
+ "given": "a fake gh module in the script fixture whose label list starts empty",
25
+ "when": "the script is run once, then again",
26
+ "then": "first run creates six labels via gh label create; second run makes zero create calls; exit 0 on both",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-15902-3",
32
+ "description": "The rendered issue title always carries the prefix (\"[<effective-slug>] \" for blueprints, \"[rcf-lite] \" for core) and the body always carries the visible rcf-feedback-fingerprint: <fp> line plus the HTML-comment twin. Both are load-bearing triage handles when labels are missing or dropped.",
33
+ "given": "render() is called on a blueprint and a core entry",
34
+ "when": "the rendered title and body are compared to templates",
35
+ "then": "blueprint titles start with \"[<slug>] \"; core titles start with \"[rcf-lite] \"; each body carries the fingerprint on its own line and inside an HTML comment (fingerprint appears twice on purpose)",
36
+ "testable": true,
37
+ "scope": "library"
38
+ },
39
+ {
40
+ "id": "AC-15902-4",
41
+ "description": "The six-label catalogue (rcf-feedback, severity:blocker, severity:major, severity:minor, area:blueprint, area:core) is exported as a single frozen constant from src/feedback/labels.js (FEEDBACK_LABELS or equivalent). Both scripts/bootstrap-feedback-labels.mjs and the submit-time label pre-check import that constant and refuse to hard-code any of the six names locally. A grep test asserts no string literal for a catalogue label name appears outside src/feedback/labels.js, its own tests, and the bootstrap script that imports it.",
42
+ "given": "a fresh clone of the repo",
43
+ "when": "the grep test enumerates string literals for each of the six label names across src/, scripts/, bin/",
44
+ "then": "every hit is either inside src/feedback/labels.js, a test file that imports the constant, or the bootstrap script; there is no bare string literal for any of the six names elsewhere",
45
+ "testable": true,
46
+ "scope": "library"
47
+ }
48
+ ],
49
+ "createdAt": "2026-09-16T13:45:23.000Z",
50
+ "updatedAt": "2026-09-16T14:14:36Z"
51
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "usId": "US-16001",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-160",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "No gh, no login or no access still gives the operator a bundle and a URL",
8
+ "asA": "operator without gh installed, not logged in, or without access to a private destination repo",
9
+ "iWant": "submit to write a bundle file with the exact issue text and print the file path and the destination issues/new URL in one line",
10
+ "soThat": "I can paste or email the report even when the tool cannot file it on my behalf, and I am not asked about the same entries again next session",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-16001-1",
14
+ "description": "Preflight order (per destination): gh on PATH -> gh auth status non-zero -> gh repo view viewerPermission NONE on a private repo -> gh repo view hasIssuesEnabled false. The first failure routes to a bundle for that destination without any further gh call. The bundle path <cwd>/.rcf/feedback/outbox/<ISO-timestamp>-<repo-slug>.md is printed on its own line next to the destination issues/new URL. Each failure kind maps to a distinct one-line message (naming gh, naming \"run gh auth login\", naming private-access with the library contact, naming issues-disabled).",
15
+ "given": "four fixture cases: gh missing on PATH; gh present but auth status non-zero; repo private with viewerPermission NONE; repo with hasIssuesEnabled false",
16
+ "when": "submit --yes is run once per case with one pending entry",
17
+ "then": "each run writes the bundle under outbox with the expected filename shape and prints the URL and path on one line together; entry state is bundled with outboxPath; exit code 0",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-16001-2",
23
+ "description": "If create or comment fails after the label pre-check (network 4xx or 5xx, abuse rate limit, unexpected label rejection), submit retries once without labels and, on a second failure, bundles that entry only. Other entries continue. Exit code is 0 when every entry ended submitted or bundled, and 3 when a residual secret leaves one entry pending.",
24
+ "given": "a fake gh module whose issue create throws with a 429-shaped error on the first two calls and succeeds on the third",
25
+ "when": "submit --yes runs with three pending entries",
26
+ "then": "the first entry retries once, then bundles; the second retries once, then bundles; the third submits; exit 0; two bundle files exist and the third entry is submitted",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-16001-3",
32
+ "description": "Bundled entries are terminal for the ask loop: rcf feedback list default (pending) does not show them, the SessionStart hook does not count them into the carry-over ask, and the Stop hook does not re-ask about them. rcf feedback submit <id> re-attempts one bundled entry by hand and moves it to submitted on success.",
33
+ "given": "a fixture with two bundled entries and one pending entry",
34
+ "when": "the Stop hook decision function is invoked and rcf feedback list default is called",
35
+ "then": "Stop asks only about the pending entry, list shows only the pending entry, list --all shows the bundled entries with status bundled; submit fb-<id-of-bundle> retries just that one",
36
+ "testable": true,
37
+ "scope": "library"
38
+ },
39
+ {
40
+ "id": "AC-16001-4",
41
+ "description": "When submit encounters an entry whose destination cannot be resolved (library without an issues field and no derivable git source, so destination.resolve() returned unresolved), the entry is written to the bundle at .rcf/feedback/outbox/<ISO-timestamp>-unresolved.md, the publisher contact from the registry entry (if present) is printed on the same line as the outbox path, no gh call is made for that entry, and exit code stays 0. The entry state folds to bundled with outboxPath.",
42
+ "given": "a fixture project with one applied library whose registry entry carries neither issuesRepo nor a derivable github git source but does carry publisher.contact, and one pending blueprint entry against that library",
43
+ "when": "submit --yes is run",
44
+ "then": "the outbox file exists with the unresolved-slug filename, stdout carries the publisher.contact on the same line as the outbox path, no gh invocation was made, entry state is bundled, exit code is 0",
45
+ "testable": true,
46
+ "scope": "library"
47
+ }
48
+ ],
49
+ "createdAt": "2026-09-16T13:45:23.000Z",
50
+ "updatedAt": "2026-09-16T14:14:36Z"
51
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "usId": "US-16101",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-161",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator is asked once, at a pause, with the exact preview text, and never nagged",
8
+ "asA": "operator in the middle of getting work done",
9
+ "iWant": "the ask to arrive at a natural pause (queue complete, an entry older than 15 minutes, a carried-over entry, or a --ask-now blocker), for the ask to carry the exact preview text and destination, and for me never to be asked twice in one session",
10
+ "soThat": "the ask is welcome rather than an interruption",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-16101-1",
14
+ "description": "The quiet rule in src/feedback/hook.js returns \"ask\" on stop when ALL hold: not opted out (rcf/feedback-settings.json ask true and RCF_FEEDBACK_ASK unset or 1); at least one pending entry; state.json has no asked record for the incoming session_id; stop_hook_active is false; and one of: an entry carries askNow; the newest pending entry is older than quietMinutes (default 15) minutes; the queue-state cache reports complete or nothing actionable; the entry was carried over. Otherwise returns \"silent\". A table test walks every named row.",
15
+ "given": "a fixture state file and a table of pending/asked/optOut/stopHookActive/age/queueState/carriedOver/askNow rows",
16
+ "when": "shouldAsk(input) is called on each row",
17
+ "then": "every row returns the expected verdict; the asked record is appended to state.json before the emit path in the wrapper (assertable at the caller by observing state mutation before hook stdout is produced)",
18
+ "testable": true,
19
+ "scope": "library"
20
+ },
21
+ {
22
+ "id": "AC-16101-2",
23
+ "description": "On Claude Code (--harness claude-code default when CLAUDECODE is set), the stop hook exits 2 with the reason text on stderr. The reason names the exact next-step verbs (\"rcf feedback preview\", \"rcf feedback submit --yes\", \"rcf feedback defer\", \"rcf feedback opt-out\") and says \"Do not ask again this session.\" On Codex (--harness codex), the hook emits stdout JSON { \"decision\": \"block\", \"reason\": \"<same text>\" } with exit 0. Both branches append the asked record to state.json exactly once per session_id.",
24
+ "given": "a fixture project with one pending entry, and two mock harness JSON inputs on stdin (Claude Code and Codex shapes)",
25
+ "when": "rcf feedback hook stop --harness claude-code and --harness codex are run",
26
+ "then": "Claude Code run: exit code 2, stderr carries the four verb names and the \"do not ask again this session\" clause; Codex run: exit 0, stdout parses to { decision: \"block\", reason: ... } with the same clause; state.json in both cases gained exactly one asked record for the input session_id",
27
+ "testable": true,
28
+ "scope": "library"
29
+ },
30
+ {
31
+ "id": "AC-16101-3",
32
+ "description": "A second stop invocation with the same session_id is silent (no exit-2, no JSON block emission, exit 0) even when new pending entries arrive after the first ask. A new session_id resets the ledger and asks again per the quiet rule.",
33
+ "given": "a fixture state.json with one asked record, one further pending entry added after the ask",
34
+ "when": "rcf feedback hook stop is run twice with the same session_id and then once with a fresh session_id",
35
+ "then": "the two same-session calls are silent (exit 0, no reason emitted); the fresh-session call re-emits the ask per the quiet rule",
36
+ "testable": true,
37
+ "scope": "library"
38
+ }
39
+ ],
40
+ "createdAt": "2026-09-16T13:45:23.000Z",
41
+ "updatedAt": "2026-09-16T13:45:23.000Z"
42
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "usId": "US-16102",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-161",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Operator silences the ask for this project",
8
+ "asA": "operator who does not want to be asked about feedback on this project",
9
+ "iWant": "a one-command opt-out that writes rcf/feedback-settings.json:ask false (checked in), and an env variable that silences the ask per user without touching the file",
10
+ "soThat": "a shared project silences the ask for everyone, and a CI or per-user preference silences it locally",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-16102-1",
14
+ "description": "rcf feedback opt-out writes rcf/feedback-settings.json with { settingsVersion: 1, ask: false, redaction: { allowHosts: [] }, quietMinutes: 15 } (merging with any prior file). rcf feedback opt-in restores ask true. The hook shouldAsk returns silent when ask is false. rcf feedback add, preview and submit keep working under ask: false (hand-driven flow).",
15
+ "given": "a fresh fixture project",
16
+ "when": "rcf feedback opt-out then rcf feedback hook stop with one pending entry, then rcf feedback preview",
17
+ "then": "the settings file contains ask: false; the hook exits 0 silently; preview still renders the entry",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ },
21
+ {
22
+ "id": "AC-16102-2",
23
+ "description": "RCF_FEEDBACK_ASK=0 forces silent on the hook regardless of file setting. RCF_FEEDBACK_DISABLE=1 makes rcf feedback add a no-op that prints \"feedback disabled by env\" (no file write, no exit-2). Precedence order: env DISABLE > env ASK=0 > file ask false > file ask true.",
24
+ "given": "a fixture project with ask true in the file, plus each env variable in turn",
25
+ "when": "rcf feedback add and rcf feedback hook stop are run under each precedence combination",
26
+ "then": "env DISABLE suppresses add entirely; env ASK=0 keeps add working but silences the hook; file ask false silences the hook and add still works",
27
+ "testable": true,
28
+ "scope": "library"
29
+ }
30
+ ],
31
+ "createdAt": "2026-09-16T13:45:23.000Z",
32
+ "updatedAt": "2026-09-16T14:14:36Z"
33
+ }