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,177 @@
1
+ // Shared helpers for application-spa probes.
2
+ //
3
+ // The engine under probe is the sample-app fixture at
4
+ // packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js. The
5
+ // fixture stamps an x-fixture-request-id header on every response as
6
+ // part of its own request pipeline (no probe-side monkey-patch), so
7
+ // the identifier the probe records is the identifier the engine
8
+ // itself issued. Probes call the fixture over real HTTP via node's
9
+ // fetch, vary inputs, assert derived outputs, and record the
10
+ // request-id, status, body excerpt, the varied input and the derived
11
+ // output as evidence on every result row.
12
+ // No account-bound branch: the engine is a local fixture, not a
13
+ // third-party account, so no CI_HAS_* gate is invented. Every env
14
+ // var this pack reads is declared on the fixture README.
15
+
16
+ import { mkdir, writeFile } from 'node:fs/promises';
17
+ import { dirname, resolve } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+
20
+ const HERE = dirname(fileURLToPath(import.meta.url));
21
+ export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
22
+ export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/probe-pack-application-spa');
23
+ export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/application-spa');
24
+
25
+ export const DEFAULT_PORT = 0;
26
+
27
+ export function aggregate(results) {
28
+ if (!Array.isArray(results) || results.length === 0) return 'fail';
29
+ if (results.some((r) => r.verdict === 'fail')) return 'fail';
30
+ if (results.some((r) => r.verdict === 'warn')) return 'warn';
31
+ return 'pass';
32
+ }
33
+
34
+ // Empty results never pass: a synthesised row is emitted with an actionable detail and its
35
+ // own evidence object recording the empty condition so the row is
36
+ // not a naked verdict scalar.
37
+ export function normaliseResults(results) {
38
+ if (!Array.isArray(results) || results.length === 0) {
39
+ return [{
40
+ anchorReqId: 'unknown',
41
+ verdict: 'fail',
42
+ detail: 'no checks ran',
43
+ evidence: {
44
+ reason: 'empty-results',
45
+ route: 'n/a',
46
+ status: 0,
47
+ xFixtureRequestId: null,
48
+ bodyExcerpt: '',
49
+ },
50
+ }];
51
+ }
52
+ return results;
53
+ }
54
+
55
+ export async function writeReport({ probeName, engine, results, extra }) {
56
+ await mkdir(REPORT_DIR, { recursive: true });
57
+ const report = {
58
+ slug: 'application-spa',
59
+ probeName,
60
+ runAt: new Date().toISOString(),
61
+ engine,
62
+ results,
63
+ aggregateVerdict: aggregate(results),
64
+ ...(extra ?? {}),
65
+ };
66
+ const path = resolve(REPORT_DIR, `${probeName}.json`);
67
+ await writeFile(path, JSON.stringify(report, null, 2) + '\n', 'utf8');
68
+ return { report, path };
69
+ }
70
+
71
+ // Starts the fixture on an ephemeral port (or PROBE_PORT when set)
72
+ // and returns { server, port, baseUrl, close }. The close helper
73
+ // rejects when the underlying close callback carries an error;
74
+ // swallowing a teardown error would hide a boundary failure.
75
+ export async function startFixture({ startServer, port } = {}) {
76
+ const resolvedPort = typeof port === 'number'
77
+ ? port
78
+ : Number(process.env.PROBE_PORT ?? DEFAULT_PORT);
79
+ const started = await startServer({ port: resolvedPort });
80
+ return {
81
+ server: started.server,
82
+ port: started.port,
83
+ baseUrl: `http://127.0.0.1:${started.port}`,
84
+ close: () => new Promise((res, rej) => started.server.close((err) => {
85
+ if (err) rej(err);
86
+ else res();
87
+ })),
88
+ };
89
+ }
90
+
91
+ // Reads a distinctive slice of a response body: the first N chars
92
+ // so the report carries a body excerpt alongside the header id.
93
+ export function bodyExcerpt(text, max = 240) {
94
+ if (text == null) return '';
95
+ const s = typeof text === 'string' ? text : String(text);
96
+ return s.length > max ? s.slice(0, max) + '...' : s;
97
+ }
98
+
99
+ // Records the positive-evidence shape on a probe result. Every row
100
+ // carries route, status, the request id the fixture stamped, and a
101
+ // body excerpt; the caller may extend the object with the varied
102
+ // input and the derived output for that row.
103
+ export function evidenceFromResponse({ route, response, bodyText, extraFields }) {
104
+ return {
105
+ route,
106
+ status: response.status,
107
+ xFixtureRequestId: response.headers.get('x-fixture-request-id') || null,
108
+ bodyExcerpt: bodyExcerpt(bodyText),
109
+ ...(extraFields ?? {}),
110
+ };
111
+ }
112
+
113
+ export async function runShim(probeName, engine, mainFn) {
114
+ try {
115
+ const outcome = (await mainFn()) ?? { results: [] };
116
+ const { results, extra } = outcome;
117
+ const { report, path } = await writeReport({ probeName, engine, results: normaliseResults(results), extra });
118
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
119
+ process.stdout.write(`report written to ${path}\n`);
120
+ if (report.aggregateVerdict !== 'pass') process.exitCode = 1;
121
+ } catch (err) {
122
+ const results = [{
123
+ anchorReqId: 'unknown',
124
+ verdict: 'fail',
125
+ detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
126
+ evidence: {
127
+ reason: 'probe-threw',
128
+ route: 'n/a',
129
+ status: 0,
130
+ xFixtureRequestId: null,
131
+ bodyExcerpt: err && err.stack ? String(err.stack).slice(0, 240) : '',
132
+ },
133
+ }];
134
+ const { report, path } = await writeReport({ probeName, engine, results });
135
+ process.stdout.write(JSON.stringify(report, null, 2) + '\n');
136
+ process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
137
+ process.stderr.write(`report written to ${path}\n`);
138
+ process.exitCode = 1;
139
+ }
140
+ }
141
+
142
+ // Browser-observable properties are AMBER on the shelf by ruling.
143
+ // A row that names such a property is recorded as notObservableHere
144
+ // carrying an object with the AC id and a reason; the tally script
145
+ // reads notObservableHere.ac to accept the row.
146
+ export function notObservableHereResult({ ac, anchorAcId, detail, reason, evidence } = {}) {
147
+ // A notObservableHere row anchors nothing else: no anchorAcId,
148
+ // no anchorReqId - only notObservableHere.ac.
149
+ const acId = ac || anchorAcId;
150
+ return {
151
+ verdict: 'pass',
152
+ notObservableHere: {
153
+ ac: acId,
154
+ reason: reason || 'not observable on server-side probe pack; needs a browser-driven runner',
155
+ },
156
+ detail: detail || 'not observable on server-side probe pack',
157
+ evidence: {
158
+ reason: reason || 'not observable here; needs a browser-driven probe runner',
159
+ ...(evidence || {}),
160
+ },
161
+ };
162
+ }
163
+
164
+ // A row that keeps a real observation but records that the
165
+ // observation only covers part of an AC uses conformanceOnly +
166
+ // limitation carrying the AC id and the property not observed.
167
+ export function conformanceOnlyResult({ anchorAcId, anchorReqId, verdict, detail, evidence, limitation }) {
168
+ return {
169
+ ...(anchorAcId ? { anchorAcId } : {}),
170
+ ...(anchorReqId ? { anchorReqId } : {}),
171
+ verdict: verdict || 'pass',
172
+ conformanceOnly: true,
173
+ limitation: limitation || 'browser-observable property not asserted from the server-side probe',
174
+ detail,
175
+ evidence,
176
+ };
177
+ }
@@ -0,0 +1,185 @@
1
+ // route-inventory-published probe for application-spa v1.5.11.
2
+ //
3
+ // Verifies AC-1101-1: the project maintains a declared route
4
+ // inventory naming every route AND no navigable surface exists
5
+ // outside it. To rule out fixture self-agreement the probe drives
6
+ // two independent inputs it controls:
7
+ //
8
+ // Run A: routes = [/, /alpha, /beta]
9
+ // Run B: routes = [/, /gamma, /delta, /epsilon]
10
+ //
11
+ // For each run the probe reads /__routes and /__mounted and
12
+ // checks both endpoints reflect the injected input verbatim,
13
+ // then crawls every declared path (expects 200) and every path
14
+ // from the OTHER run's set that is NOT in the current set (expects
15
+ // 404). If /__routes or /__mounted diverged from the injected
16
+ // input, or if a path outside the input responded 200, the row
17
+ // fails. The two runs together establish input-driven variation.
18
+ //
19
+ // anchorAcId: application-spa-AC-1101-1.
20
+
21
+ import { startFixture, evidenceFromResponse, conformanceOnlyResult } from './probe-utils.mjs';
22
+
23
+ export const anchorReqId = 'application-spa-REQ-001';
24
+ export const accountBound = false;
25
+
26
+ const RUN_A_ROUTES = [
27
+ { path: '/', name: 'landing', state: 'populated', dataBearing: false },
28
+ { path: '/alpha', name: 'alpha', state: 'populated', dataBearing: true },
29
+ { path: '/beta', name: 'beta', state: 'populated', dataBearing: false },
30
+ ];
31
+ const RUN_B_ROUTES = [
32
+ { path: '/', name: 'landing', state: 'populated', dataBearing: false },
33
+ { path: '/gamma', name: 'gamma', state: 'populated', dataBearing: true },
34
+ { path: '/delta', name: 'delta', state: 'populated', dataBearing: false },
35
+ { path: '/epsilon', name: 'epsilon', state: 'empty', dataBearing: true },
36
+ ];
37
+
38
+ async function runOne(routeSet, otherSet) {
39
+ const { startServer } = await import('../../../../packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js');
40
+ const fixture = await startFixture({ startServer: (opts) => startServer({ ...opts, routes: routeSet }), port: 0 });
41
+ try {
42
+ const declaredPaths = routeSet.map((r) => r.path);
43
+ const routesRes = await fetch(`${fixture.baseUrl}/__routes`);
44
+ const routesBody = await routesRes.text();
45
+ const routesJson = JSON.parse(routesBody);
46
+ const routesPaths = (routesJson.routes || []).map((r) => r.path);
47
+
48
+ const mountedRes = await fetch(`${fixture.baseUrl}/__mounted`);
49
+ const mountedBody = await mountedRes.text();
50
+ const mountedJson = JSON.parse(mountedBody);
51
+ const mountedPaths = mountedJson.paths || [];
52
+
53
+ const perPath = {};
54
+ for (const p of declaredPaths) {
55
+ const r = await fetch(`${fixture.baseUrl}${p}`);
56
+ const body = await r.text();
57
+ perPath[p] = { status: r.status, ok: r.status === 200 && /<main[^>]+data-route=/.test(body) };
58
+ }
59
+
60
+ // Paths NOT in the injected inventory must 404. We take them
61
+ // from the OTHER run's set (minus paths shared with this run).
62
+ const shared = new Set(declaredPaths);
63
+ const outsidePaths = otherSet.map((r) => r.path).filter((p) => !shared.has(p));
64
+ const perOutside = {};
65
+ for (const p of outsidePaths) {
66
+ const r = await fetch(`${fixture.baseUrl}${p}`);
67
+ await r.text();
68
+ perOutside[p] = { status: r.status, ok: r.status === 404 };
69
+ }
70
+
71
+ const routesMatchInput = declaredPaths.length === routesPaths.length && declaredPaths.every((p) => routesPaths.includes(p));
72
+ const mountedMatchInput = declaredPaths.length === mountedPaths.length && declaredPaths.every((p) => mountedPaths.includes(p));
73
+ const declaredAll200 = Object.values(perPath).every((v) => v.ok);
74
+ const outsideAll404 = Object.values(perOutside).every((v) => v.ok);
75
+ return {
76
+ routesRes,
77
+ routesBody,
78
+ mountedRes,
79
+ mountedBody,
80
+ declaredPaths,
81
+ routesPaths,
82
+ mountedPaths,
83
+ outsidePaths,
84
+ perPath,
85
+ perOutside,
86
+ routesMatchInput,
87
+ mountedMatchInput,
88
+ declaredAll200,
89
+ outsideAll404,
90
+ };
91
+ } finally {
92
+ await fixture.close();
93
+ }
94
+ }
95
+
96
+ export default async function runProbe() {
97
+ const results = [];
98
+ const runA = await runOne(RUN_A_ROUTES, RUN_B_ROUTES);
99
+ const runB = await runOne(RUN_B_ROUTES, RUN_A_ROUTES);
100
+
101
+ const bothMatchInput = runA.routesMatchInput && runA.mountedMatchInput && runB.routesMatchInput && runB.mountedMatchInput;
102
+ const bothDeclared200 = runA.declaredAll200 && runB.declaredAll200;
103
+ const bothOutside404 = runA.outsideAll404 && runB.outsideAll404;
104
+ const pass = bothMatchInput && bothDeclared200 && bothOutside404;
105
+
106
+ results.push({
107
+ anchorAcId: 'application-spa-AC-1101-1',
108
+ anchorReqId: 'application-spa-REQ-001',
109
+ verdict: pass ? 'pass' : 'fail',
110
+ detail: `The project maintains a declared route inventory naming every route; no navigable surface exists outside it - runA(${runA.declaredPaths.join(',')}) routes=${runA.routesMatchInput} mounted=${runA.mountedMatchInput} declared200=${runA.declaredAll200} outside404=${runA.outsideAll404}; runB(${runB.declaredPaths.join(',')}) routes=${runB.routesMatchInput} mounted=${runB.mountedMatchInput} declared200=${runB.declaredAll200} outside404=${runB.outsideAll404}`,
111
+ evidence: evidenceFromResponse({
112
+ route: '/__routes (runA)',
113
+ response: runA.routesRes,
114
+ bodyText: runA.routesBody,
115
+ extraFields: {
116
+ input: {
117
+ runARoutes: RUN_A_ROUTES.map((r) => r.path),
118
+ runBRoutes: RUN_B_ROUTES.map((r) => r.path),
119
+ },
120
+ derived: {
121
+ runA: {
122
+ routesPaths: runA.routesPaths,
123
+ mountedPaths: runA.mountedPaths,
124
+ routesMatchInput: runA.routesMatchInput,
125
+ mountedMatchInput: runA.mountedMatchInput,
126
+ perPath: runA.perPath,
127
+ outsidePaths: runA.outsidePaths,
128
+ perOutside: runA.perOutside,
129
+ },
130
+ runB: {
131
+ routesPaths: runB.routesPaths,
132
+ mountedPaths: runB.mountedPaths,
133
+ routesMatchInput: runB.routesMatchInput,
134
+ mountedMatchInput: runB.mountedMatchInput,
135
+ perPath: runB.perPath,
136
+ outsidePaths: runB.outsidePaths,
137
+ perOutside: runB.perOutside,
138
+ },
139
+ },
140
+ altBodyExcerpt: runB.routesBody.slice(0, 240),
141
+ },
142
+ }),
143
+ });
144
+
145
+ // Second row: shell <meta name="route-inventory"> agrees with
146
+ // /__routes and /__mounted under run A. This observation covers
147
+ // only a same-run agreement slice of AC-1101-1 (route-inventory
148
+ // completeness across the app) and is emitted as conformanceOnly
149
+ // anchored on AC-1101-1 with a limitation naming the property the
150
+ // slice does not observe. The first row already carries the full
151
+ // positive AC-1101-1 observation across two injected sets.
152
+ const { startServer } = await import('../../../../packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js');
153
+ const fixture = await startFixture({ startServer: (opts) => startServer({ ...opts, routes: RUN_A_ROUTES }), port: 0 });
154
+ let shellRes; let shellBody; let shellPaths = []; let shellAgreesJson = false; let shellAgreesMounted = false;
155
+ try {
156
+ shellRes = await fetch(`${fixture.baseUrl}/`);
157
+ shellBody = await shellRes.text();
158
+ const metaMatch = shellBody.match(/<meta name="route-inventory" content="([^"]+)"/);
159
+ shellPaths = metaMatch ? metaMatch[1].split(',') : [];
160
+ const declaredSet = new Set(RUN_A_ROUTES.map((r) => r.path));
161
+ shellAgreesJson = shellPaths.length === RUN_A_ROUTES.length && shellPaths.every((p) => declaredSet.has(p));
162
+ shellAgreesMounted = shellPaths.every((p) => runA.mountedPaths.includes(p));
163
+ } finally {
164
+ await fixture.close();
165
+ }
166
+ const agreeAll = shellAgreesJson && shellAgreesMounted;
167
+ results.push(conformanceOnlyResult({
168
+ anchorAcId: 'application-spa-AC-1101-1',
169
+ anchorReqId: 'application-spa-REQ-001',
170
+ verdict: agreeAll ? 'pass' : 'fail',
171
+ detail: `The project maintains a declared route inventory naming every route - same-run agreement slice: shell <meta name="route-inventory"> ${shellPaths.join(',')} agrees with /__routes JSON: ${shellAgreesJson} and /__mounted: ${shellAgreesMounted}`,
172
+ evidence: evidenceFromResponse({
173
+ route: '/',
174
+ response: shellRes,
175
+ bodyText: shellBody,
176
+ extraFields: {
177
+ input: { shellMetaPaths: shellPaths, injectedRoutes: RUN_A_ROUTES.map((r) => r.path) },
178
+ derived: { shellAgreesJson, shellAgreesMounted, agreeAll },
179
+ },
180
+ }),
181
+ limitation: 'application-spa-AC-1101-1: this row observes only same-run agreement between the shell meta, /__routes and /__mounted for one injected set; the AC also requires that no navigable surface exists outside the declared inventory, which the first AC-1101-1 row observes by injecting two independent route sets and confirming outsiders return 404',
182
+ }));
183
+
184
+ return { results };
185
+ }
@@ -0,0 +1,5 @@
1
+ import runProbe from './designed-empty-state.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = { kind: 'application-spa-fixture', server: 'packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js' };
5
+ runShim('designed-empty-state', engine, runProbe);
@@ -0,0 +1,5 @@
1
+ import runProbe from './route-inventory-published.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = { kind: 'application-spa-fixture', server: 'packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js' };
5
+ runShim('route-inventory-published', engine, runProbe);
@@ -0,0 +1,5 @@
1
+ import runProbe from './shell-nav-present.mjs';
2
+ import { runShim } from './probe-utils.mjs';
3
+
4
+ const engine = { kind: 'application-spa-fixture', server: 'packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js' };
5
+ runShim('shell-nav-present', engine, runProbe);
@@ -0,0 +1,69 @@
1
+ // shell-nav-present probe for application-spa v1.5.11.
2
+ //
3
+ // Verifies AC-1102-1: navigation renders on every route (not only
4
+ // the shell root). The probe crawls every declared inventory path,
5
+ // GETs each, and asserts the primary <nav> block appears in every
6
+ // rendered page with one link per inventory entry.
7
+ //
8
+ // anchorAcId: application-spa-AC-1102-1.
9
+
10
+ import { startFixture, evidenceFromResponse } from './probe-utils.mjs';
11
+
12
+ export const anchorReqId = 'application-spa-REQ-002';
13
+ export const accountBound = false;
14
+
15
+ export default async function runProbe() {
16
+ const { startServer } = await import('../../../../packages/rcf-lite/test/fixtures/probe-pack-application-spa/server.js');
17
+ const fixture = await startFixture({ startServer, port: 0 });
18
+ try {
19
+ const results = [];
20
+
21
+ const routesRes = await fetch(`${fixture.baseUrl}/__routes`);
22
+ const routesJson = JSON.parse(await routesRes.text());
23
+ const inventory = routesJson.routes || [];
24
+ const inventoryNames = inventory.map((r) => r.name);
25
+
26
+ const perRoute = {};
27
+ let allPerRoutePass = true;
28
+ let firstFailBody = '';
29
+ let lastRoute = null;
30
+ let lastBody = null;
31
+ let lastRes = null;
32
+
33
+ for (const r of inventory) {
34
+ const shellRes = await fetch(`${fixture.baseUrl}${r.path}`);
35
+ const body = await shellRes.text();
36
+ lastRes = shellRes; lastBody = body; lastRoute = r.path;
37
+ const navMatch = body.match(/<nav[^>]+aria-label="Primary"[^>]+data-region="primary-nav"[^>]*>([\s\S]*?)<\/nav>/);
38
+ const hasNav = !!navMatch;
39
+ const linksInNav = hasNav
40
+ ? Array.from(navMatch[1].matchAll(/data-route-name="([^"]+)"/g)).map((m) => m[1])
41
+ : [];
42
+ const linksParity = linksInNav.length === inventoryNames.length
43
+ && inventoryNames.every((n) => linksInNav.includes(n));
44
+ const routePass = shellRes.status === 200 && hasNav && linksParity;
45
+ perRoute[r.path] = { status: shellRes.status, hasNav, linksInNav, routePass };
46
+ if (!routePass) { allPerRoutePass = false; if (!firstFailBody) firstFailBody = body.slice(0, 240); }
47
+ }
48
+ const pass = allPerRoutePass && inventory.length > 0;
49
+
50
+ results.push({
51
+ anchorAcId: 'application-spa-AC-1102-1',
52
+ anchorReqId: 'application-spa-REQ-002',
53
+ verdict: pass ? 'pass' : 'fail',
54
+ detail: `Top navigation renders on every route from the - primary <nav aria-label="Primary"> renders on all ${Object.keys(perRoute).length} routes; every route carries links [${inventoryNames.join(',')}]`,
55
+ evidence: evidenceFromResponse({
56
+ route: lastRoute || '/',
57
+ response: lastRes,
58
+ bodyText: lastBody,
59
+ extraFields: {
60
+ input: { inventoryPaths: inventory.map((r) => r.path), inventoryNames },
61
+ derived: { perRoute, allRoutesRenderNav: allPerRoutePass, firstFailBody },
62
+ },
63
+ }),
64
+ });
65
+ return { results };
66
+ } finally {
67
+ await fixture.close();
68
+ }
69
+ }
@@ -5,7 +5,7 @@
5
5
  "version": "1.0.1",
