rcf-lite 0.20.0 → 0.22.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 (532) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/blueprints/application-account-settings/CHANGELOG.md +12 -0
  3. package/blueprints/application-account-settings/README.md +114 -0
  4. package/blueprints/application-account-settings/blueprint.json +234 -0
  5. package/blueprints/application-account-settings/contributions/adrs/adr-2601-application-account-settings-capability-vocabulary.json +20 -0
  6. package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +20 -0
  7. package/blueprints/application-account-settings/contributions/adrs/adr-2603-application-account-settings-theme-persistence.json +20 -0
  8. package/blueprints/application-account-settings/contributions/adrs/adr-2604-application-account-settings-reauth-window.json +20 -0
  9. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +18 -0
  10. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +18 -0
  11. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +18 -0
  12. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +18 -0
  13. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +18 -0
  14. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +18 -0
  15. package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +41 -0
  16. package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +28 -0
  17. package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +35 -0
  18. package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +40 -0
  19. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25101.json +34 -0
  20. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25102.json +27 -0
  21. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25103.json +27 -0
  22. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25104.json +27 -0
  23. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +33 -0
  24. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +27 -0
  25. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25107.json +27 -0
  26. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25108.json +27 -0
  27. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25109.json +33 -0
  28. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25110.json +27 -0
  29. package/blueprints/application-account-settings/docs/topics.md +48 -0
  30. package/blueprints/application-account-settings/guide/application-account-settings.md +30 -0
  31. package/blueprints/application-account-settings/probe-packs/application-account-settings.pack.mjs +246 -0
  32. package/blueprints/application-admin-console/CHANGELOG.md +11 -0
  33. package/blueprints/application-admin-console/README.md +98 -0
  34. package/blueprints/application-admin-console/blueprint.json +226 -0
  35. package/blueprints/application-admin-console/contributions/adrs/adr-2201-application-admin-console-capability-vocabulary.json +25 -0
  36. package/blueprints/application-admin-console/contributions/adrs/adr-2202-application-admin-console-baseline-roles.json +25 -0
  37. package/blueprints/application-admin-console/contributions/adrs/adr-2203-application-admin-console-invite-transport.json +20 -0
  38. package/blueprints/application-admin-console/contributions/adrs/adr-2204-application-admin-console-audit-retention.json +20 -0
  39. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-001.json +18 -0
  40. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-002.json +18 -0
  41. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-003.json +18 -0
  42. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-004.json +18 -0
  43. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-005.json +18 -0
  44. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-006.json +18 -0
  45. package/blueprints/application-admin-console/contributions/tacs/tac-2201-application-admin-console-shell.json +40 -0
  46. package/blueprints/application-admin-console/contributions/tacs/tac-2202-application-admin-console-capability-discovery.json +44 -0
  47. package/blueprints/application-admin-console/contributions/tacs/tac-2203-application-admin-console-permission-matrix.json +34 -0
  48. package/blueprints/application-admin-console/contributions/tacs/tac-2204-application-admin-console-audit-view.json +40 -0
  49. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21101.json +34 -0
  50. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21102.json +34 -0
  51. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21103.json +34 -0
  52. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21104.json +28 -0
  53. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21105.json +34 -0
  54. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21106.json +27 -0
  55. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21107.json +27 -0
  56. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21108.json +27 -0
  57. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21109.json +33 -0
  58. package/blueprints/application-admin-console/docs/topics.md +42 -0
  59. package/blueprints/application-admin-console/guide/application-admin-console.md +29 -0
  60. package/blueprints/application-admin-console/probe-packs/application-admin-console.pack.mjs +182 -0
  61. package/blueprints/application-api-rest/docs/topics.md +13 -1
  62. package/blueprints/application-charts/CHANGELOG.md +12 -0
  63. package/blueprints/application-charts/README.md +73 -0
  64. package/blueprints/application-charts/blueprint.json +26 -0
  65. package/blueprints/application-charts/contributions/adrs/adr-1901-application-charts-engine-choice.json +25 -0
  66. package/blueprints/application-charts/contributions/adrs/adr-1902-application-charts-accessible-palette.json +25 -0
  67. package/blueprints/application-charts/contributions/adrs/adr-1903-application-charts-motion.json +25 -0
  68. package/blueprints/application-charts/contributions/requirements/application-charts-req-001.json +15 -0
  69. package/blueprints/application-charts/contributions/requirements/application-charts-req-002.json +15 -0
  70. package/blueprints/application-charts/contributions/requirements/application-charts-req-003.json +15 -0
  71. package/blueprints/application-charts/contributions/requirements/application-charts-req-004.json +15 -0
  72. package/blueprints/application-charts/contributions/tacs/tac-1901-application-charts-render-shell.json +42 -0
  73. package/blueprints/application-charts/contributions/tacs/tac-1902-application-charts-keyboard-traversal.json +40 -0
  74. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18101.json +35 -0
  75. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18102.json +35 -0
  76. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18103.json +35 -0
  77. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18104.json +35 -0
  78. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18105.json +35 -0
  79. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18106.json +35 -0
  80. package/blueprints/application-charts/docs/topics.md +44 -0
  81. package/blueprints/application-charts/guide/application-charts.md +44 -0
  82. package/blueprints/application-charts/probe-packs/application-charts.pack.mjs +191 -0
  83. package/blueprints/application-dashboard/CHANGELOG.md +10 -0
  84. package/blueprints/application-dashboard/README.md +102 -0
  85. package/blueprints/application-dashboard/assets/guidance/dashboard-design.md +124 -0
  86. package/blueprints/application-dashboard/blueprint.json +29 -0
  87. package/blueprints/application-dashboard/contributions/adrs/adr-2001-application-dashboard-primary-kpi-enum.json +25 -0
  88. package/blueprints/application-dashboard/contributions/adrs/adr-2002-application-dashboard-timeframe-presets.json +25 -0
  89. package/blueprints/application-dashboard/contributions/adrs/adr-2003-application-dashboard-export-formats.json +25 -0
  90. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-001.json +15 -0
  91. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-002.json +15 -0
  92. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-003.json +15 -0
  93. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-004.json +15 -0
  94. package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-005.json +15 -0
  95. package/blueprints/application-dashboard/contributions/tacs/tac-2001-application-dashboard-tile-grid.json +47 -0
  96. package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +41 -0
  97. package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +35 -0
  98. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19101.json +35 -0
  99. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19102.json +35 -0
  100. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19103.json +35 -0
  101. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19104.json +35 -0
  102. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19105.json +35 -0
  103. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +35 -0
  104. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19107.json +35 -0
  105. package/blueprints/application-dashboard/docs/topics.md +50 -0
  106. package/blueprints/application-dashboard/guide/application-dashboard.md +48 -0
  107. package/blueprints/application-dashboard/probe-packs/application-dashboard.pack.mjs +231 -0
  108. package/blueprints/application-datatable/CHANGELOG.md +8 -0
  109. package/blueprints/application-datatable/README.md +43 -0
  110. package/blueprints/application-datatable/blueprint.json +33 -0
  111. package/blueprints/application-datatable/contributions/adrs/adr-1801-application-datatable-pattern-choice.json +25 -0
  112. package/blueprints/application-datatable/contributions/adrs/adr-1802-application-datatable-url-state.json +20 -0
  113. package/blueprints/application-datatable/contributions/adrs/adr-1803-application-datatable-page-size.json +20 -0
  114. package/blueprints/application-datatable/contributions/adrs/adr-1804-application-datatable-selection-persistence.json +20 -0
  115. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-001.json +15 -0
  116. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-002.json +15 -0
  117. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-003.json +15 -0
  118. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-004.json +15 -0
  119. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-005.json +15 -0
  120. package/blueprints/application-datatable/contributions/requirements/application-datatable-req-006.json +15 -0
  121. package/blueprints/application-datatable/contributions/tacs/tac-1801-application-datatable-shell.json +50 -0
  122. package/blueprints/application-datatable/contributions/tacs/tac-1802-application-datatable-query-adapter.json +39 -0
  123. package/blueprints/application-datatable/contributions/tacs/tac-1803-application-datatable-selection-model.json +28 -0
  124. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17101.json +44 -0
  125. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17102.json +44 -0
  126. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17103.json +44 -0
  127. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17104.json +44 -0
  128. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17105.json +44 -0
  129. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17106.json +44 -0
  130. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17107.json +44 -0
  131. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17108.json +44 -0
  132. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17109.json +44 -0
  133. package/blueprints/application-datatable/docs/topics.md +42 -0
  134. package/blueprints/application-datatable/guide/application-datatable.md +38 -0
  135. package/blueprints/application-datatable/probe-packs/application-datatable.pack.mjs +240 -0
  136. package/blueprints/application-empty-error-states/CHANGELOG.md +9 -0
  137. package/blueprints/application-empty-error-states/README.md +88 -0
  138. package/blueprints/application-empty-error-states/blueprint.json +119 -0
  139. package/blueprints/application-empty-error-states/contributions/adrs/adr-2301-application-empty-error-states-status-contract.json +25 -0
  140. package/blueprints/application-empty-error-states/contributions/adrs/adr-2302-application-empty-error-states-stack-trace-visibility.json +25 -0
  141. package/blueprints/application-empty-error-states/contributions/adrs/adr-2303-application-empty-error-states-offline-strategy.json +25 -0
  142. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +18 -0
  143. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +18 -0
  144. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +18 -0
  145. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +18 -0
  146. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +18 -0
  147. package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +46 -0
  148. package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +36 -0
  149. package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +40 -0
  150. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22101.json +29 -0
  151. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22102.json +29 -0
  152. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22103.json +29 -0
  153. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22104.json +29 -0
  154. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22105.json +29 -0
  155. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22106.json +29 -0
  156. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22107.json +29 -0
  157. package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22108.json +29 -0
  158. package/blueprints/application-empty-error-states/docs/topics.md +53 -0
  159. package/blueprints/application-empty-error-states/guide/application-empty-error-states.md +50 -0
  160. package/blueprints/application-empty-error-states/probe-packs/application-empty-error-states.pack.mjs +284 -0
  161. package/blueprints/application-error-handling/docs/topics.md +12 -0
  162. package/blueprints/application-file-upload/CHANGELOG.md +9 -0
  163. package/blueprints/application-file-upload/README.md +85 -0
  164. package/blueprints/application-file-upload/blueprint.json +114 -0
  165. package/blueprints/application-file-upload/contributions/adrs/adr-2401-application-file-upload-transport.json +25 -0
  166. package/blueprints/application-file-upload/contributions/adrs/adr-2402-application-file-upload-accepted-set.json +25 -0
  167. package/blueprints/application-file-upload/contributions/adrs/adr-2403-application-file-upload-virus-scan.json +25 -0
  168. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +18 -0
  169. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +18 -0
  170. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +18 -0
  171. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +18 -0
  172. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +18 -0
  173. package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +46 -0
  174. package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +47 -0
  175. package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +46 -0
  176. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23101.json +28 -0
  177. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +28 -0
  178. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23103.json +29 -0
  179. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23104.json +28 -0
  180. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +29 -0
  181. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23106.json +28 -0
  182. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23107.json +28 -0
  183. package/blueprints/application-file-upload/docs/topics.md +58 -0
  184. package/blueprints/application-file-upload/guide/application-file-upload.md +48 -0
  185. package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +238 -0
  186. package/blueprints/application-forms-wizard/CHANGELOG.md +9 -0
  187. package/blueprints/application-forms-wizard/README.md +102 -0
  188. package/blueprints/application-forms-wizard/blueprint.json +120 -0
  189. package/blueprints/application-forms-wizard/contributions/adrs/adr-2501-application-forms-wizard-navigation.json +25 -0
  190. package/blueprints/application-forms-wizard/contributions/adrs/adr-2502-application-forms-wizard-save-and-return.json +25 -0
  191. package/blueprints/application-forms-wizard/contributions/adrs/adr-2503-application-forms-wizard-step-indicator.json +25 -0
  192. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +18 -0
  193. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +18 -0
  194. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +18 -0
  195. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +18 -0
  196. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +18 -0
  197. package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +46 -0
  198. package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +40 -0
  199. package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +40 -0
  200. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +28 -0
  201. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24102.json +29 -0
  202. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24103.json +28 -0
  203. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24104.json +29 -0
  204. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24105.json +28 -0
  205. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24106.json +28 -0
  206. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24107.json +28 -0
  207. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24108.json +29 -0
  208. package/blueprints/application-forms-wizard/docs/topics.md +49 -0
  209. package/blueprints/application-forms-wizard/guide/application-forms-wizard.md +48 -0
  210. package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +233 -0
  211. package/blueprints/application-notifications-in-app/CHANGELOG.md +9 -0
  212. package/blueprints/application-notifications-in-app/README.md +80 -0
  213. package/blueprints/application-notifications-in-app/blueprint.json +30 -0
  214. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2101-application-notifications-in-app-live-region-role-mapping.json +25 -0
  215. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2102-application-notifications-in-app-toast-timeout-floor.json +25 -0
  216. package/blueprints/application-notifications-in-app/contributions/adrs/adr-2103-application-notifications-in-app-retention-window.json +25 -0
  217. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-001.json +15 -0
  218. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-002.json +15 -0
  219. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-003.json +15 -0
  220. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-004.json +15 -0
  221. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-005.json +15 -0
  222. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +46 -0
  223. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +52 -0
  224. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2103-application-notifications-in-app-preferences.json +40 -0
  225. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +35 -0
  226. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +35 -0
  227. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +35 -0
  228. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20104.json +35 -0
  229. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +35 -0
  230. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20106.json +26 -0
  231. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20107.json +26 -0
  232. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20108.json +26 -0
  233. package/blueprints/application-notifications-in-app/docs/topics.md +46 -0
  234. package/blueprints/application-notifications-in-app/guide/application-notifications-in-app.md +47 -0
  235. package/blueprints/application-notifications-in-app/probe-packs/application-notifications-in-app.pack.mjs +328 -0
  236. package/blueprints/application-onboarding-tour/CHANGELOG.md +12 -0
  237. package/blueprints/application-onboarding-tour/README.md +77 -0
  238. package/blueprints/application-onboarding-tour/blueprint.json +164 -0
  239. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2701-application-onboarding-tour-dismissal-policy.json +20 -0
  240. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2702-application-onboarding-tour-completion-store-shape.json +20 -0
  241. package/blueprints/application-onboarding-tour/contributions/adrs/adr-2703-application-onboarding-tour-checklist-anchor.json +20 -0
  242. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +18 -0
  243. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +18 -0
  244. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +18 -0
  245. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +18 -0
  246. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +41 -0
  247. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +35 -0
  248. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +34 -0
  249. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26101.json +27 -0
  250. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26102.json +27 -0
  251. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26103.json +27 -0
  252. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26104.json +27 -0
  253. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26105.json +27 -0
  254. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26106.json +27 -0
  255. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26107.json +27 -0
  256. package/blueprints/application-onboarding-tour/docs/topics.md +48 -0
  257. package/blueprints/application-onboarding-tour/guide/application-onboarding-tour.md +59 -0
  258. package/blueprints/application-onboarding-tour/probe-packs/application-onboarding-tour.pack.mjs +231 -0
  259. package/blueprints/application-spa/docs/topics.md +13 -1
  260. package/blueprints/delivery-ci-workflows/docs/topics.md +13 -1
  261. package/blueprints/deploy-cloudflare-workers/docs/topics.md +13 -1
  262. package/blueprints/email-smtp-resend/docs/topics.md +13 -1
  263. package/blueprints/object-storage-s3/CHANGELOG.md +13 -0
  264. package/blueprints/object-storage-s3/README.md +108 -0
  265. package/blueprints/object-storage-s3/blueprint.json +72 -0
  266. package/blueprints/object-storage-s3/contributions/adrs/adr-2901-object-storage-s3-adapter.json +30 -0
  267. package/blueprints/object-storage-s3/contributions/adrs/adr-2902-object-storage-s3-presigned-ttl-floor.json +25 -0
  268. package/blueprints/object-storage-s3/contributions/adrs/adr-2903-object-storage-s3-multipart-threshold.json +25 -0
  269. package/blueprints/object-storage-s3/contributions/adrs/adr-2904-object-storage-s3-contract.json +25 -0
  270. package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +103 -0
  271. package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +43 -0
  272. package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +84 -0
  273. package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +101 -0
  274. package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +85 -0
  275. package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +84 -0
  276. package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +64 -0
  277. package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +4 -0
  278. package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +10 -0
  279. package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +4 -0
  280. package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +4 -0
  281. package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +7 -0
  282. package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +4 -0
  283. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +18 -0
  284. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +18 -0
  285. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +18 -0
  286. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +18 -0
  287. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +18 -0
  288. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +18 -0
  289. package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +57 -0
  290. package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +36 -0
  291. package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +36 -0
  292. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +34 -0
  293. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +43 -0
  294. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +25 -0
  295. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +34 -0
  296. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +25 -0
  297. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +34 -0
  298. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28107.json +34 -0
  299. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28108.json +34 -0
  300. package/blueprints/object-storage-s3/docs/topics.md +62 -0
  301. package/blueprints/object-storage-s3/guide/object-storage-s3.md +207 -0
  302. package/blueprints/observability-essentials/docs/topics.md +13 -1
  303. package/blueprints/observability-logging/CHANGELOG.md +9 -0
  304. package/blueprints/observability-logging/README.md +4 -1
  305. package/blueprints/observability-logging/blueprint.json +114 -21
  306. package/blueprints/observability-logging/docs/topics.md +12 -0
  307. package/blueprints/observability-probe-endpoints/docs/topics.md +13 -1
  308. package/blueprints/persistence-data-d1/docs/topics.md +13 -1
  309. package/blueprints/persistence-data-postgres/CHANGELOG.md +12 -0
  310. package/blueprints/persistence-data-postgres/README.md +101 -0
  311. package/blueprints/persistence-data-postgres/blueprint.json +80 -0
  312. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +30 -0
  313. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2802-persistence-data-postgres-migration-shape.json +25 -0
  314. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2803-persistence-data-postgres-runner-mode.json +25 -0
  315. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2804-persistence-data-postgres-recovery.json +25 -0
  316. package/blueprints/persistence-data-postgres/contributions/adrs/adr-2805-persistence-data-postgres-connection-pool-posture.json +25 -0
  317. package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +56 -0
  318. package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +75 -0
  319. package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +56 -0
  320. package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +186 -0
  321. package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +76 -0
  322. package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +173 -0
  323. package/blueprints/persistence-data-postgres/contributions/probes/run-facade-round-trip.mjs +10 -0
  324. package/blueprints/persistence-data-postgres/contributions/probes/run-migration-apply.mjs +10 -0
  325. package/blueprints/persistence-data-postgres/contributions/probes/run-pool-posture-smoke.mjs +9 -0
  326. package/blueprints/persistence-data-postgres/contributions/probes/run-prepared-statement-scan.mjs +10 -0
  327. package/blueprints/persistence-data-postgres/contributions/probes/run-recovery-restore-round-trip.mjs +9 -0
  328. package/blueprints/persistence-data-postgres/contributions/probes/run-transaction-atomicity.mjs +10 -0
  329. package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +79 -0
  330. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +18 -0
  331. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +18 -0
  332. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +18 -0
  333. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +18 -0
  334. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +18 -0
  335. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +18 -0
  336. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +18 -0
  337. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +58 -0
  338. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +40 -0
  339. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +35 -0
  340. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +40 -0
  341. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +34 -0
  342. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +25 -0
  343. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +25 -0
  344. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +25 -0
  345. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +25 -0
  346. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +25 -0
  347. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +25 -0
  348. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +25 -0
  349. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +25 -0
  350. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +25 -0
  351. package/blueprints/persistence-data-postgres/docs/topics.md +64 -0
  352. package/blueprints/persistence-data-postgres/guide/persistence-data-postgres.md +172 -0
  353. package/blueprints/persistence-data-sqlite/docs/topics.md +13 -1
  354. package/blueprints/security-auth-clerk/CHANGELOG.md +9 -0
  355. package/blueprints/security-auth-clerk/README.md +3 -0
  356. package/blueprints/security-auth-clerk/blueprint.json +147 -29
  357. package/blueprints/security-auth-clerk/docs/topics.md +13 -1
  358. package/blueprints/security-auth-keycloak/CHANGELOG.md +9 -0
  359. package/blueprints/security-auth-keycloak/README.md +3 -0
  360. package/blueprints/security-auth-keycloak/blueprint.json +182 -36
  361. package/blueprints/security-auth-keycloak/docs/topics.md +13 -1
  362. package/blueprints/security-auth-magic-link/CHANGELOG.md +9 -0
  363. package/blueprints/security-auth-magic-link/README.md +3 -0
  364. package/blueprints/security-auth-magic-link/blueprint.json +159 -32
  365. package/blueprints/security-auth-magic-link/docs/topics.md +13 -1
  366. package/blueprints/security-auth-oauth2/CHANGELOG.md +9 -0
  367. package/blueprints/security-auth-oauth2/README.md +3 -0
  368. package/blueprints/security-auth-oauth2/blueprint.json +158 -31
  369. package/blueprints/security-auth-oauth2/docs/topics.md +13 -1
  370. package/blueprints/security-secrets-management/CHANGELOG.md +11 -0
  371. package/blueprints/security-secrets-management/blueprint.json +2 -1
  372. package/blueprints/security-secrets-management/docs/topics.md +13 -1
  373. package/fixtures/canary-manifest.json +9 -9
  374. package/package.json +2 -2
  375. package/rcf/code-nodes/cn-106.json +13 -0
  376. package/rcf/code-nodes/cn-107.json +14 -0
  377. package/rcf/code-nodes/cn-108.json +13 -0
  378. package/rcf/code-nodes/cn-109.json +12 -0
  379. package/rcf/code-nodes/cn-110.json +12 -0
  380. package/rcf/code-nodes/cn-111.json +14 -0
  381. package/rcf/code-nodes/cn-112.json +14 -0
  382. package/rcf/code-nodes/cn-113.json +12 -0
  383. package/rcf/code-nodes/cn-114.json +13 -0
  384. package/rcf/code-nodes/cn-115.json +13 -0
  385. package/rcf/code-nodes/cn-116.json +12 -0
  386. package/rcf/code-nodes/cn-117.json +13 -0
  387. package/rcf/code-nodes/cn-118.json +13 -0
  388. package/rcf/code-nodes/cn-119.json +13 -0
  389. package/rcf/code-nodes/cn-120.json +13 -0
  390. package/rcf/code-nodes/cn-121.json +12 -0
  391. package/rcf/code-nodes/cn-122.json +12 -0
  392. package/rcf/code-nodes/cn-123.json +13 -0
  393. package/rcf/code-nodes/cn-124.json +13 -0
  394. package/rcf/code-nodes/cn-125.json +13 -0
  395. package/rcf/code-nodes/cn-126.json +13 -0
  396. package/rcf/code-nodes/cn-127.json +12 -0
  397. package/rcf/code-nodes/cn-128.json +14 -0
  398. package/rcf/code-nodes/cn-129.json +14 -0
  399. package/rcf/code-nodes/cn-130.json +14 -0
  400. package/rcf/code-nodes/cn-131.json +15 -0
  401. package/rcf/code-nodes/cn-132.json +12 -0
  402. package/rcf/code-nodes/cn-133.json +13 -0
  403. package/rcf/code-nodes/cn-134.json +13 -0
  404. package/rcf/code-nodes/cn-135.json +12 -0
  405. package/rcf/code-nodes/cn-136.json +13 -0
  406. package/rcf/code-nodes/cn-137.json +13 -0
  407. package/rcf/code-nodes/cn-138.json +12 -0
  408. package/rcf/code-nodes/cn-139.json +12 -0
  409. package/rcf/code-nodes/cn-140.json +13 -0
  410. package/rcf/code-nodes/cn-141.json +13 -0
  411. package/rcf/code-nodes/cn-142.json +12 -0
  412. package/rcf/code-nodes/cn-143.json +13 -0
  413. package/rcf/code-nodes/cn-144.json +13 -0
  414. package/rcf/code-nodes/cn-145.json +12 -0
  415. package/rcf/code-nodes/cn-146.json +12 -0
  416. package/rcf/code-nodes/cn-147.json +13 -0
  417. package/rcf/code-nodes/cn-148.json +13 -0
  418. package/rcf/code-nodes/cn-149.json +12 -0
  419. package/rcf/code-nodes/cn-150.json +13 -0
  420. package/rcf/code-nodes/cn-151.json +13 -0
  421. package/rcf/code-nodes/cn-152.json +12 -0
  422. package/rcf/code-nodes/cn-153.json +12 -0
  423. package/rcf/code-nodes/cn-154.json +13 -0
  424. package/rcf/code-nodes/cn-155.json +14 -0
  425. package/rcf/code-nodes/cn-156.json +13 -0
  426. package/rcf/code-nodes/cn-157.json +13 -0
  427. package/rcf/code-nodes/cn-158.json +12 -0
  428. package/rcf/code-nodes/cn-159.json +13 -0
  429. package/rcf/code-nodes/cn-160.json +12 -0
  430. package/rcf/code-nodes/cn-161.json +12 -0
  431. package/rcf/code-nodes/cn-162.json +13 -0
  432. package/rcf/code-nodes/cn-163.json +12 -0
  433. package/rcf/code-nodes/cn-164.json +13 -0
  434. package/rcf/code-nodes/cn-165.json +12 -0
  435. package/rcf/code-nodes/cn-166.json +12 -0
  436. package/rcf/code-nodes/cn-167.json +12 -0
  437. package/rcf/code-nodes/cn-168.json +12 -0
  438. package/rcf/code-nodes/cn-169.json +12 -0
  439. package/rcf/code-nodes/cn-170.json +12 -0
  440. package/rcf/code-nodes/cn-171.json +12 -0
  441. package/rcf/code-nodes/cn-172.json +12 -0
  442. package/rcf/code-nodes/cn-173.json +12 -0
  443. package/rcf/code-nodes/cn-174.json +12 -0
  444. package/rcf/code-nodes/cn-175.json +13 -0
  445. package/rcf/code-nodes/cn-176.json +12 -0
  446. package/rcf/code-nodes/cn-177.json +12 -0
  447. package/rcf/code-nodes/cn-178.json +12 -0
  448. package/rcf/code-nodes/cn-179.json +12 -0
  449. package/rcf/code-nodes/cn-180.json +13 -0
  450. package/rcf/code-nodes/cn-181.json +12 -0
  451. package/rcf/code-nodes/cn-182.json +13 -0
  452. package/rcf/code-nodes/cn-183.json +12 -0
  453. package/rcf/code-nodes/cn-184.json +13 -0
  454. package/rcf/code-nodes/cn-185.json +12 -0
  455. package/rcf/code-nodes/cn-186.json +12 -0
  456. package/rcf/code-nodes/cn-200.json +14 -0
  457. package/rcf/code-nodes/cn-201.json +13 -0
  458. package/rcf/code-nodes/cn-202.json +14 -0
  459. package/rcf/code-nodes/cn-203.json +14 -0
  460. package/rcf/code-nodes/cn-204.json +13 -0
  461. package/rcf/code-nodes/cn-205.json +14 -0
  462. package/rcf/fbs/fbs-036.json +22 -0
  463. package/rcf/fbs/fbs-037.json +19 -0
  464. package/rcf/fbs/fbs-038.json +19 -0
  465. package/rcf/fbs/fbs-039.json +21 -0
  466. package/rcf/fbs/fbs-040.json +20 -0
  467. package/rcf/fbs/fbs-041.json +13 -0
  468. package/rcf/fbs/fbs-042.json +13 -0
  469. package/rcf/fbs/fbs-043.json +23 -0
  470. package/rcf/fbs/fbs-044.json +23 -0
  471. package/rcf/fbs/fbs-045.json +23 -0
  472. package/rcf/fbs/fbs-046.json +24 -0
  473. package/rcf/fbs/fbs-047.json +24 -0
  474. package/rcf/fbs/fbs-060.json +22 -0
  475. package/rcf/fbs/fbs-061.json +20 -0
  476. package/rcf/requirements/req-017.json +18 -0
  477. package/rcf/requirements/req-018.json +18 -0
  478. package/rcf/requirements/req-019.json +38 -0
  479. package/rcf/requirements/req-020.json +13 -0
  480. package/rcf/requirements/req-021.json +13 -0
  481. package/rcf/requirements/req-022.json +13 -0
  482. package/rcf/requirements/req-023.json +14 -0
  483. package/rcf/requirements/req-024.json +69 -0
  484. package/rcf/requirements/req-025.json +59 -0
  485. package/rcf/requirements/req-026.json +154 -0
  486. package/rcf/requirements/req-027.json +33 -0
  487. package/rcf/requirements/req-028.json +13 -0
  488. package/rcf/requirements/req-040.json +13 -0
  489. package/rcf/requirements/req-041.json +125 -0
  490. package/rcf/test-suites/ts-046.json +78 -0
  491. package/rcf/test-suites/ts-047.json +54 -0
  492. package/rcf/test-suites/ts-048.json +54 -0
  493. package/rcf/test-suites/ts-049.json +70 -0
  494. package/rcf/test-suites/ts-050.json +69 -0
  495. package/rcf/test-suites/ts-051.json +22 -0
  496. package/rcf/test-suites/ts-052.json +20 -0
  497. package/rcf/test-suites/ts-053.json +70 -0
  498. package/rcf/test-suites/ts-054.json +70 -0
  499. package/rcf/test-suites/ts-055.json +77 -0
  500. package/rcf/test-suites/ts-056.json +78 -0
  501. package/rcf/test-suites/ts-057.json +78 -0
  502. package/rcf/test-suites/ts-070.json +62 -0
  503. package/rcf/test-suites/ts-071.json +62 -0
  504. package/rcf/user-stories/us-1701.json +56 -0
  505. package/rcf/user-stories/us-1801.json +40 -0
  506. package/rcf/user-stories/us-1901.json +40 -0
  507. package/rcf/user-stories/us-2001.json +50 -0
  508. package/rcf/user-stories/us-2101.json +45 -0
  509. package/rcf/user-stories/us-2201.json +60 -0
  510. package/rcf/user-stories/us-2301.json +51 -0
  511. package/rcf/user-stories/us-2401.json +62 -0
  512. package/rcf/user-stories/us-2501.json +58 -0
  513. package/rcf/user-stories/us-2601.json +51 -0
  514. package/rcf/user-stories/us-2701.json +55 -0
  515. package/rcf/user-stories/us-2801.json +55 -0
  516. package/rcf/user-stories/us-4001.json +69 -0
  517. package/rcf/user-stories/us-4101.json +69 -0
  518. package/releases/releases.yaml +21 -1
  519. package/src/blueprint/apply.js +107 -1
  520. package/src/blueprint/capabilities.js +357 -0
  521. package/src/blueprint/loader.js +247 -0
  522. package/src/browser-verify/boot.js +180 -0
  523. package/src/browser-verify/index.js +13 -0
  524. package/src/browser-verify/manifest-writer.js +31 -6
  525. package/src/browser-verify/pack-browser.js +294 -0
  526. package/src/browser-verify/pack-loader.js +176 -0
  527. package/src/browser-verify/pack-runner.js +193 -0
  528. package/src/browser-verify/pack-schema.js +155 -0
  529. package/src/browser-verify/runner.js +24 -1
  530. package/src/cli/blueprint.js +99 -0
  531. package/src/cli/browser-verify.js +147 -7
  532. package/src/core/errors/index.js +7 -0