6
6
  "status": "approved",
7
7
  "name": "Token adherence probe",
8
- "purpose": "The runtime-observable enforcement handle for the ADR-202 theming discipline. The blueprint declares that component styles consume semantic tokens only, that raw palette values are a defect, and that every light token has a declared dark counterpart (application-spa-REQ-005, US-1106). Watchpost run4 demonstrated that declaring the discipline does not compel the shipped surface: build cycles ran green while raw hex values sat in component stylesheets. This TAC is the project-realised probe that inspects the built stylesheet output plus the design-tokens JSON, refuses at non-zero exit when the discipline is violated, and writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
8
+ "purpose": "The runtime-observable enforcement handle for the ADR-202 theming discipline. The blueprint declares that component styles consume semantic tokens only, that raw palette values are a defect, and that every light token has a declared dark counterpart (application-spa-REQ-005, US-1106). This TAC is the project-realised probe that inspects the built stylesheet output plus the design-tokens JSON, refuses at non-zero exit on any raw palette literal outside the token-realisation file or any missing light/dark counterpart, and writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
9
9
  "responsibilities": [
10
10
  "Expose a Node entry point (a single `.js` or `.mjs` file) invocable as `node <path>` with no shell glue; the entry point path is stable and recorded on the aggregate report's `runner.entryPoint` field when this probe is wired as a delivery-ci-workflows gate (AC-1129-1, AC-1129-4).",
11
11
  "Read the design tokens source at a configured path (default `assets/tokens/design-tokens.json` per ADR-202) and enumerate the semantic token key sets for both themes (AC-1129-2).",
@@ -5,7 +5,7 @@
5
5
  "version": "1.0.1",
6
6
  "status": "approved",
7
7
  "name": "Icon adherence probe",
8
- "purpose": "The runtime-observable enforcement handle for the ADR-206 iconography discipline. The blueprint declares that components reference icons only through the semantic alias registry and that bespoke per-component artwork is an extension to the registry rather than inline SVG (application-spa-REQ-011, US-1118). Watchpost run4 shipped zero icons across eight surfaces while the build cycle ran green; declaring the discipline is not the same as compelling it. This TAC is the project-realised probe that inspects the shipped component source (or built bundle), refuses at non-zero exit when a component sidesteps the alias registry, and writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
8
+ "purpose": "The runtime-observable enforcement handle for the ADR-206 iconography discipline. The blueprint declares that components reference icons only through the semantic alias registry and that bespoke per-component artwork is an extension to the registry rather than inline SVG (application-spa-REQ-011, US-1118). This TAC is the project-realised probe that inspects the shipped component source (or built bundle), refuses at non-zero exit on any inline SVG outside the registry or any icon reference naming an alias the registry does not declare, and writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
9
9
  "responsibilities": [
10
10
  "Expose a Node entry point (a single `.js` or `.mjs` file) invocable as `node <path>` with no shell glue; the entry point path is stable and recorded on the aggregate report's `runner.entryPoint` field when this probe is wired as a delivery-ci-workflows gate (AC-1130-1, AC-1130-4).",
11
11
  "Read the icon alias registry at a configured path (default `assets/icons/aliases.json` or the project-declared equivalent per ADR-206) and enumerate the declared alias names (AC-1130-2).",
@@ -50,7 +50,7 @@
50
50
  "description": "When this probe is wired as a delivery-ci-workflows gate, the runner invokes it as a child process, captures the exit code, and delegates the per-gate report write to TAC-702. The probe writes its own detailed report; the gate report writer records the exit-code envelope."
51
51
  }
52
52
  ],