@@ -0,0 +1,176 @@
1
+ // Pack loader for blueprint-shipped probe packs
2
+ // (visual round T-0, US-1701 AC-1701-1 / 2 / 3). CN-107.
3
+ //
4
+ // Given a list of applied blueprints, discovers each blueprint's
5
+ // probe packs under `<blueprintAbsPath>/probe-packs/*.pack.{js,mjs}`,
6
+ // imports each module dynamically, validates against the pack schema
7
+ // (`pack-schema.js`), and cross-checks every check id against the AC
8
+ // ids the blueprint contributes via `blueprint.json:contributions[]`.
9
+ //
10
+ // The loader is pure with respect to the filesystem it reads: no
11
+ // writes, no side effects on the imported modules. It returns an
12
+ // aggregate result (`packs`, `warnings`, `errors`) so the CLI can
13
+ // emit one refusal diagnostic per fault rather than stop at the first.
14
+
15
+ import { readdir, readFile } from 'node:fs/promises';
16
+ import { existsSync } from 'node:fs';
17
+ import { join, resolve, isAbsolute } from 'node:path';
18
+ import { pathToFileURL } from 'node:url';
19
+
20
+ import { validatePackModule } from './pack-schema.js';
21
+
22
+ const PACK_FILENAME_RE = /\.pack\.(?:js|mjs)$/;
23
+
24
+ /**
25
+ * Load and validate probe packs under a set of applied blueprints.
26
+ *
27
+ * @param {object} args
28
+ * @param {Array<{ slug: string, absPath: string }>} args.appliedBlueprints
29
+ * List of blueprints on the applied shelf. `absPath` is the
30
+ * directory containing the blueprint's `blueprint.json`.
31
+ * @param {string} [args.projectRoot] reserved; unused today.
32
+ * @returns {Promise<{ packs: Array<LoadedPack>, warnings: Array<{ packAbsPath: string, message: string }>, errors: Array<{ packAbsPath: string, message: string }> }>}
33
+ */
34
+ export async function loadProbePacks({ appliedBlueprints, projectRoot: _projectRoot }) {
35
+ const packs = [];
36
+ const warnings = [];
37
+ const errors = [];
38
+
39
+ for (const bp of Array.isArray(appliedBlueprints) ? appliedBlueprints : []) {
40
+ if (!bp || typeof bp.slug !== 'string' || typeof bp.absPath !== 'string' || !isAbsolute(bp.absPath)) {
41
+ errors.push({
42
+ packAbsPath: '(no path)',
43
+ message: `pack-loader: blueprint entry must carry { slug: string, absPath: absolute path } (got ${JSON.stringify(bp)})`,
44
+ });
45
+ continue;
46
+ }
47
+ const packsDir = join(bp.absPath, 'probe-packs');
48
+ if (!existsSync(packsDir)) continue;
49
+
50
+ let contributedAcIds;
51
+ try {
52
+ contributedAcIds = await readContributedAcIds({ blueprintAbsPath: bp.absPath });
53
+ } catch (err) {
54
+ errors.push({ packAbsPath: bp.absPath, message: `pack-loader: cannot read blueprint contributions for '${bp.slug}': ${err.message}` });
55
+ continue;
56
+ }
57
+
58
+ let entries;
59
+ try {
60
+ entries = await readdir(packsDir, { withFileTypes: true });
61
+ } catch (err) {
62
+ errors.push({ packAbsPath: packsDir, message: `pack-loader: cannot list probe-packs dir for '${bp.slug}': ${err.message}` });
63
+ continue;
64
+ }
65
+
66
+ const packFiles = entries
67
+ .filter((e) => e.isFile() && PACK_FILENAME_RE.test(e.name))
68
+ .map((e) => join(packsDir, e.name))
69
+ .sort();
70
+
71
+ for (const packAbsPath of packFiles) {
72
+ let mod;
73
+ try {
74
+ mod = await import(pathToFileURL(packAbsPath).href);
75
+ } catch (err) {
76
+ errors.push({ packAbsPath, message: `pack-loader: import failed for ${packAbsPath}: ${err.message}` });
77
+ continue;
78
+ }
79
+ const validation = validatePackModule({ mod, blueprintSlug: bp.slug, packAbsPath });
80
+ if (!validation.ok) {
81
+ for (const e of validation.errors) errors.push({ packAbsPath, message: e.message });
82
+ continue;
83
+ }
84
+ const pack = validation.pack;
85
+
86
+ const badCheckIds = pack.checks
87
+ .map((c) => c.id)
88
+ .filter((id) => !contributedAcIds.has(id));
89
+ if (badCheckIds.length > 0) {
90
+ errors.push({
91
+ packAbsPath,
92
+ message: `pack-loader: pack '${pack.packName}' names checks [${badCheckIds.join(', ')}] that the blueprint '${bp.slug}' does not contribute; contributed AC ids on this blueprint: ${contributedAcIds.size === 0 ? '(none)' : [...contributedAcIds].sort().join(', ')}`,
93
+ });
94
+ continue;
95
+ }
96
+
97
+ packs.push({
98
+ packName: pack.packName,
99
+ version: pack.version,
100
+ blueprintSlug: bp.slug,
101
+ packAbsPath,
102
+ appliesTo: pack.appliesTo,
103
+ boot: pack.boot ?? null,
104
+ checks: pack.checks,
105
+ preChecks: Array.isArray(pack.preChecks) ? pack.preChecks : [],
106
+ });
107
+ }
108
+ }
109
+
110
+ return { packs, warnings, errors };
111
+ }
112
+
113
+ /**
114
+ * Read every AC id contributed by a blueprint. A blueprint contributes ACs
115
+ * inside its US contribution files (`contributions[].kind === 'us'`).
116
+ *
117
+ * @param {object} args
118
+ * @param {string} args.blueprintAbsPath
119
+ * @returns {Promise<Set<string>>}
120
+ */
121
+ export async function readContributedAcIds({ blueprintAbsPath }) {
122
+ const bpJsonPath = join(blueprintAbsPath, 'blueprint.json');
123
+ const bpRaw = await readFile(bpJsonPath, 'utf8');
124
+ let bpJson;
125
+ try { bpJson = JSON.parse(bpRaw); } catch (err) {
126
+ throw new Error(`invalid JSON in ${bpJsonPath}: ${err.message}`);
127
+ }
128
+ const contributions = Array.isArray(bpJson?.contributions) ? bpJson.contributions : [];
129
+ const acIds = new Set();
130
+ for (const c of contributions) {
131
+ if (c?.kind !== 'us' || typeof c.path !== 'string') continue;
132
+ // blueprint.json contribution paths are relative to the blueprint's
133
+ // `contributions/` subdirectory (see src/blueprint/loader.js). Older
134
+ // tests supplied paths that included `contributions/` at the root
135
+ // instead; probe for both shapes so shelf blueprints and hand-rolled
136
+ // fixtures both load without a per-caller convention.
137
+ const insideContributions = resolve(blueprintAbsPath, 'contributions', c.path);
138
+ const legacyRootRelative = resolve(blueprintAbsPath, c.path);
139
+ let usAbs = insideContributions;
140
+ let usRaw;
141
+ try {
142
+ usRaw = await readFile(insideContributions, 'utf8');
143
+ } catch (primaryErr) {
144
+ try {
145
+ usRaw = await readFile(legacyRootRelative, 'utf8');
146
+ usAbs = legacyRootRelative;
147
+ } catch {
148
+ throw new Error(`cannot read US contribution ${c.path}: ${primaryErr.message}`);
149
+ }
150
+ }
151
+ let usJson;
152
+ try {
153
+ usJson = JSON.parse(usRaw);
154
+ } catch (err) {
155
+ throw new Error(`cannot read US contribution ${c.path}: ${err.message}`);
156
+ }
157
+ void usAbs;
158
+ const inlineAcs = Array.isArray(usJson?.acceptanceCriteria) ? usJson.acceptanceCriteria : [];
159
+ for (const ac of inlineAcs) {
160
+ if (typeof ac?.id === 'string') acIds.add(ac.id);
161
+ }
162
+ }
163
+ return acIds;
164
+ }
165
+
166
+ /**
167
+ * @typedef {object} LoadedPack
168
+ * @property {string} packName
169
+ * @property {string} version
170
+ * @property {string} blueprintSlug
171
+ * @property {string} packAbsPath
172
+ * @property {(ctx: { fbs: object, uiBaseline: object|null, manifest: object|null }) => boolean} appliesTo
173
+ * @property {object|null} boot
174
+ * @property {Array<{ id: string, severity: 'block'|'warn'|'advisory', description: string, run: (ctx: object) => Promise<{ verdict: 'pass'|'warn'|'fail'|'skipped', detail?: string }>, dependsOn?: string|string[] }>} checks
175
+ * @property {Array<{ id: string, severity: 'block'|'warn'|'advisory', description: string, run: () => Promise<{ verdict: 'pass'|'warn'|'fail', detail?: string }> }>} preChecks
176
+ */
@@ -0,0 +1,193 @@
1
+ // Pack pass runner (visual round T-0, US-1701 AC-1701-4 / 6). CN-108.
2
+ //
3
+ // Invokes every applicable loaded pack against a FBS and folds the
4
+ // results into a `probePacks[]` array on the browserVerification
5
+ // record. Applicability is enforced by the pack's own `appliesTo`
6
+ // predicate: a false return records `applicable: false` and no
7
+ // check runs. `preChecks[]` (if any) run first; a failing pre-check
8
+ // causes browser checks that name it under `dependsOn` to record
9
+ // `skipped` with detail `skipped-by-pre-check:<preCheckId>`.
10
+ //
11
+ // The runner is browser-driver-agnostic: the caller injects a
12
+ // `browser` seam (the same shape a pack's `run` expects on its `browser`
13
+ // argument) plus `fetch`, `runtimeUrl` and the route/theme cursor.
14
+
15
+ /**
16
+ * Run applicable packs for one FBS.
17
+ *
18
+ * @param {object} args
19
+ * @param {Array<import('./pack-loader.js').LoadedPack>} args.packs
20
+ * @param {object} args.fbs
21
+ * @param {object|null} args.uiBaseline
22
+ * @param {object|null} args.manifest
23
+ * @param {object|null} args.browser injected browser (or null in unit tests)
24
+ * @param {(url: string, init?: object) => Promise<any>|null} args.fetch
25
+ * @param {string} args.runtimeUrl
26
+ * @param {Array<object>} args.routes FBS routes (nav model)
27
+ * @param {Array<'light'|'dark'>} args.themes
28
+ * @param {string} [args.packNameFilter] when set, only packs whose packName === filter are considered
29
+ * @param {(pack: import('./pack-loader.js').LoadedPack) => object} [args.buildContext] optional context override for unit tests
30
+ * @returns {Promise<{ probePacks: Array<object>, packHighestSeverityFail: 'block'|'warn'|null }>}
31
+ */
32
+ export async function runProbePacksForFbs({
33
+ packs,
34
+ fbs,
35
+ uiBaseline,
36
+ manifest,
37
+ projectRoot = null,
38
+ browser,
39
+ fetch,
40
+ runtimeUrl,
41
+ routes,
42
+ themes,
43
+ packNameFilter,
44
+ buildContext,
45
+ }) {
46
+ const probePacks = [];
47
+ let highest = null;
48
+ const chosen = Array.isArray(packs) ? packs : [];
49
+ const primaryRoute = Array.isArray(routes) && routes.length > 0 ? routes[0] : null;
50
+ const primaryTheme = Array.isArray(themes) && themes.length > 0 ? themes[0] : 'light';
51
+
52
+ for (const pack of chosen) {
53
+ if (typeof packNameFilter === 'string' && packNameFilter.length > 0 && pack.packName !== packNameFilter) {
54
+ continue;
55
+ }
56
+
57
+ let applicable;
58
+ let applicabilityDetail;
59
+ try {
60
+ applicable = Boolean(pack.appliesTo({ fbs, uiBaseline, manifest }));
61
+ } catch (err) {
62
+ applicable = false;
63
+ applicabilityDetail = `appliesTo threw: ${err.message}`;
64
+ }
65
+
66
+ if (!applicable) {
67
+ probePacks.push({
68
+ packName: pack.packName,
69
+ packVersion: pack.version,
70
+ blueprintSlug: pack.blueprintSlug,
71
+ applicable: false,
72
+ ...(applicabilityDetail ? { detail: applicabilityDetail } : { detail: `appliesTo returned false for ${fbs?.fbsId ?? '(no fbs)'}` }),
73
+ checks: [],
74
+ });
75
+ continue;
76
+ }
77
+
78
+ // Pre-checks first.
79
+ const preCheckRecords = [];
80
+ const failedPreCheckIds = new Set();
81
+ for (const pre of pack.preChecks) {
82
+ let verdict = 'pass';
83
+ let detail;
84
+ try {
85
+ const outcome = await pre.run({ fbs, uiBaseline, manifest, runtimeUrl, fetch, browser });
86
+ verdict = outcome?.verdict ?? 'pass';
87
+ detail = outcome?.detail;
88
+ } catch (err) {
89
+ verdict = 'fail';
90
+ detail = `pre-check threw: ${err.message}`;
91
+ }
92
+ preCheckRecords.push({
93
+ id: pre.id,
94
+ verdict,
95
+ severity: pre.severity,
96
+ ...(typeof detail === 'string' && detail.length > 0 ? { detail } : {}),
97
+ });
98
+ if (verdict === 'fail') failedPreCheckIds.add(pre.id);
99
+ if (verdict === 'fail' && pre.severity === 'block') highest = 'block';
100
+ else if (verdict === 'fail' && pre.severity === 'warn' && highest !== 'block') highest = 'warn';
101
+ }
102
+
103
+ const checkRecords = [];
104
+ for (const check of pack.checks) {
105
+ const deps = normaliseDependsOn(check.dependsOn);
106
+ const failingDep = deps.find((d) => failedPreCheckIds.has(d));
107
+ if (failingDep) {
108
+ checkRecords.push({
109
+ id: check.id,
110
+ verdict: 'skipped',
111
+ severity: check.severity,
112
+ detail: `skipped-by-pre-check:${failingDep}`,
113
+ });
114
+ continue;
115
+ }
116
+ // Per-check applicability (visual round T-5 spec section 5.5).
117
+ // A pack check may declare its own `appliesTo` predicate that
118
+ // reads the applied capability set (from projectRoot) so an
119
+ // absent capability records `applicable: false` and the
120
+ // aggregate verdict treats the check as neither pass nor fail.
121
+ // A check without a predicate always runs (backward compatible
122
+ // with T-0 through T-4 packs).
123
+ if (typeof check.appliesTo === 'function') {
124
+ let checkApplicable;
125
+ let checkAppliesDetail;
126
+ try {
127
+ checkApplicable = Boolean(await check.appliesTo({ fbs, uiBaseline, manifest, projectRoot }));
128
+ } catch (err) {
129
+ checkApplicable = false;
130
+ checkAppliesDetail = `appliesTo threw: ${err.message}`;
131
+ }
132
+ if (!checkApplicable) {
133
+ // Spec section 5.5 says the residual cure records
134
+ // applicable: false at the check level. rcf-schemas 0.6.1
135
+ // (browserVerificationProbePackCheck) closes the schema and
136
+ // still requires a verdict enum, so the manifest write path
137
+ // refuses a check that carries `applicable: false` alone.
138
+ // Until the schema minor promotes an `applicable` field at
139
+ // the check level (follow-up rcf-schemas bump), emit
140
+ // `verdict: 'skipped'` with a detail naming the applicability
141
+ // gate. Semantically the aggregate verdict still treats this
142
+ // as neither pass nor fail (skipped does not raise `highest`).
143
+ checkRecords.push({
144
+ id: check.id,
145
+ verdict: 'skipped',
146
+ severity: check.severity,
147
+ detail: checkAppliesDetail ?? 'check appliesTo returned false (required capability not applied)',
148
+ });
149
+ continue;
150
+ }
151
+ }
152
+ const context = typeof buildContext === 'function'
153
+ ? buildContext(pack)
154
+ : { browser, fetch, runtimeUrl, route: primaryRoute, theme: primaryTheme, projectRoot };
155
+ let verdict = 'pass';
156
+ let detail;
157
+ try {
158
+ const outcome = await check.run(context);
159
+ verdict = outcome?.verdict ?? 'pass';
160
+ detail = outcome?.detail;
161
+ } catch (err) {
162
+ verdict = 'fail';
163
+ detail = `check threw: ${err.message}`;
164
+ }
165
+ checkRecords.push({
166
+ id: check.id,
167
+ verdict,
168
+ severity: check.severity,
169
+ ...(typeof detail === 'string' && detail.length > 0 ? { detail } : {}),
170
+ });
171
+ if (verdict === 'fail' && check.severity === 'block') highest = 'block';
172
+ else if (verdict === 'fail' && check.severity === 'warn' && highest !== 'block') highest = 'warn';
173
+ }
174
+
175
+ const record = {
176
+ packName: pack.packName,
177
+ packVersion: pack.version,
178
+ blueprintSlug: pack.blueprintSlug,
179
+ applicable: true,
180
+ checks: checkRecords,
181
+ };
182
+ if (preCheckRecords.length > 0) record.preChecks = preCheckRecords;
183
+ probePacks.push(record);
184
+ }
185
+
186
+ return { probePacks, packHighestSeverityFail: highest };
187
+ }
188
+
189
+ function normaliseDependsOn(dependsOn) {
190
+ if (typeof dependsOn === 'string' && dependsOn.length > 0) return [dependsOn];
191
+ if (Array.isArray(dependsOn)) return dependsOn.filter((d) => typeof d === 'string' && d.length > 0);
192
+ return [];
193
+ }
@@ -0,0 +1,155 @@
1
+ // Pack schema validator for blueprint-shipped probe packs
2
+ // (visual round T-0, US-1701 AC-1701-1/2). CN-106.
3
+ //
4
+ // Validates a pack module's exported default object against the
5
+ // section 3.2 shape. Enforces the field-level rules the loader must
6
+ // refuse at load time (packName grammar and blueprint-slug prefix,
7
+ // version semver, blueprintSlug matches directory, appliesTo function
8
+ // referencing one of the three legal scoping seams, checks[] non-empty
9
+ // with an id / severity / description / async run per entry).
10
+ //
11
+ // Returns a plain-JS shape (not RcfError): the loader wraps refusals
12
+ // in its own diagnostic aggregate, so a single validation call reports
13
+ // every issue on one pack instead of stopping at the first.
14
+
15
+ const PACK_NAME_RE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
16
+ const SEMVER_RE = /^\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/;
17
+ const CHECK_ID_RE = /^AC-\d{3,}-\d+$/;
18
+ const SEVERITIES = new Set(['block', 'warn', 'advisory']);
19
+
20
+ const APPLIES_TO_TOKENS = [
21
+ { key: 'route', matcher: /\broute\b|\bnavModel\b|\bpath\b/ },
22
+ { key: 'tacIds', matcher: /\btacIds?\b/ },
23
+ { key: 'blueprintTag', matcher: /blueprint:/ },
24
+ ];
25
+
26
+ /**
27
+ * Validate a pack module's exported default object.
28
+ *
29
+ * @param {object} args
30
+ * @param {object} args.mod the imported module (its `.default` is the pack object).
31
+ * @param {string} args.blueprintSlug the owning blueprint slug (directory).
32
+ * @param {string} args.packAbsPath absolute path of the pack file, for error context.
33
+ * @returns {{ ok: true, pack: object } | { ok: false, errors: Array<{ field: string, message: string }> }}
34
+ */
35
+ export function validatePackModule({ mod, blueprintSlug, packAbsPath }) {
36
+ const errors = [];
37
+ const pack = mod?.default;
38
+ if (!pack || typeof pack !== 'object') {
39
+ return { ok: false, errors: [{ field: 'default', message: `pack ${packAbsPath}: missing default export (expected an object)` }] };
40
+ }
41
+
42
+ if (typeof pack.packName !== 'string' || pack.packName.length === 0) {
43
+ errors.push({ field: 'packName', message: `pack ${packAbsPath}: packName must be a non-empty string` });
44
+ } else if (!PACK_NAME_RE.test(pack.packName)) {
45
+ errors.push({ field: 'packName', message: `pack ${packAbsPath}: packName '${pack.packName}' must match ${PACK_NAME_RE}` });
46
+ } else if (pack.packName !== blueprintSlug && !pack.packName.startsWith(`${blueprintSlug}-`)) {
47
+ errors.push({ field: 'packName', message: `pack ${packAbsPath}: packName '${pack.packName}' must equal the blueprint slug '${blueprintSlug}' or start with '${blueprintSlug}-'` });
48
+ }
49
+
50
+ if (typeof pack.version !== 'string' || !SEMVER_RE.test(pack.version)) {
51
+ errors.push({ field: 'version', message: `pack ${packAbsPath}: version must be semver (got ${JSON.stringify(pack.version)})` });
52
+ }
53
+
54
+ if (typeof pack.blueprintSlug !== 'string' || pack.blueprintSlug.length === 0) {
55
+ errors.push({ field: 'blueprintSlug', message: `pack ${packAbsPath}: blueprintSlug must be a non-empty string` });
56
+ } else if (pack.blueprintSlug !== blueprintSlug) {
57
+ errors.push({ field: 'blueprintSlug', message: `pack ${packAbsPath}: blueprintSlug '${pack.blueprintSlug}' must match the enclosing directory '${blueprintSlug}'` });
58
+ }
59
+
60
+ if (typeof pack.appliesTo !== 'function') {
61
+ errors.push({ field: 'appliesTo', message: `pack ${packAbsPath}: appliesTo is required and must be a function ({ fbs, uiBaseline, manifest }) => boolean` });
62
+ } else {
63
+ const source = String(pack.appliesTo);
64
+ const matched = APPLIES_TO_TOKENS.filter((t) => t.matcher.test(source)).map((t) => t.key);
65
+ if (matched.length === 0) {
66
+ errors.push({
67
+ field: 'appliesTo',
68
+ message: `pack ${packAbsPath}: appliesTo must reference one of { route (or navModel/path), tacIds, blueprint:<slug> tag }; got source ${trimForError(source)}. The default '() => true' predicate is refused; scope the pack to the FBS surface it probes.`,
69
+ });
70
+ }
71
+ }
72
+
73
+ if (pack.boot !== undefined && pack.boot !== null && typeof pack.boot !== 'object') {
74
+ errors.push({ field: 'boot', message: `pack ${packAbsPath}: boot must be an object or null when present (fields bootCommand, waitForUrl, waitForSelector are optional)` });
75
+ }
76
+
77
+ if (!Array.isArray(pack.checks) || pack.checks.length === 0) {
78
+ errors.push({ field: 'checks', message: `pack ${packAbsPath}: checks must be a non-empty array` });
79
+ } else {
80
+ const seenIds = new Set();
81
+ pack.checks.forEach((check, index) => {
82
+ const at = `checks[${index}]`;
83
+ if (!check || typeof check !== 'object') {
84
+ errors.push({ field: at, message: `pack ${packAbsPath}: ${at} must be an object` });
85
+ return;
86
+ }
87
+ if (typeof check.id !== 'string' || !CHECK_ID_RE.test(check.id)) {
88
+ errors.push({ field: `${at}.id`, message: `pack ${packAbsPath}: ${at}.id must match ${CHECK_ID_RE} (got ${JSON.stringify(check.id)})` });
89
+ } else if (seenIds.has(check.id)) {
90
+ errors.push({ field: `${at}.id`, message: `pack ${packAbsPath}: ${at}.id '${check.id}' duplicates an earlier check on the same pack` });
91
+ } else {
92
+ seenIds.add(check.id);
93
+ }
94
+ if (!SEVERITIES.has(check.severity)) {
95
+ errors.push({ field: `${at}.severity`, message: `pack ${packAbsPath}: ${at}.severity must be one of ${[...SEVERITIES].join(' | ')} (got ${JSON.stringify(check.severity)})` });
96
+ }
97
+ if (typeof check.description !== 'string' || check.description.length === 0) {
98
+ errors.push({ field: `${at}.description`, message: `pack ${packAbsPath}: ${at}.description must be a non-empty string` });
99
+ }
100
+ if (typeof check.run !== 'function') {
101
+ errors.push({ field: `${at}.run`, message: `pack ${packAbsPath}: ${at}.run must be an async function` });
102
+ }
103
+ if (check.dependsOn !== undefined && !(typeof check.dependsOn === 'string' || (Array.isArray(check.dependsOn) && check.dependsOn.every((d) => typeof d === 'string')))) {
104
+ errors.push({ field: `${at}.dependsOn`, message: `pack ${packAbsPath}: ${at}.dependsOn must be a string or an array of strings (pre-check ids)` });
105
+ }
106
+ });
107
+ }
108
+
109
+ if (pack.preChecks !== undefined) {
110
+ if (!Array.isArray(pack.preChecks)) {
111
+ errors.push({ field: 'preChecks', message: `pack ${packAbsPath}: preChecks must be an array when present` });
112
+ } else {
113
+ const seenPre = new Set();
114
+ pack.preChecks.forEach((pre, index) => {
115
+ const at = `preChecks[${index}]`;
116
+ if (!pre || typeof pre !== 'object') {
117
+ errors.push({ field: at, message: `pack ${packAbsPath}: ${at} must be an object` });
118
+ return;
119
+ }
120
+ if (typeof pre.id !== 'string' || pre.id.length === 0) {
121
+ errors.push({ field: `${at}.id`, message: `pack ${packAbsPath}: ${at}.id must be a non-empty string` });
122
+ } else if (seenPre.has(pre.id)) {
123
+ errors.push({ field: `${at}.id`, message: `pack ${packAbsPath}: ${at}.id '${pre.id}' duplicates an earlier pre-check on the same pack` });
124
+ } else {
125
+ seenPre.add(pre.id);
126
+ }
127
+ if (!SEVERITIES.has(pre.severity)) {
128
+ errors.push({ field: `${at}.severity`, message: `pack ${packAbsPath}: ${at}.severity must be one of ${[...SEVERITIES].join(' | ')} (got ${JSON.stringify(pre.severity)})` });
129
+ }
130
+ if (typeof pre.description !== 'string' || pre.description.length === 0) {
131
+ errors.push({ field: `${at}.description`, message: `pack ${packAbsPath}: ${at}.description must be a non-empty string` });
132
+ }
133
+ if (typeof pre.run !== 'function') {
134
+ errors.push({ field: `${at}.run`, message: `pack ${packAbsPath}: ${at}.run must be an async function` });
135
+ }
136
+ });
137
+ }
138
+ }
139
+
140
+ if (errors.length > 0) return { ok: false, errors };
141
+ return { ok: true, pack };
142
+ }
143
+
144
+ function trimForError(s) {
145
+ const trimmed = String(s).replace(/\s+/g, ' ').trim();
146
+ return trimmed.length > 80 ? `${trimmed.slice(0, 77)}...` : trimmed;
147
+ }
148
+
149
+ export const PACK_SCHEMA_INTERNALS = Object.freeze({
150
+ PACK_NAME_RE,
151
+ SEMVER_RE,
152
+ CHECK_ID_RE,
153
+ SEVERITIES,
154
+ APPLIES_TO_TOKENS,
155
+ });
@@ -20,6 +20,7 @@
20
20
  import { runInvariantsForCapture, foldInvariantsForRecord, compareTopLevelStructure } from './invariants.js';