53
- "tradeoffs": "Scanning source for inline SVG accepts that a project may sometimes ship a genuinely single-use bespoke glyph; the discipline says such a glyph joins the registry rather than living inline, and the probe surfaces the choice at the ship gate rather than at design review. The alias-reference scanner needs a project-declared reference-shape pattern (JSX prop, function call, or template literal); the probe ships a small pattern library and the project selects the shape it uses. The cost is one line of configuration; the buy is a runtime-observable enforcement that closes the mechanism-reach gap watchpost run4 caught.",
53
+ "tradeoffs": "Scanning source for inline SVG accepts that a project may sometimes ship a genuinely single-use bespoke glyph; the discipline says such a glyph joins the registry rather than living inline, and the probe surfaces the choice at the ship gate rather than at the design gate. The alias-reference scanner needs a project-declared reference-shape pattern (JSX prop, function call, or template literal); the probe ships a small pattern library and the project selects the shape it uses. The cost is one line of configuration; the buy is a runtime-observable enforcement that closes the mechanism-reach gap this probe cures.",
54
54
  "createdAt": "2026-08-24T00:00:00Z",
55
55
  "updatedAt": "2026-08-24T00:00:00Z"
56
56
  }
@@ -5,14 +5,14 @@
5
5
  "version": "1.0.2",
6
6
  "status": "approved",
7
7
  "name": "Styled-under-shipped-CSP adherence probe",
8
- "purpose": "The runtime-observable enforcement handle for application-spa-REQ-018 (SPA security baselines: CSP, sanitised dynamic HTML, hardened cookies, secret-free bundle). Watchpost run4 demonstrated the mechanism-reach gap this probe cures: FBS-011 declared a strict CSP (style-src 'self', no unsafe-inline), FBS-013/015 rendered inline <style> blocks, every existing UI-bearing gate passed (28 styled screenshots, browser-verify green), and yet every production page rendered unstyled at deploy because the harness bypassed the production security-header path. This TAC is the project-realised probe that (a) refuses any inline <style> block in the rendered HTML surface, (b) refuses a CSP that relaxes style-src to unsafe-inline, and (c) drives a real browser at the same server instance that stamps the production headers to prove the shipped stylesheet actually reaches the runtime surface. Writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
8
+ "purpose": "The runtime-observable enforcement handle for application-spa-REQ-018 (SPA security baselines: CSP, sanitised dynamic HTML, hardened cookies, secret-free bundle). This TAC is the project-realised probe that (a) refuses any inline <style> block in the rendered HTML surface, (b) refuses a CSP that relaxes style-src to unsafe-inline, and (c) drives a real browser at the same server instance that stamps the production headers to prove the shipped stylesheet actually reaches the runtime surface. Writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
9
9
  "responsibilities": [
10
10
  "Expose a Node entry point (a single `.js` or `.mjs` file) invocable as `node <path>` with no shell glue; the entry point path is stable and recorded on the aggregate report's `runner.entryPoint` field when this probe is wired as a delivery-ci-workflows gate (AC-1131-5, AC-1131-6).",
11
11
  "Accept configuration naming (i) how to boot the target server (a Node module or command that starts the same server instance the production entry point starts, with the same route registration), (ii) the enumerated set of UI-bearing routes to probe, and (iii) the stylesheet URL every rendered document is expected to link (AC-1131-3, AC-1131-4).",
12
12
  "For every enumerated route: navigate a real headless browser to the served URL, capture the response `content-security-policy` header, capture the response body, read the browser's final URL after any redirect chain resolves, run getComputedStyle on document.body, and record the results (AC-1131-1, AC-1131-2, AC-1131-3).",
13
13
  "Refuse the run when any captured CSP declares 'unsafe-inline' or 'unsafe-eval' on style-src, when style-src is absent, or when style-src is served as a wildcard (AC-1131-1).",
14
14
  "Refuse the run when any captured response body contains a `<style` substring (case-insensitive), including <style> injected by templating helpers (AC-1131-2).",
15
- "Refuse the run when the browser's final URL path for any enumerated route does NOT equal the requested route path (a `pathMismatch` refusal class); a headless browser follows redirects by default, so a session-broken authenticated route silently 302'ing to a styled /login would otherwise cause every downstream styled-body assertion below to pass against the redirect target rather than the requested surface. The refusal names both the requested and the landed path (AC-1131-3, the watchpost run4 partial-acceptance class defect).",
15
+ "Refuse the run when the browser's final URL path for any enumerated route does NOT equal the requested route path (a `pathMismatch` refusal class); a headless browser follows redirects by default, so a session-broken authenticated route silently 302'ing to a styled /login would otherwise cause every downstream styled-body assertion below to pass against the redirect target rather than the requested surface. The refusal names both the requested and the landed path (AC-1131-3, `pathMismatch`).",
16
16
  "Refuse the run when the computed body backgroundColor for any route is the browser default (`rgba(0, 0, 0, 0)` / `transparent`) or when the computed body fontFamily resolves to an empty value; both indicate the shipped stylesheet did NOT reach the runtime surface under the production headers (AC-1131-3).",
17
17
  "Issue a same-origin GET against the linked stylesheet URL through the same server instance and refuse when the response is not 200 with content-type `text/css` (AC-1131-4).",
18
18
  "Write a JSON report at a stable relative path (`reports/csp-styled-adherence.json` under the configured report directory, matching the delivery-ci-workflows per-gate report shape of TAC-702) naming: every route probed, the CSP header captured, whether an inline <style> was detected, the computed background and fontFamily values, the stylesheet GET verdict, and an ok / fail verdict (AC-1131-5).",
@@ -55,7 +55,7 @@
55
55
  "description": "When this probe is wired as a delivery-ci-workflows gate, the runner invokes it as a child process, captures the exit code, and delegates the per-gate report write to TAC-702 in the ordinary way. The probe writes its own detailed report; the gate report writer records the exit-code envelope."
56
56
  }