21
21
  import { runAuthSmokeChecks, shouldRunAuthSmokeChecks } from './auth-smoke.js';
22
22
  import { composeBrowserVerificationRecord } from './manifest-writer.js';
23
+ import { runProbePacksForFbs } from './pack-runner.js';
23
24
 
24
25
  /**
25
26
  * @typedef {object} BrowserCapture
@@ -63,7 +64,8 @@ export const stubBrowserDriver = Object.freeze({
63
64
  * @returns {Promise<object>} the composed browserVerification record
64
65
  */
65
66
  export async function runAgentScreenshotCritique({
66
- tree, fbs, runtimeUrl, runtimeProfile, browserDriver, fetch, artefactDir, critiqueNotes, now = new Date(),
67
+ tree, fbs, runtimeUrl, runtimeProfile, browserDriver, fetch, artefactDir, critiqueNotes,
68
+ probePacks = [], packBrowser = null, packNameFilter, projectRoot = null, now = new Date(),
67
69
  }) {
68
70
  const routes = fbs?.designStage?.navModel?.routes ?? [];
69
71
  const themes = readThemesFromBaseline(tree.manifest?.uiBaseline);
@@ -124,6 +126,26 @@ export async function runAgentScreenshotCritique({
124
126
  authSmokeChecks = await runAuthSmokeChecks({ fetch, runtimeUrl });
125
127
  }
126
128
 
129
+ // Probe-pack pass: runs after invariants and auth-smoke
130
+ // (visual-round-spec-2026-09-04 §3.4).
131
+ let packRecords = [];
132
+ if (Array.isArray(probePacks) && probePacks.length > 0) {
133
+ const result = await runProbePacksForFbs({
134
+ packs: probePacks,
135
+ fbs,
136
+ uiBaseline: tree.manifest?.uiBaseline ?? null,
137
+ manifest: tree.manifest ?? null,
138
+ projectRoot,
139
+ browser: packBrowser,
140
+ fetch,
141
+ runtimeUrl,
142
+ routes,
143
+ themes,
144
+ packNameFilter,
145
+ });
146
+ packRecords = result.probePacks;
147
+ }
148
+
127
149
  return composeBrowserVerificationRecord({
128
150
  manifest: tree.manifest,
129
151
  fbsId: fbs.fbsId,
@@ -133,6 +155,7 @@ export async function runAgentScreenshotCritique({
133
155
  routesChecked,
134
156
  invariantChecks,
135
157
  authSmokeChecks,
158
+ probePacks: packRecords,
136
159
  notes,
137
160
  now,
138
161
  });