57
57
  ],
58
- "tradeoffs": "The probe requires a real browser and a running server for every delivery-ci-workflows invocation. That cost buys the runtime-observable enforcement the mechanism-reach gap at watchpost run4 proved was missing: build cycles ran green and shipped an unstyled surface because no gate exercised the production header path with a real browser. Driving the shipped construction (not a bespoke harness) is the load-bearing choice; refusing app.inject() satisfaction is deliberate. The requirement that verification runs THROUGH the shipped headers is what makes the AC bite; a probe that stamps its own headers would recreate the class defect it exists to refuse. The v1.0.1 landed-path refusal cures a second gap the same class defect exposed: Playwright's `page.goto` follows redirects by default and returns the FINAL response, so a session-broken authenticated route silently 302'ing to a styled /login left every downstream styled-body assertion validating the login page instead of the requested surface (the watchpost partial-acceptance class defect). Comparing `new URL(page.url()).pathname` to the enumerated route path is the cheapest structural refusal that closes the gap without coupling the probe to session-lane internals.",
58
+ "tradeoffs": "The probe requires a real browser and a running server for every delivery-ci-workflows invocation. That cost buys runtime-observable enforcement of the production header path: driving the shipped construction (not a bespoke harness) is the load-bearing choice, and refusing app.inject() satisfaction is deliberate because a probe that stamps its own headers cannot refuse a CSP defect. The landed-path refusal is necessary because Playwright's `page.goto` follows redirects by default and returns the FINAL response, so without a final-path check a session-broken authenticated route that silently 302's to a styled /login would leave every downstream styled-body assertion validating the login page instead of the requested surface. Comparing `new URL(page.url()).pathname` to the enumerated route path is the cheapest structural refusal that closes that gap without coupling the probe to session-lane internals.",
59
59
  "createdAt": "2026-08-24T10:30:00Z",
60
60
  "updatedAt": "2026-08-31T11:15:00Z"
61
61
  }
@@ -5,7 +5,7 @@
5
5
  "version": "1.0.1",
6
6
  "status": "approved",
7
7
  "name": "External-service-dependency provisioning adherence probe",
8
- "purpose": "The runtime-observable enforcement handle for the deployment-gate class defect the watchpost first-production review caught: the only login path (magic-link email) shipped inert because RESEND_API_KEY was a placeholder, the gap was filed as a 'quirk' in status.md rather than blocked at sign-off, and a real key existed in the estate all along. This TAC is the project-realised probe that (a) refuses any placeholder-shape value in a credential field named on the application's external-service-dependency manifest, (b) requires captured live-handshake evidence for every dependency at status 'verified', (c) requires an operator-ratified persistent deferral record for every dependency at status 'deferred' (a README note, a status.md quirk line, or a code comment does NOT satisfy), and (d) writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
8
+ "purpose": "The runtime-observable enforcement handle for external-service-dependency provisioning discipline. This TAC is the project-realised probe that (a) refuses any placeholder-shape value in a credential field named on the application's external-service-dependency manifest, (b) requires captured live-handshake evidence for every dependency at status 'verified', (c) requires an operator-ratified persistent deferral record for every dependency at status 'deferred' (a README note, a status.md line, or a code comment does NOT satisfy), and (d) writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
9
9
  "responsibilities": [
10
10
  "Expose a Node entry point (a single '.js' or '.mjs' file) invocable as 'node <path>' with no shell glue; the entry point path is stable and recorded on the aggregate report's 'runner.entryPoint' field when this probe is wired as a delivery-ci-workflows gate (AC-1132-5, AC-1132-6).",
11
11
  "Accept configuration naming (i) the path of the application's external-service-dependency manifest, (ii) how to boot the target server for handshake evidence (a Node module or command that starts the same server instance the production entry point starts, with the same route registration and middleware stack), (iii) the path of the ratified-deferrals store the deferral records live in, and (iv) the report directory (AC-1132-1, AC-1132-3, AC-1132-4).",
@@ -64,7 +64,7 @@
64
64
  "description": "When this probe is wired as a delivery-ci-workflows gate, the runner invokes it as a child process, captures the exit code, and delegates the per-gate report write to TAC-702 in the ordinary way. The probe writes its own detailed report; the gate report writer records the exit-code envelope."
65
65
  }
66
66
  ],
67
- "tradeoffs": "The probe requires a running server booted through the production construction and network reach to real external providers for every delivery-ci-workflows invocation. That cost buys the runtime-observable enforcement the watchpost first-production defect proved was missing: the build cycle ran green, sign-off said DEPLOYED, and the only login path was inert on a placeholder credential. Requiring a manifest is a deliberate load-bearing choice: without the manifest, the enumeration set of runtime-reached externals is invisible to the gate. Requiring the ratified-deferrals store to be a persistent machine-readable artefact (not a README note) is the choice that refuses the 'quirk-in-status.md' pattern the class defect exposed. Extending the detector's ruleset in rcf-lite (rather than per-project) is deliberate: one authoritative catalogue of placeholder shapes serves every downstream project.",
67
+ "tradeoffs": "The probe requires a running server booted through the production construction and network reach to real external providers for every delivery-ci-workflows invocation. Requiring a manifest is a deliberate load-bearing choice: without the manifest, the enumeration set of runtime-reached externals is invisible to the gate. Requiring the ratified-deferrals store to be a persistent machine-readable artefact (not a README note) makes deferrals durable and machine-checkable rather than prose the gate cannot inspect. Extending the detector's ruleset in rcf-lite (rather than per-project) is deliberate: one authoritative catalogue of placeholder shapes serves every downstream project.",
68
68
  "createdAt": "2026-08-24T13:00:00Z",
69
69
  "updatedAt": "2026-08-24T13:00:00Z"
70
70
  }
@@ -5,7 +5,7 @@
5
5
  "version": "1.0.1",
6
6
  "status": "approved",
7
7
  "name": "Core-flow end-to-end adherence probe",
8
- "purpose": "The runtime-observable enforcement handle for application-spa-REQ-008 (journey completeness) at ship. Watchpost first production demonstrated the deployment-gate class defect this probe cures: the app was signed off as DEPLOYED, admin access was reachable only via ssh-minted tokens because magic-link email never worked in production, and the authentication core flow was never proven end-to-end in the shipped runtime. This TAC is the project-realised probe that (a) enumerates the app's core flows from a stable manifest and refuses when authentication is absent from the manifest while application-spa-REQ-009 surfaces are present, (b) drives a real browser through every enumerated flow against the shipped runtime and real external-service providers, (c) captures per-flow evidence sufficient to reconstruct the run, (d) refuses on any skipped, timed-out, absent, or failed flow (a documented workaround does NOT satisfy), and (e) writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
8
+ "purpose": "The runtime-observable enforcement handle for application-spa-REQ-008 (journey completeness) at ship. This TAC is the project-realised probe that (a) enumerates the app's core flows from a stable manifest and refuses when authentication is absent from the manifest while application-spa-REQ-009 surfaces are present, (b) drives a real browser through every enumerated flow against the shipped runtime and real external-service providers, (c) captures per-flow evidence sufficient to reconstruct the run, (d) refuses on any skipped, timed-out, absent, or failed flow (a documented workaround does NOT satisfy), and (e) writes a stable JSON report the delivery-ci-workflows aggregate report can name.",
9
9
  "responsibilities": [
10
10
  "Expose a Node entry point (a single '.js' or '.mjs' file) invocable as 'node <path>' with no shell glue; the entry point path is stable and recorded on the aggregate report's 'runner.entryPoint' field when this probe is wired as a delivery-ci-workflows gate (AC-1133-5, AC-1133-6).",
11
11
  "Accept configuration naming (i) the path of the application's core-flow manifest, (ii) how to boot the target server (a Node module or command that starts the same server instance the production entry point starts, with the same route registration, the same production security-header stack, and the same middleware), (iii) how to reach real external-service providers (the deferrals-permission is the same shape as TAC-210 accepts for its 'deferred' entries), and (iv) the report directory (AC-1133-1, AC-1133-2, AC-1133-4).",
@@ -64,7 +64,7 @@
64
64
  "description": "When this probe is wired as a delivery-ci-workflows gate, the runner invokes it as a child process, captures the exit code, and delegates the per-gate report write to TAC-702 in the ordinary way. The probe writes its own detailed report; the gate report writer records the exit-code envelope."
65
65
  }
66
66
  ],
67
- "tradeoffs": "The probe requires a real browser, the shipped server construction, and network reach to real external providers for every delivery-ci-workflows invocation. That cost buys the runtime-observable enforcement the watchpost first-production defect proved was missing: sign-off said DEPLOYED, admin login was only reachable via a manually minted token, and no gate demanded the auth flow work end-to-end in the shipped runtime. Requiring an auth-flow-enumeration hard invariant is deliberate: authentication is the flow the class-defect instance exposed, and its enumeration cannot be optional when application-spa-REQ-009 surfaces are present. Refusing to accept a 'documented workaround' as sign-off is the choice that refuses the 'quirk-in-status.md' pattern; the aggregate 'deployed-with-defects' vocabulary is what the probe emits to name the distinction between 'shipped and accepted' and 'shipped with a broken core flow'.",
67
+ "tradeoffs": "The probe requires a real browser, the shipped server construction, and network reach to real external providers for every delivery-ci-workflows invocation. Requiring an auth-flow-enumeration hard invariant is deliberate: authentication cannot be optional when application-spa-REQ-009 surfaces are present, because a manifest that omits it would silently permit a shipped surface with no proven login path. Refusing to accept a 'documented workaround' as passing is what forces broken or skipped flows into the aggregate; the 'ok' | 'deployed-with-defects' vocabulary is what the probe emits to name the distinction between 'every core flow proved' and 'shipped with a broken or unproven core flow'.",
68
68
  "createdAt": "2026-08-24T13:00:00Z",
69
69
  "updatedAt": "2026-08-24T13:00:00Z"
70
70
  }
@@ -31,7 +31,7 @@
31
31
  },
32
32
  {
33
33
  "id": "AC-1131-3",
34
- "description": "Every UI-bearing route renders styled UNDER the shipped strict CSP, AND the probe proves it exercised the requested surface (not a page a redirect would land on). A browser-driven check drives the same server instance that stamps the production security headers, navigates each enumerated UI route, and asserts (a) the browser's final URL path equals the requested route path; a silent redirect (for example an authenticated route 302'ing to /login when the harness session is broken) is a hard refusal because a headless browser follows redirects by default and would otherwise validate the redirect target's styled state seven times over, and (b) the computed body background is NOT the browser default (rgba(0,0,0,0) / transparent) and the computed body font-family resolves to a non-empty value. Verification runs through the production header path; a harness that strips the security headers, injects nonces the CSP does not declare, or invokes the app via app.inject() rather than a real browser fetch does NOT satisfy the AC. Cures the class of harness where a broken session lane silently causes every route assertion to run against /login (styled) and pass (a partial-acceptance class defect a prior review caught). Applying agent sets: the enumerated list of UI-bearing routes to probe, the production boot command the probe invokes, and the strict-CSP header set the production runtime stamps on every response.",
34
+ "description": "Every UI-bearing route renders styled UNDER the shipped strict CSP, AND the probe proves it exercised the requested surface (not a page a redirect would land on). A browser-driven check drives the same server instance that stamps the production security headers, navigates each enumerated UI route, and asserts (a) the browser's final URL path equals the requested route path; a silent redirect (for example an authenticated route 302'ing to /login when the harness session is broken) is a hard refusal because a headless browser follows redirects by default and would otherwise validate the redirect target's styled state seven times over, and (b) the computed body background is NOT the browser default (rgba(0,0,0,0) / transparent) and the computed body font-family resolves to a non-empty value. Verification runs through the production header path; a harness that strips the security headers, injects nonces the CSP does not declare, or invokes the app via app.inject() rather than a real browser fetch does NOT satisfy the AC. Applying agent sets: the enumerated list of UI-bearing routes to probe, the production boot command the probe invokes, and the strict-CSP header set the production runtime stamps on every response.",
35
35
  "given": "a server booted through the project's production entry point with every UI-bearing route registered",
36
36
  "when": "a real browser navigates each enumerated route, its final URL is read, and getComputedStyle(document.body) is read",
37
37
  "then": "the final URL path equals the requested route (no silent redirect chain to another surface) AND the computed background is not the browser default AND the computed font-family resolves; on any route the check fails, the run refuses ship with a per-route diagnostic naming the requested and landed paths",
@@ -79,4 +79,4 @@ Suffix-family ids (ADR, TAC) are string-distinct once slug-suffixed. SPA numbers
79
79
 
80
80
  ## v1.0.0 US-1101 collision note (preserved)
81
81
 
82
- In run4 of the watchpost case study, a project-side `US-1101` derived mechanically from `REQ-011` (leading `11` + sequence `01`) collided with the application-spa blueprint's `application-spa-us-1101` at the AC-id-scoping bucket. The seat allocated the project story as `US-1181` and moved on. Lesson: keep contributions on the LOW end of the band and leave headroom at the HIGH end for project-side stories that mechanically derive to your numbers. v1.1 preserves this lesson: US-1129 and US-1130 remain at the low end.
82
+ A project-side `US-1101` derived mechanically from `REQ-011` (leading `11` + sequence `01`) collides with the application-spa blueprint's `application-spa-us-1101` at the AC-id-scoping bucket; the project story is allocated as `US-1181` instead. Rule: keep contributions on the LOW end of the band and leave headroom at the HIGH end for project-side stories that mechanically derive to your numbers. v1.1 preserves this rule: US-1129 and US-1130 remain at the low end.