rcf-lite 0.28.4 → 0.30.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 (882) hide show
  1. package/CHANGELOG.md +194 -1
  2. package/bin/rcf.js +4 -0
  3. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +1 -1
  4. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +1 -1
  5. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +1 -1
  6. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +1 -1
  7. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +1 -1
  8. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +1 -1
  9. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-007.json +1 -1
  10. package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-009.json +1 -1
  11. package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +4 -4
  12. package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +2 -2
  13. package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +2 -2
  14. package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +7 -7
  15. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +3 -15
  16. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +2 -10
  17. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25111.json +3 -6
  18. package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25112.json +4 -4
  19. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-001.json +1 -1
  20. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-002.json +1 -1
  21. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-003.json +1 -1
  22. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-004.json +1 -1
  23. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-005.json +1 -1
  24. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-006.json +1 -1
  25. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-007.json +1 -1
  26. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-008.json +1 -1
  27. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-009.json +1 -1
  28. package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-014.json +1 -1
  29. package/blueprints/application-admin-console/contributions/tacs/tac-2201-application-admin-console-shell.json +4 -4
  30. package/blueprints/application-admin-console/contributions/tacs/tac-2202-application-admin-console-capability-discovery.json +7 -7
  31. package/blueprints/application-admin-console/contributions/tacs/tac-2203-application-admin-console-permission-matrix.json +2 -2
  32. package/blueprints/application-admin-console/contributions/tacs/tac-2204-application-admin-console-audit-view.json +2 -2
  33. package/blueprints/application-admin-console/contributions/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +3 -2
  34. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21107.json +2 -2
  35. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21111.json +3 -11
  36. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21112.json +4 -4
  37. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21815.json +2 -2
  38. package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21816.json +2 -2
  39. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-001.json +1 -1
  40. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-002.json +1 -2
  41. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-004.json +1 -1
  42. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-008.json +1 -1
  43. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-016.json +1 -1
  44. package/blueprints/application-api-rest/contributions/tacs/tac-301-application-api-rest-request-pipeline.json +4 -4
  45. package/blueprints/application-api-rest/contributions/tacs/tac-302-application-api-rest-auth-middleware.json +4 -4
  46. package/blueprints/application-api-rest/contributions/tacs/tac-303-application-api-rest-contract-surface.json +4 -4
  47. package/blueprints/application-api-rest/contributions/tacs/tac-304-application-api-rest-resource-layer.json +4 -4
  48. package/blueprints/application-api-rest/contributions/tacs/tac-305-application-api-rest-observability.json +4 -4
  49. package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +4 -4
  50. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2102.json +1 -1
  51. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +1 -1
  52. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2104.json +4 -4
  53. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2105.json +2 -2
  54. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +1 -1
  55. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2110.json +1 -1
  56. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2111.json +1 -1
  57. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2118.json +1 -1
  58. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2119.json +2 -2
  59. package/blueprints/application-charts/contributions/tacs/tac-1901-application-charts-render-shell.json +4 -4
  60. package/blueprints/application-charts/contributions/tacs/tac-1902-application-charts-keyboard-traversal.json +4 -4
  61. package/blueprints/application-charts/contributions/user-stories/application-charts-us-18105.json +1 -1
  62. package/blueprints/application-dashboard/contributions/tacs/tac-2001-application-dashboard-tile-grid.json +4 -4
  63. package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +4 -4
  64. package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +2 -2
  65. package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +1 -1
  66. package/blueprints/application-datatable/contributions/tacs/tac-1801-application-datatable-shell.json +4 -4
  67. package/blueprints/application-datatable/contributions/tacs/tac-1802-application-datatable-query-adapter.json +4 -4
  68. package/blueprints/application-datatable/contributions/tacs/tac-1803-application-datatable-selection-model.json +2 -2
  69. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17101.json +1 -1
  70. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17102.json +1 -1
  71. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17103.json +1 -1
  72. package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17105.json +1 -1
  73. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +1 -1
  74. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +1 -1
  75. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +1 -1
  76. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +1 -1
  77. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +2 -2
  78. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-006.json +1 -1
  79. package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-007.json +2 -2
  80. package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +5 -5
  81. package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +2 -2
  82. package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +5 -5
  83. package/blueprints/application-error-handling/contributions/tacs/tac-1701-application-error-handling-boundary.json +6 -6
  84. package/blueprints/application-error-handling/contributions/tacs/tac-1702-application-error-handling-record-factory.json +4 -4
  85. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16101.json +1 -1
  86. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16107.json +4 -4
  87. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +1 -1
  88. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +1 -1
  89. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +1 -1
  90. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +1 -1
  91. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +1 -1
  92. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-006.json +2 -2
  93. package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-007.json +2 -2
  94. package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +7 -7
  95. package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +8 -8
  96. package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +11 -11
  97. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +1 -1
  98. package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +1 -1
  99. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +1 -1
  100. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +1 -1
  101. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +1 -1
  102. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +1 -1
  103. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +1 -1
  104. package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-006.json +2 -2
  105. package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +7 -7
  106. package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +4 -4
  107. package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +4 -4
  108. package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +1 -1
  109. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-001.json +1 -1
  110. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-002.json +1 -1
  111. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-003.json +1 -1
  112. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-004.json +1 -1
  113. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-005.json +2 -2
  114. package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-006.json +2 -2
  115. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +6 -6
  116. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +9 -9
  117. package/blueprints/application-notifications-in-app/contributions/tacs/tac-2103-application-notifications-in-app-preferences.json +4 -4
  118. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +1 -1
  119. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +1 -1
  120. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +2 -2
  121. package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +4 -4
  122. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +1 -1
  123. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +1 -1
  124. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +1 -1
  125. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +1 -1
  126. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-005.json +1 -1
  127. package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-006.json +1 -1
  128. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +4 -4
  129. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +2 -2
  130. package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +2 -2
  131. package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26108.json +2 -2
  132. package/blueprints/application-spa/contributions/requirements/application-spa-req-004.json +1 -2
  133. package/blueprints/application-spa/contributions/requirements/application-spa-req-007.json +1 -1
  134. package/blueprints/application-spa/contributions/requirements/application-spa-req-014.json +1 -1
  135. package/blueprints/application-spa/contributions/requirements/application-spa-req-015.json +1 -1
  136. package/blueprints/application-spa/contributions/requirements/application-spa-req-017.json +1 -1
  137. package/blueprints/application-spa/contributions/requirements/application-spa-req-018.json +1 -1
  138. package/blueprints/application-spa/contributions/tacs/tac-201-application-spa-app-shell.json +4 -4
  139. package/blueprints/application-spa/contributions/tacs/tac-202-application-spa-theme-system.json +4 -4
  140. package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +6 -6
  141. package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +6 -6
  142. package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +6 -6
  143. package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +8 -8
  144. package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +8 -8
  145. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1101.json +2 -2
  146. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1102.json +1 -1
  147. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1107.json +1 -1
  148. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1117.json +1 -1
  149. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1129.json +4 -4
  150. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1130.json +4 -4
  151. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +1 -1
  152. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1132.json +6 -6
  153. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1133.json +5 -5
  154. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1134.json +2 -2
  155. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-001.json +1 -1
  156. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-002.json +1 -1
  157. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-003.json +1 -1
  158. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +1 -1
  159. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-005.json +1 -1
  160. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-006.json +1 -1
  161. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-007.json +1 -1
  162. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-008.json +1 -1
  163. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-009.json +1 -1
  164. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-010.json +1 -1
  165. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-011.json +1 -1
  166. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-012.json +1 -1
  167. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-013.json +1 -1
  168. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-014.json +1 -1
  169. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-015.json +1 -1
  170. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-016.json +1 -1
  171. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-017.json +1 -1
  172. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-018.json +1 -1
  173. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-019.json +1 -1
  174. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-020.json +1 -1
  175. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-021.json +1 -1
  176. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-022.json +1 -1
  177. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-023.json +1 -1
  178. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-701-delivery-ci-workflows-gate-runner.json +6 -6
  179. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-702-delivery-ci-workflows-gate-report.json +4 -4
  180. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-703-delivery-ci-workflows-aggregate-report.json +4 -4
  181. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-704-delivery-ci-workflows-workflow-materialiser.json +6 -6
  182. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-705-delivery-ci-workflows-release-workflow.json +6 -6
  183. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-706-delivery-ci-workflows-scheduled-audit.json +4 -4
  184. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6101.json +1 -1
  185. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6102.json +1 -1
  186. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6103.json +1 -1
  187. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6104.json +1 -1
  188. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6106.json +1 -1
  189. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6107.json +1 -1
  190. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6109.json +1 -1
  191. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6110.json +1 -1
  192. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6111.json +1 -1
  193. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6113.json +1 -1
  194. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6115.json +1 -1
  195. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6116.json +1 -1
  196. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6117.json +1 -1
  197. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6118.json +1 -1
  198. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6119.json +1 -1
  199. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6120.json +1 -1
  200. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6122.json +1 -1
  201. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6123.json +1 -1
  202. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6124.json +1 -1
  203. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-001.json +1 -1
  204. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-002.json +1 -1
  205. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-003.json +1 -1
  206. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-004.json +1 -1
  207. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-005.json +1 -1
  208. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-006.json +1 -1
  209. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-007.json +1 -1
  210. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-008.json +1 -1
  211. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-009.json +1 -1
  212. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-010.json +1 -1
  213. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-011.json +1 -1
  214. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-012.json +1 -1
  215. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-013.json +1 -1
  216. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-014.json +1 -1
  217. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1301-deploy-cloudflare-workers-deploy-adapter.json +6 -6
  218. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1302-deploy-cloudflare-workers-wrangler-manifest.json +8 -8
  219. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1303-deploy-cloudflare-workers-preview-url-resolver.json +6 -6
  220. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1304-deploy-cloudflare-workers-promote-gate.json +8 -8
  221. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1305-deploy-cloudflare-workers-served-surface-verifier.json +8 -8
  222. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1306-deploy-cloudflare-workers-deploy-ci-workflows.json +8 -8
  223. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12101.json +1 -1
  224. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12102.json +2 -2
  225. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12105.json +1 -1
  226. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12109.json +1 -1
  227. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12113.json +2 -2
  228. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12114.json +1 -1
  229. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12115.json +1 -1
  230. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-001.json +1 -1
  231. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-002.json +1 -1
  232. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-003.json +1 -1
  233. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-004.json +1 -1
  234. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-005.json +1 -1
  235. package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-006.json +1 -1
  236. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json +3 -2
  237. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +3 -2
  238. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +3 -2
  239. package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +3 -2
  240. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37101.json +4 -4
  241. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37102.json +3 -3
  242. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37103.json +4 -4
  243. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37104.json +2 -2
  244. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37105.json +2 -2
  245. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37106.json +3 -3
  246. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37107.json +2 -2
  247. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37108.json +2 -2
  248. package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37109.json +2 -2
  249. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-001.json +1 -1
  250. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-002.json +1 -1
  251. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-003.json +1 -1
  252. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-004.json +1 -1
  253. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-005.json +1 -1
  254. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-006.json +1 -1
  255. package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-007.json +1 -1
  256. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +6 -4
  257. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +3 -2
  258. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +3 -2
  259. package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +3 -2
  260. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34101.json +1 -1
  261. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34102.json +5 -5
  262. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34103.json +1 -1
  263. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34104.json +3 -3
  264. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34105.json +1 -1
  265. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34106.json +1 -1
  266. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34107.json +5 -5
  267. package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34110.json +1 -1
  268. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-001.json +1 -1
  269. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-002.json +1 -1
  270. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-003.json +1 -1
  271. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-004.json +1 -1
  272. package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-005.json +1 -1
  273. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +6 -4
  274. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +3 -2
  275. package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +3 -2
  276. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36101.json +2 -2
  277. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36103.json +1 -1
  278. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36104.json +6 -6
  279. package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36106.json +2 -2
  280. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-001.json +1 -1
  281. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-002.json +1 -1
  282. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-003.json +1 -1
  283. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-004.json +1 -1
  284. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-005.json +1 -1
  285. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-006.json +1 -1
  286. package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-007.json +1 -1
  287. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +3 -2
  288. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +3 -2
  289. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +3 -2
  290. package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4004-edge-cloudflare-tunnel-zone-and-hostname-apply.json +3 -2
  291. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39101.json +3 -3
  292. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39102.json +2 -2
  293. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39103.json +4 -4
  294. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39104.json +2 -2
  295. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39105.json +2 -2
  296. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39106.json +5 -5
  297. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39107.json +2 -2
  298. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39108.json +3 -3
  299. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39109.json +4 -4
  300. package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39110.json +3 -3
  301. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-001.json +1 -1
  302. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-002.json +1 -1
  303. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-003.json +1 -1
  304. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-004.json +1 -1
  305. package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-005.json +1 -1
  306. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +3 -2
  307. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +9 -6
  308. package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +3 -2
  309. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35101.json +3 -3
  310. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35102.json +4 -4
  311. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35103.json +6 -6
  312. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35104.json +2 -2
  313. package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35105.json +1 -1
  314. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-001.json +1 -1
  315. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-002.json +1 -1
  316. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-003.json +1 -1
  317. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-004.json +1 -1
  318. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-005.json +1 -1
  319. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-006.json +1 -1
  320. package/blueprints/email-smtp-resend/contributions/tacs/tac-401-email-smtp-resend-send-adapter.json +8 -8
  321. package/blueprints/email-smtp-resend/contributions/tacs/tac-402-email-smtp-resend-webhook-verifier.json +10 -10
  322. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4101.json +1 -1
  323. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4102.json +1 -1
  324. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4103.json +1 -1
  325. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4105.json +1 -1
  326. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4106.json +2 -2
  327. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-001.json +1 -1
  328. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-002.json +1 -1
  329. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-003.json +1 -1
  330. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-004.json +1 -1
  331. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-005.json +1 -1
  332. package/blueprints/jobs-background/contributions/requirements/jobs-background-req-006.json +1 -1
  333. package/blueprints/jobs-background/contributions/tacs/tac-3101-jobs-background-job-definition.json +4 -4
  334. package/blueprints/jobs-background/contributions/tacs/tac-3102-jobs-background-scheduler.json +6 -6
  335. package/blueprints/jobs-background/contributions/tacs/tac-3103-jobs-background-run-log.json +6 -6
  336. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30101.json +1 -1
  337. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30102.json +3 -3
  338. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30103.json +1 -1
  339. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30104.json +4 -4
  340. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30105.json +1 -1
  341. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30106.json +1 -1
  342. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30107.json +1 -1
  343. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30108.json +1 -1
  344. package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30109.json +1 -1
  345. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-001.json +1 -1
  346. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-002.json +1 -1
  347. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-003.json +1 -1
  348. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-004.json +1 -1
  349. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-005.json +1 -1
  350. package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +1 -1
  351. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3001-messaging-queue-cloudflare-producer-facade.json +6 -6
  352. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3002-messaging-queue-cloudflare-consumer-registration.json +2 -2
  353. package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3003-messaging-queue-cloudflare-event-sink.json +2 -2
  354. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29101.json +1 -1
  355. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29102.json +1 -1
  356. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29103.json +1 -1
  357. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29104.json +2 -2
  358. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29105.json +1 -1
  359. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29106.json +2 -2
  360. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29107.json +1 -1
  361. package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29108.json +1 -1
  362. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +1 -1
  363. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +1 -1
  364. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +1 -1
  365. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +1 -1
  366. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +1 -1
  367. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +1 -1
  368. package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-101.json +1 -1
  369. package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +6 -6
  370. package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +2 -2
  371. package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +2 -2
  372. package/blueprints/object-storage-s3/contributions/tacs/tac-2904-object-storage-s3-hetzner-endpoint-helper.json +2 -2
  373. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +1 -1
  374. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +1 -1
  375. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +2 -2
  376. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +1 -1
  377. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +2 -2
  378. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +1 -1
  379. package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28110.json +1 -1
  380. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +1 -1
  381. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +1 -1
  382. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-003.json +1 -1
  383. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-004.json +1 -1
  384. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-005.json +1 -1
  385. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-006.json +1 -1
  386. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-007.json +1 -1
  387. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-008.json +1 -1
  388. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-009.json +1 -1
  389. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-010.json +1 -1
  390. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +4 -4
  391. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +12 -12
  392. package/blueprints/observability-essentials/contributions/tacs/tac-803-observability-essentials-status-page.json +6 -6
  393. package/blueprints/observability-essentials/contributions/tacs/tac-804-observability-essentials-notification-outcome.json +8 -8
  394. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +1 -1
  395. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7103.json +3 -3
  396. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7106.json +2 -2
  397. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7107.json +1 -1
  398. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-001.json +1 -1
  399. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-002.json +1 -1
  400. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-003.json +1 -1
  401. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-004.json +1 -1
  402. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-005.json +1 -1
  403. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-006.json +8 -2
  404. package/blueprints/observability-logging/contributions/tacs/tac-1601-observability-logging-logger-factory.json +6 -6
  405. package/blueprints/observability-logging/contributions/tacs/tac-1602-observability-logging-redaction-boundary.json +2 -2
  406. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15101.json +4 -4
  407. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15103.json +2 -2
  408. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15104.json +2 -2
  409. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15105.json +1 -1
  410. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15106.json +1 -1
  411. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15107.json +2 -2
  412. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15108.json +1 -1
  413. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15109.json +3 -3
  414. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-001.json +1 -1
  415. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-002.json +1 -1
  416. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-003.json +1 -1
  417. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-004.json +1 -1
  418. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-005.json +1 -1
  419. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-006.json +1 -1
  420. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-007.json +1 -1
  421. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-008.json +1 -1
  422. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1501-observability-probe-endpoints-profile-resolver.json +6 -6
  423. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1502-observability-probe-endpoints-handler-set.json +4 -4
  424. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1503-observability-probe-endpoints-listener-topology.json +6 -6
  425. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json +4 -4
  426. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14101.json +2 -2
  427. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +1 -1
  428. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14105.json +3 -3
  429. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-001.json +1 -1
  430. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-002.json +1 -1
  431. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-003.json +1 -1
  432. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-004.json +1 -1
  433. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-005.json +1 -1
  434. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-006.json +1 -1
  435. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-007.json +1 -1
  436. package/blueprints/persistence-data-d1/contributions/tacs/tac-1401-persistence-data-d1-facade.json +6 -6
  437. package/blueprints/persistence-data-d1/contributions/tacs/tac-1402-persistence-data-d1-migration-catalog.json +4 -4
  438. package/blueprints/persistence-data-d1/contributions/tacs/tac-1403-persistence-data-d1-deploy-gate.json +4 -4
  439. package/blueprints/persistence-data-d1/contributions/tacs/tac-1404-persistence-data-d1-recovery-runner.json +4 -4
  440. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13101.json +2 -2
  441. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13102.json +1 -1
  442. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13107.json +2 -2
  443. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +1 -1
  444. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +1 -1
  445. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +1 -1
  446. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +1 -1
  447. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +1 -1
  448. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +1 -1
  449. package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +1 -1
  450. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +6 -6
  451. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +4 -4
  452. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +2 -2
  453. package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +4 -4
  454. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +1 -1
  455. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +4 -4
  456. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +1 -1
  457. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +2 -2
  458. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +1 -1
  459. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +1 -1
  460. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +1 -1
  461. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +1 -1
  462. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +1 -1
  463. package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +1 -1
  464. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-001.json +1 -1
  465. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-002.json +1 -1
  466. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-003.json +1 -1
  467. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-004.json +1 -1
  468. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-005.json +1 -1
  469. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-006.json +1 -1
  470. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-007.json +1 -1
  471. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-008.json +1 -1
  472. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-009.json +1 -1
  473. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-010.json +1 -1
  474. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-011.json +1 -1
  475. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-601-persistence-data-sqlite-store.json +6 -6
  476. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-602-persistence-data-sqlite-migration-runner.json +2 -2
  477. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-603-persistence-data-sqlite-migration-catalog.json +4 -4
  478. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-604-persistence-data-sqlite-backup-runner.json +2 -2
  479. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5101.json +2 -2
  480. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5103.json +1 -1
  481. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5104.json +1 -1
  482. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5106.json +1 -1
  483. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5110.json +2 -2
  484. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5111.json +1 -1
  485. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-001.json +1 -1
  486. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-002.json +1 -1
  487. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-003.json +1 -1
  488. package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-004.json +1 -1
  489. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json +6 -1
  490. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json +9 -2
  491. package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json +6 -1
  492. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32101.json +6 -6
  493. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32102.json +5 -5
  494. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32103.json +3 -3
  495. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32104.json +4 -4
  496. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32105.json +4 -4
  497. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32106.json +4 -4
  498. package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32107.json +3 -3
  499. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-001.json +1 -1
  500. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-002.json +1 -1
  501. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-003.json +1 -1
  502. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-004.json +1 -1
  503. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-005.json +1 -1
  504. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-006.json +1 -1
  505. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-007.json +1 -1
  506. package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-008.json +1 -1
  507. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3401-platform-cloudflare-durable-objects-namespace-facade.json +6 -4
  508. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3402-platform-cloudflare-durable-objects-single-cell-shape.json +6 -4
  509. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3403-platform-cloudflare-durable-objects-alarm-handler.json +6 -4
  510. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3404-platform-cloudflare-durable-objects-websocket-hub.json +6 -4
  511. package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3405-platform-cloudflare-durable-objects-event-sink.json +3 -2
  512. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33101.json +5 -5
  513. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33102.json +4 -4
  514. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33103.json +5 -5
  515. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33104.json +5 -5
  516. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33105.json +5 -5
  517. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33106.json +4 -4
  518. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33107.json +3 -3
  519. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33108.json +5 -5
  520. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33109.json +3 -3
  521. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33110.json +4 -4
  522. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33111.json +3 -3
  523. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33112.json +3 -3
  524. package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33113.json +5 -5
  525. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-001.json +1 -1
  526. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-002.json +1 -1
  527. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-003.json +1 -1
  528. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-004.json +1 -1
  529. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-005.json +1 -1
  530. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-006.json +1 -1
  531. package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-007.json +1 -1
  532. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3201-platform-cloudflare-kv-facade.json +3 -2
  533. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3202-platform-cloudflare-kv-cache-aside.json +3 -2
  534. package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3203-platform-cloudflare-kv-event-sink.json +3 -2
  535. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31101.json +4 -4
  536. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31102.json +3 -3
  537. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31103.json +4 -4
  538. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31104.json +4 -4
  539. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31105.json +4 -4
  540. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31106.json +3 -3
  541. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31107.json +3 -3
  542. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31108.json +3 -3
  543. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31109.json +4 -4
  544. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31110.json +5 -5
  545. package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31111.json +5 -5
  546. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +1 -1
  547. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +1 -1
  548. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +1 -1
  549. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +1 -1
  550. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +1 -1
  551. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +1 -1
  552. package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-007.json +1 -1
  553. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +3 -2
  554. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +3 -2
  555. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +3 -2
  556. package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +3 -2
  557. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +5 -5
  558. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +4 -4
  559. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +4 -4
  560. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +4 -4
  561. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +3 -3
  562. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +3 -3
  563. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +3 -3
  564. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +3 -3
  565. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +3 -3
  566. package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38110.json +3 -3
  567. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-001.json +1 -1
  568. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-002.json +1 -1
  569. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-003.json +1 -1
  570. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-004.json +1 -1
  571. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-006.json +1 -1
  572. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-010.json +1 -1
  573. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-011.json +1 -1
  574. package/blueprints/security-auth-clerk/contributions/tacs/tac-1001-security-auth-clerk-middleware.json +6 -6
  575. package/blueprints/security-auth-clerk/contributions/tacs/tac-1002-security-auth-clerk-authorisation-adapter.json +8 -3
  576. package/blueprints/security-auth-clerk/contributions/tacs/tac-1003-security-auth-clerk-session-verifier.json +8 -8
  577. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9102.json +1 -1
  578. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9108.json +1 -1
  579. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9112.json +6 -6
  580. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9113.json +6 -6
  581. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-002.json +1 -1
  582. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-003.json +1 -1
  583. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-004.json +1 -1
  584. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-005.json +1 -1
  585. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-006.json +1 -1
  586. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-011.json +1 -1
  587. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-013.json +1 -1
  588. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-014.json +1 -1
  589. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-015.json +1 -1
  590. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-016.json +1 -1
  591. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-017.json +1 -1
  592. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-018.json +1 -1
  593. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-019.json +1 -1
  594. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1201-security-auth-keycloak-discovery-client.json +10 -10
  595. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1202-security-auth-keycloak-jwt-verifier.json +8 -8
  596. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1203-security-auth-keycloak-introspection-client.json +8 -8
  597. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1204-security-auth-keycloak-provider-router.json +6 -6
  598. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1205-security-auth-keycloak-role-adapter.json +4 -4
  599. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11102.json +1 -1
  600. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11103.json +2 -2
  601. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11104.json +1 -1
  602. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11106.json +3 -3
  603. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11111.json +2 -2
  604. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11114.json +1 -1
  605. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11115.json +5 -5
  606. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11116.json +7 -7
  607. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11117.json +7 -7
  608. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11118.json +7 -7
  609. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11119.json +7 -7
  610. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11120.json +6 -6
  611. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-002.json +1 -1
  612. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-003.json +1 -1
  613. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-004.json +1 -1
  614. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-005.json +1 -1
  615. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-008.json +1 -1
  616. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-009.json +1 -1
  617. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-010.json +1 -1
  618. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-011.json +1 -1
  619. package/blueprints/security-auth-magic-link/contributions/tacs/tac-501-security-auth-magic-link-manager.json +6 -6
  620. package/blueprints/security-auth-magic-link/contributions/tacs/tac-502-security-auth-magic-link-session-manager.json +6 -6
  621. package/blueprints/security-auth-magic-link/contributions/tacs/tac-503-security-auth-magic-link-login-routes.json +10 -10
  622. package/blueprints/security-auth-magic-link/contributions/tacs/tac-504-security-auth-magic-link-email-delivery-adapter.json +2 -2
  623. package/blueprints/security-auth-magic-link/contributions/tacs/tac-505-security-auth-magic-link-principal-registry.json +2 -2
  624. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3111.json +2 -2
  625. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-002.json +1 -1
  626. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-003.json +1 -1
  627. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-005.json +1 -1
  628. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-006.json +1 -1
  629. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-008.json +1 -1
  630. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-009.json +1 -1
  631. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-011.json +1 -1
  632. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-012.json +1 -1
  633. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-013.json +1 -1
  634. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1101-security-auth-oauth2-flow-controller.json +24 -14
  635. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1102-security-auth-oauth2-provider-adapter.json +4 -4
  636. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1103-security-auth-oauth2-session-bridge.json +10 -10
  637. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1104-security-auth-oauth2-provider-selector.json +8 -3
  638. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10111.json +1 -1
  639. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10112.json +1 -1
  640. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10114.json +5 -5
  641. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-001.json +1 -1
  642. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-002.json +1 -1
  643. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-003.json +1 -1
  644. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-004.json +1 -1
  645. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-005.json +1 -1
  646. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-006.json +1 -1
  647. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-007.json +1 -1
  648. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-008.json +1 -1
  649. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-009.json +1 -1
  650. package/blueprints/security-secrets-management/contributions/tacs/tac-901-security-secrets-management-manager-client.json +8 -8
  651. package/blueprints/security-secrets-management/contributions/tacs/tac-902-security-secrets-management-manifest.json +4 -4
  652. package/blueprints/security-secrets-management/contributions/tacs/tac-903-security-secrets-management-env-reflector.json +4 -4
  653. package/blueprints/security-secrets-management/contributions/tacs/tac-904-security-secrets-management-rotation-gate.json +8 -8
  654. package/blueprints/security-secrets-management/contributions/tacs/tac-905-security-secrets-management-agent-cli.json +4 -4
  655. package/fixtures/canary-manifest.json +9 -9
  656. package/guidance/define-draft-shapes.md +89 -0
  657. package/guidance/define-intake.md +97 -0
  658. package/guidance/define-intent.md +107 -0
  659. package/guidance/define-litmus.md +102 -0
  660. package/guidance/discover-prototype.md +67 -0
  661. package/guidance/discovery-prototypes.md +69 -0
  662. package/guidance/harness-template.md +34 -0
  663. package/guidance/managed/agent-instructions-block.hash +1 -1
  664. package/guidance/managed/agent-instructions-block.md +34 -0
  665. package/guidance/manifest.json +10 -2
  666. package/package.json +1 -1
  667. package/rcf/adrs/adr-4124-define-freeze-verb.json +30 -0
  668. package/rcf/adrs/adr-4126-persona-tagged-blockers-two-levels.json +40 -0
  669. package/rcf/adrs/adr-4127-readiness-tab-order-and-register.json +40 -0
  670. package/rcf/adrs/adr-4129-questions-harness-driven-loop.json +25 -0
  671. package/rcf/adrs/adr-4130-intake-harness-split-tool-scanned.json +20 -0
  672. package/rcf/adrs/adr-4131-gates-bite-ack-recorded-override.json +30 -0
  673. package/rcf/adrs/adr-4132-prototypes-in-discovery-as-evidence.json +20 -0
  674. package/rcf/adrs/adr-4133-dag-dependency-depth-layout.json +40 -0
  675. package/rcf/adrs/adr-4134-index-json-route.json +35 -0
  676. package/rcf/adrs/adr-4135-readiness-po-register-and-adapter.json +35 -0
  677. package/rcf/adrs/adr-4136-embedding-host-fixture.json +35 -0
  678. package/rcf/code-nodes/cn-725.json +18 -2
  679. package/rcf/code-nodes/cn-726.json +10 -2
  680. package/rcf/code-nodes/cn-727.json +13 -4
  681. package/rcf/code-nodes/cn-728.json +18 -2
  682. package/rcf/code-nodes/cn-729.json +10 -2
  683. package/rcf/code-nodes/cn-730.json +13 -3
  684. package/rcf/code-nodes/cn-731.json +20 -0
  685. package/rcf/code-nodes/cn-732.json +14 -0
  686. package/rcf/code-nodes/cn-733.json +14 -0
  687. package/rcf/code-nodes/cn-734.json +14 -0
  688. package/rcf/code-nodes/cn-735.json +20 -0
  689. package/rcf/code-nodes/cn-736.json +14 -0
  690. package/rcf/code-nodes/cn-737.json +14 -0
  691. package/rcf/code-nodes/cn-738.json +14 -0
  692. package/rcf/code-nodes/cn-739.json +18 -0
  693. package/rcf/code-nodes/cn-740.json +19 -0
  694. package/rcf/code-nodes/cn-741.json +16 -0
  695. package/rcf/code-nodes/cn-742.json +16 -0
  696. package/rcf/code-nodes/cn-743.json +15 -0
  697. package/rcf/code-nodes/cn-744.json +22 -0
  698. package/rcf/code-nodes/cn-745.json +16 -0
  699. package/rcf/code-nodes/cn-746.json +14 -0
  700. package/rcf/code-nodes/cn-747.json +18 -0
  701. package/rcf/code-nodes/cn-748.json +16 -0
  702. package/rcf/code-nodes/cn-749.json +16 -0
  703. package/rcf/code-nodes/cn-750.json +15 -0
  704. package/rcf/code-nodes/cn-751.json +18 -0
  705. package/rcf/code-nodes/cn-752.json +14 -0
  706. package/rcf/code-nodes/cn-753.json +19 -0
  707. package/rcf/code-nodes/cn-754.json +17 -0
  708. package/rcf/code-nodes/cn-755.json +14 -0
  709. package/rcf/code-nodes/cn-756.json +15 -0
  710. package/rcf/code-nodes/cn-757.json +21 -0
  711. package/rcf/code-nodes/cn-758.json +16 -0
  712. package/rcf/code-nodes/cn-759.json +21 -0
  713. package/rcf/code-nodes/cn-760.json +19 -0
  714. package/rcf/code-nodes/cn-761.json +16 -0
  715. package/rcf/code-nodes/cn-762.json +18 -0
  716. package/rcf/code-nodes/cn-763.json +18 -0
  717. package/rcf/code-nodes/cn-764.json +15 -0
  718. package/rcf/code-nodes/cn-765.json +23 -0
  719. package/rcf/code-nodes/cn-766.json +17 -0
  720. package/rcf/code-nodes/cn-767.json +17 -0
  721. package/rcf/code-nodes/cn-768.json +19 -0
  722. package/rcf/code-nodes/cn-769.json +17 -0
  723. package/rcf/code-nodes/cn-770.json +18 -0
  724. package/rcf/fbs/fbs-196.json +13 -5
  725. package/rcf/fbs/fbs-198.json +42 -0
  726. package/rcf/fbs/fbs-199.json +59 -0
  727. package/rcf/fbs/fbs-200.json +46 -0
  728. package/rcf/fbs/fbs-201.json +49 -0
  729. package/rcf/fbs/fbs-202.json +170 -0
  730. package/rcf/fbs/fbs-203.json +100 -0
  731. package/rcf/requirements/req-002.json +2 -2
  732. package/rcf/requirements/req-173.json +2 -2
  733. package/rcf/requirements/req-174.json +10 -4
  734. package/rcf/requirements/req-175.json +10 -4
  735. package/rcf/requirements/req-176.json +25 -0
  736. package/rcf/requirements/req-177.json +31 -0
  737. package/rcf/requirements/req-178.json +31 -0
  738. package/rcf/requirements/req-179.json +31 -0
  739. package/rcf/requirements/req-180.json +31 -0
  740. package/rcf/requirements/req-181.json +31 -0
  741. package/rcf/requirements/req-182.json +25 -0
  742. package/rcf/requirements/req-186.json +25 -0
  743. package/rcf/requirements/req-187.json +31 -0
  744. package/rcf/requirements/req-188.json +25 -0
  745. package/rcf/tacs/tac-001.json +7 -7
  746. package/rcf/tacs/tac-002.json +23 -23
  747. package/rcf/tacs/tac-003.json +5 -5
  748. package/rcf/tacs/tac-004.json +9 -9
  749. package/rcf/tacs/tac-005.json +7 -7
  750. package/rcf/tacs/tac-006.json +21 -21
  751. package/rcf/tacs/tac-007.json +7 -7
  752. package/rcf/tacs/tac-008.json +7 -7
  753. package/rcf/tacs/tac-4101-feedback-cli.json +5 -5
  754. package/rcf/tacs/tac-4102-feedback-store.json +9 -9
  755. package/rcf/tacs/tac-4103-feedback-redact.json +5 -5
  756. package/rcf/tacs/tac-4104-feedback-fingerprint.json +3 -3
  757. package/rcf/tacs/tac-4105-feedback-render.json +7 -7
  758. package/rcf/tacs/tac-4106-feedback-destination.json +5 -5
  759. package/rcf/tacs/tac-4107-feedback-gh.json +7 -7
  760. package/rcf/tacs/tac-4108-feedback-hook.json +7 -7
  761. package/rcf/tacs/tac-4121-define-ledgers.json +16 -3
  762. package/rcf/tacs/tac-4122-define-gates.json +69 -5
  763. package/rcf/tacs/tac-4123-define-readiness.json +66 -4
  764. package/rcf/tacs/tac-4124-define-freeze.json +28 -0
  765. package/rcf/tacs/tac-4125-build-bundle-refuse-override-skip.json +43 -0
  766. package/rcf/tacs/tac-4126-define-validate-findings.json +32 -0
  767. package/rcf/tacs/tac-4127-readiness-view.json +49 -0
  768. package/rcf/tacs/tac-4128-define-guidance.json +59 -0
  769. package/rcf/tacs/tac-4129-define-questions.json +45 -0
  770. package/rcf/tacs/tac-4130-define-intake-brief.json +35 -0
  771. package/rcf/tacs/tac-4131-build-dag-view.json +39 -0
  772. package/rcf/tacs/tac-4132-id-lookup.json +42 -0
  773. package/rcf/tacs/tac-4133-readiness-po-layer.json +37 -0
  774. package/rcf/tacs/tac-4134-wespa-host-fixture.json +54 -0
  775. package/rcf/test-suites/ts-016.json +3 -3
  776. package/rcf/test-suites/ts-215.json +148 -4
  777. package/rcf/test-suites/ts-216.json +19 -3
  778. package/rcf/test-suites/ts-218.json +78 -0
  779. package/rcf/test-suites/ts-219.json +70 -0
  780. package/rcf/test-suites/ts-220.json +78 -0
  781. package/rcf/test-suites/ts-221.json +78 -0
  782. package/rcf/test-suites/ts-222.json +100 -0
  783. package/rcf/test-suites/ts-223.json +94 -0
  784. package/rcf/test-suites/ts-224.json +70 -0
  785. package/rcf/test-suites/ts-225.json +78 -0
  786. package/rcf/test-suites/ts-226.json +158 -0
  787. package/rcf/test-suites/ts-227.json +38 -0
  788. package/rcf/test-suites/ts-228.json +86 -0
  789. package/rcf/test-suites/ts-229.json +83 -0
  790. package/rcf/test-suites/ts-230.json +76 -0
  791. package/rcf/test-suites/ts-231.json +104 -0
  792. package/rcf/test-suites/ts-232.json +109 -0
  793. package/rcf/test-suites/ts-233.json +61 -0
  794. package/rcf/test-suites/ts-234.json +53 -0
  795. package/rcf/test-suites/ts-235.json +53 -0
  796. package/rcf/user-stories/us-17302.json +50 -0
  797. package/rcf/user-stories/us-17401.json +14 -2
  798. package/rcf/user-stories/us-17402.json +55 -0
  799. package/rcf/user-stories/us-17403.json +60 -0
  800. package/rcf/user-stories/us-17404.json +51 -0
  801. package/rcf/user-stories/us-17405.json +61 -0
  802. package/rcf/user-stories/us-17406.json +51 -0
  803. package/rcf/user-stories/us-17502.json +60 -0
  804. package/rcf/user-stories/us-17503.json +65 -0
  805. package/rcf/user-stories/us-17504.json +46 -0
  806. package/rcf/user-stories/us-17601.json +58 -0
  807. package/rcf/user-stories/us-17702.json +51 -0
  808. package/rcf/user-stories/us-17802.json +40 -0
  809. package/rcf/user-stories/us-17902.json +46 -0
  810. package/rcf/user-stories/us-18001.json +55 -0
  811. package/rcf/user-stories/us-18002.json +35 -0
  812. package/rcf/user-stories/us-18101.json +35 -0
  813. package/rcf/user-stories/us-18202.json +40 -0
  814. package/rcf/user-stories/us-18601.json +55 -0
  815. package/rcf/user-stories/us-18602.json +50 -0
  816. package/rcf/user-stories/us-18603.json +45 -0
  817. package/rcf/user-stories/us-18701.json +50 -0
  818. package/rcf/user-stories/us-18702.json +50 -0
  819. package/rcf/user-stories/us-18801.json +45 -0
  820. package/rcf/user-stories/us-204.json +59 -0
  821. package/rcf/user-stories/us-205.json +64 -0
  822. package/rcf/user-stories/us-206.json +54 -0
  823. package/releases/releases.yaml +21 -1
  824. package/src/blueprint/consistency-lint.js +72 -3
  825. package/src/cli/build.js +206 -3
  826. package/src/cli/freeze.js +780 -0
  827. package/src/cli/help.js +12 -0
  828. package/src/cli/ledger.js +228 -12
  829. package/src/cli/questions.js +288 -0
  830. package/src/cli/readiness.js +393 -74
  831. package/src/cli/validate.js +8 -0
  832. package/src/cli/view.js +29 -0
  833. package/src/define/concern-catalogue.js +130 -0
  834. package/src/define/freeze-record.js +104 -15
  835. package/src/define/ledgers.js +210 -11
  836. package/src/define/probe-runner.js +55 -0
  837. package/src/define/validate-findings.js +256 -0
  838. package/src/intake/index.js +1 -1
  839. package/src/intake/orchestrator.js +117 -0
  840. package/src/mcp/tools.js +354 -0
  841. package/src/query/delta.js +6 -0
  842. package/src/query/gates.js +1258 -48
  843. package/src/query/index.js +22 -3
  844. package/src/query/questions.js +438 -0
  845. package/src/query/readiness.js +427 -9
  846. package/src/query/refuse-on-admissibility.js +137 -4
  847. package/src/ruleset/ruleset.json +35 -0
  848. package/src/server/index.js +24 -2
  849. package/src/server/routes.js +68 -1
  850. package/src/setup/identity-seed.js +17 -0
  851. package/src/view/build-dag.js +563 -0
  852. package/src/view/components/badge.js +41 -0
  853. package/src/view/components/diff.js +72 -0
  854. package/src/view/components/doc-row.js +62 -0
  855. package/src/view/components/empty-state.js +35 -0
  856. package/src/view/components/entity-selector.js +137 -0
  857. package/src/view/components/filter-bar.js +97 -0
  858. package/src/view/components/findings-list.js +49 -0
  859. package/src/view/components/index.js +12 -0
  860. package/src/view/components/pill.js +46 -0
  861. package/src/view/components/sub-tab-strip.js +43 -0
  862. package/src/view/components/toast.js +25 -0
  863. package/src/view/components-fixture.js +265 -0
  864. package/src/view/doc-renderers/architecture.js +304 -0
  865. package/src/view/doc-renderers/build.js +160 -0
  866. package/src/view/doc-renderers/index.js +2 -0
  867. package/src/view/doc-renderers/prd.js +35 -6
  868. package/src/view/html-page.js +700 -602
  869. package/src/view/index.js +96 -3
  870. package/src/view/live-client.js +39 -6
  871. package/src/view/needs-work.js +79 -0
  872. package/src/view/page-init.js +2193 -0
  873. package/src/view/readiness/phrasebook.js +115 -0
  874. package/src/view/readiness/po-layer.js +288 -0
  875. package/src/view/readiness/question-adapter.js +329 -0
  876. package/src/view/readiness/stage-legend.js +71 -0
  877. package/src/view/readiness.js +505 -0
  878. package/src/view/style.css +2017 -382
  879. package/src/view/test-host/embed-client.js +121 -0
  880. package/src/view/test-host/fixture.js +183 -0
  881. package/src/view/test-host/lints.js +220 -0
  882. package/src/view/view-index.js +323 -0
@@ -0,0 +1,2193 @@
1
+ // Page init script. Classic (non-module) browser script extracted from
2
+ // the former inline <script> block in html-page.js: wespa (Dex,
3
+ // 2026-10-02) pins inline scripts by CSP hash, so the viewer now
4
+ // serves this logic as a cacheable asset at ./page-init.js and the
5
+ // shell page carries no inline script at all. PR 1 (viewer UI
6
+ // refresh) also folds in the shell contract:
7
+ // - Theme boot: read ?theme=light|dark|auto, stamp data-theme on
8
+ // <html>. Live changes arrive via postMessage from the embedding
9
+ // host as { type: "rcf-view-theme", theme: "light"|"dark" }; we
10
+ // check event.origin against our own and ignore anything else.
11
+ // The viewport media query handles theme=auto natively; explicit
12
+ // light/dark wins over the media query.
13
+ // - Embed boot: ?embed=1 stamps data-embed on <html>; the stylesheet
14
+ // hides the brand block and footer in that state and keeps the
15
+ // tab nav sticky.
16
+ // - Router: hash scheme #tab=&sub=&entity=&... with bare #REQ-002
17
+ // still working; every hash write preserves the host query string
18
+ // (?embed=1, ?theme=..., ?blueprint=..., ?ticket=...) so embed and
19
+ // theme survive every in-viewer navigation.
20
+ //
21
+ // Idempotent: live-client re-invokes rcfPage.init() after every SSE
22
+ // innerHTML swap of #rcf-live-content. All wiring guards with
23
+ // __rcfTabWired-style sentinels.
24
+
25
+ (function () {
26
+ var TABS = ['readiness', 'overview', 'requirements', 'architecture', 'build', 'product-map'];
27
+ var PM_GROUPS = ['shape', 'component', 'trace', 'capability', 'blueprint'];
28
+ var PM_STATUSES = ['all', 'draft', 'review', 'needsRevision', 'approved', 'superseded'];
29
+ // Partial-render cache: grouping -> HTML string. First fetch fills it,
30
+ // subsequent switches use the cache.
31
+ var pmPartialCache = {};
32
+ function pmCacheKey(group) { return group; }
33
+
34
+ // ---- shell: theme + embed ---------------------------------------------
35
+
36
+ function parseQuery(search) {
37
+ var out = {};
38
+ if (typeof search !== 'string' || search.length === 0) return out;
39
+ var raw = search.charAt(0) === '?' ? search.slice(1) : search;
40
+ if (raw.length === 0) return out;
41
+ var pairs = raw.split('&');
42
+ for (var i = 0; i < pairs.length; i += 1) {
43
+ var eq = pairs[i].indexOf('=');
44
+ var k = eq === -1 ? pairs[i] : pairs[i].slice(0, eq);
45
+ var v = eq === -1 ? '' : pairs[i].slice(eq + 1);
46
+ if (!k) continue;
47
+ try { out[decodeURIComponent(k)] = decodeURIComponent(v.replace(/\+/g, ' ')); }
48
+ catch (e) { out[k] = v; }
49
+ }
50
+ return out;
51
+ }
52
+
53
+ function applyTheme(t) {
54
+ var root = document.documentElement;
55
+ if (t === 'light' || t === 'dark') root.setAttribute('data-theme', t);
56
+ else root.removeAttribute('data-theme');
57
+ }
58
+
59
+ function applyEmbed(flag) {
60
+ var root = document.documentElement;
61
+ if (flag) root.setAttribute('data-embed', '1');
62
+ else root.removeAttribute('data-embed');
63
+ }
64
+
65
+ function initShellFromQuery() {
66
+ var q = parseQuery(window.location.search);
67
+ // theme: explicit light|dark wins, auto falls through to the
68
+ // :root:not([data-theme]) + @media prefers-color-scheme block in
69
+ // style.css. Absent stays light (the base :root tokens).
70
+ var theme = q.theme;
71
+ if (theme === 'light' || theme === 'dark' || theme === 'auto') applyTheme(theme === 'auto' ? null : theme);
72
+ // embed: any value other than exactly "1" is ignored.
73
+ applyEmbed(q.embed === '1');
74
+ }
75
+
76
+ var messageListenerWired = false;
77
+ function wireThemeMessages() {
78
+ if (messageListenerWired) return;
79
+ messageListenerWired = true;
80
+ window.addEventListener('message', function (ev) {
81
+ // Same-origin only: wespa reverse-proxies the viewer under its
82
+ // own origin, so a legitimate theme ping comes from the viewer's
83
+ // own origin. Anything else is a cross-origin posting we ignore.
84
+ if (!ev || ev.origin !== window.location.origin) return;
85
+ var data = ev.data || {};
86
+ if (data.type !== 'rcf-view-theme') return;
87
+ if (data.theme === 'light' || data.theme === 'dark') applyTheme(data.theme);
88
+ });
89
+ }
90
+
91
+ // ---- hash parsing + preservation --------------------------------------
92
+
93
+ function flashLookupTarget(el) {
94
+ if (!el || !el.classList) return;
95
+ try {
96
+ el.classList.remove('is-rcf-lookup-flash');
97
+ // Force reflow so the animation restarts on repeat picks.
98
+ void el.offsetWidth;
99
+ el.classList.add('is-rcf-lookup-flash');
100
+ setTimeout(function () { try { el.classList.remove('is-rcf-lookup-flash'); } catch (e) {} }, 1400);
101
+ } catch (e) {}
102
+ }
103
+
104
+ function parseHashParams(raw) {
105
+ var out = {};
106
+ if (!raw) return out;
107
+ var parts = raw.split('&');
108
+ for (var i = 0; i < parts.length; i += 1) {
109
+ var eq = parts[i].indexOf('=');
110
+ if (eq === -1) continue;
111
+ var k = parts[i].slice(0, eq);
112
+ var v = parts[i].slice(eq + 1);
113
+ if (k) out[k] = v;
114
+ }
115
+ return out;
116
+ }
117
+
118
+ // Build a URL that keeps the host query untouched (?embed=, ?theme=,
119
+ // ?blueprint=, ?ticket=, ...) and only swaps the hash. Required by
120
+ // Dex's embed contract: embed/theme survive every in-viewer navigation.
121
+ function urlWithHash(hash) {
122
+ var base = window.location.pathname + window.location.search;
123
+ if (!hash) return base;
124
+ return base + (hash.charAt(0) === '#' ? hash : '#' + hash);
125
+ }
126
+
127
+ function writeHash(hash, replace) {
128
+ if (!window.history) return;
129
+ var fn = replace === false ? 'pushState' : 'replaceState';
130
+ if (typeof window.history[fn] !== 'function') return;
131
+ var next = urlWithHash(hash);
132
+ if (next === window.location.pathname + window.location.search + window.location.hash) return;
133
+ window.history[fn](null, '', next);
134
+ }
135
+
136
+ // ---- mermaid lifecycle ------------------------------------------------
137
+
138
+ function initMermaid() {
139
+ if (typeof window.mermaid !== 'undefined') {
140
+ window.mermaid.initialize({ startOnLoad: false, securityLevel: 'loose' });
141
+ }
142
+ }
143
+
144
+ function runMermaidIn(container) {
145
+ if (!container || typeof window.mermaid === 'undefined') return;
146
+ var pending = container.querySelectorAll('.mermaid:not([data-processed="true"])');
147
+ if (pending.length === 0) return;
148
+ try {
149
+ window.mermaid.run({ nodes: Array.prototype.slice.call(pending) });
150
+ } catch (e) { /* swallow */ }
151
+ }
152
+
153
+ // ---- tabs -------------------------------------------------------------
154
+
155
+ function tabButtons() {
156
+ return Array.prototype.slice.call(document.querySelectorAll('nav.tabs [role="tab"]'));
157
+ }
158
+
159
+ function panelFor(name) {
160
+ return document.getElementById('tab-' + name);
161
+ }
162
+
163
+ function activateTab(name) {
164
+ if (TABS.indexOf(name) === -1) return false;
165
+ tabButtons().forEach(function (btn) {
166
+ var isTarget = btn.getAttribute('data-tab') === name;
167
+ btn.setAttribute('aria-selected', isTarget ? 'true' : 'false');
168
+ });
169
+ TABS.forEach(function (t) {
170
+ var p = panelFor(t);
171
+ if (!p) return;
172
+ if (t === name) {
173
+ p.removeAttribute('hidden');
174
+ runMermaidIn(p);
175
+ } else {
176
+ p.setAttribute('hidden', '');
177
+ }
178
+ });
179
+ return true;
180
+ }
181
+
182
+ function tabForNode(node) {
183
+ var cur = node;
184
+ while (cur && cur !== document.body) {
185
+ if (cur.getAttribute && cur.getAttribute('role') === 'tabpanel') {
186
+ var id = cur.id || '';
187
+ if (id.indexOf('tab-') === 0) return id.slice(4);
188
+ }
189
+ cur = cur.parentNode;
190
+ }
191
+ return null;
192
+ }
193
+
194
+ function openAncestorDetails(node) {
195
+ var cur = node.parentNode;
196
+ while (cur && cur !== document.body) {
197
+ if (cur.tagName && cur.tagName.toLowerCase() === 'details') {
198
+ cur.open = true;
199
+ }
200
+ cur = cur.parentNode;
201
+ }
202
+ }
203
+
204
+ function findByDocId(id) {
205
+ if (!id) return null;
206
+ var byId = document.getElementById(id);
207
+ if (byId) return byId;
208
+ return document.querySelector('[data-doc-id="' + id.replace(/"/g, '\\\\"') + '"]');
209
+ }
210
+
211
+ // ---- product map ------------------------------------------------------
212
+
213
+ function pmGroupPanel(name) {
214
+ return document.getElementById('pm-group-' + name);
215
+ }
216
+
217
+ function hydrateLazyGroup(name, cb) {
218
+ var panel = pmGroupPanel(name);
219
+ if (!panel) { if (cb) cb(false); return; }
220
+ if (panel.getAttribute('data-pm-lazy') !== 'true' && !pmPartialCache[pmCacheKey(name)]) {
221
+ if (cb) cb(true);
222
+ return;
223
+ }
224
+ if (window.__rcfPmDirty) {
225
+ pmPartialCache = {};
226
+ window.__rcfPmDirty = false;
227
+ }
228
+ var cached = pmPartialCache[pmCacheKey(name)];
229
+ var heading = panel.querySelector('.pm-group-heading');
230
+ var headingHtml = heading ? heading.outerHTML : '';
231
+ if (cached) {
232
+ panel.innerHTML = headingHtml + cached;
233
+ panel.removeAttribute('data-pm-lazy');
234
+ wireProductMapWithin(panel);
235
+ if (cb) cb(true);
236
+ return;
237
+ }
238
+ panel.setAttribute('data-pm-loading', 'true');
239
+ var xhr = new XMLHttpRequest();
240
+ // Dex / wespa 2026-10-02: asset references are relative so the
241
+ // reverse-proxy mount point can live anywhere under its origin.
242
+ xhr.open('GET', './product-map/' + name, true);
243
+ xhr.onreadystatechange = function () {
244
+ if (xhr.readyState !== 4) return;
245
+ panel.removeAttribute('data-pm-loading');
246
+ if (xhr.status >= 200 && xhr.status < 300) {
247
+ pmPartialCache[pmCacheKey(name)] = xhr.responseText;
248
+ panel.innerHTML = headingHtml + xhr.responseText;
249
+ panel.removeAttribute('data-pm-lazy');
250
+ wireProductMapWithin(panel);
251
+ if (cb) cb(true);
252
+ } else {
253
+ panel.setAttribute('data-pm-lazy', 'true');
254
+ if (cb) cb(false);
255
+ }
256
+ };
257
+ xhr.send();
258
+ }
259
+
260
+ function activatePmGroup(name, opts) {
261
+ if (PM_GROUPS.indexOf(name) === -1) return false;
262
+ var buttons = document.querySelectorAll('.pm-group-btn');
263
+ for (var i = 0; i < buttons.length; i += 1) {
264
+ var btn = buttons[i];
265
+ var isTarget = btn.getAttribute('data-pm-group') === name;
266
+ btn.setAttribute('aria-selected', isTarget ? 'true' : 'false');
267
+ }
268
+ var panels = document.querySelectorAll('.pm-group');
269
+ for (var j = 0; j < panels.length; j += 1) {
270
+ var p = panels[j];
271
+ if (p.getAttribute('data-pm-group') === name) {
272
+ p.removeAttribute('hidden');
273
+ } else {
274
+ p.setAttribute('hidden', '');
275
+ }
276
+ }
277
+ var target = pmGroupPanel(name);
278
+ if (target && target.getAttribute('data-pm-lazy') === 'true') {
279
+ hydrateLazyGroup(name, function () {
280
+ if (opts && opts.after) opts.after();
281
+ applyPmStatusFilter(currentStatus());
282
+ });
283
+ } else {
284
+ if (opts && opts.after) opts.after();
285
+ applyPmStatusFilter(currentStatus());
286
+ }
287
+ return true;
288
+ }
289
+
290
+ function currentGroup() {
291
+ var sel = document.querySelector('.pm-group-btn[aria-selected="true"]');
292
+ return sel ? sel.getAttribute('data-pm-group') : 'shape';
293
+ }
294
+
295
+ function currentStatus() {
296
+ var s = document.querySelector('.pm-status-select');
297
+ return s ? s.value : 'all';
298
+ }
299
+
300
+ function currentOpenBuckets() {
301
+ var group = currentGroup();
302
+ var panel = pmGroupPanel(group);
303
+ if (!panel) return [];
304
+ var nodes = panel.querySelectorAll('details.pm-bucket[open]');
305
+ var out = [];
306
+ for (var i = 0; i < nodes.length; i += 1) {
307
+ var id = nodes[i].getAttribute('data-pm-bucket-id');
308
+ if (id) out.push(id);
309
+ }
310
+ return out;
311
+ }
312
+
313
+ function applyPmStatusFilter(status) {
314
+ if (PM_STATUSES.indexOf(status) === -1) return false;
315
+ var select = document.querySelector('.pm-status-select');
316
+ if (select) select.value = status;
317
+ var reqCards = document.querySelectorAll('#tab-product-map [data-req-status]');
318
+ for (var i = 0; i < reqCards.length; i += 1) {
319
+ var card = reqCards[i];
320
+ var s = card.getAttribute('data-req-status') || '';
321
+ if (status === 'all' || s === status) {
322
+ card.removeAttribute('hidden');
323
+ } else {
324
+ card.setAttribute('hidden', '');
325
+ }
326
+ }
327
+ var buckets = document.querySelectorAll('#tab-product-map .pm-group:not([hidden]) details.pm-bucket');
328
+ var emptyCount = 0;
329
+ for (var k = 0; k < buckets.length; k += 1) {
330
+ var bk = buckets[k];
331
+ var visible = bk.querySelectorAll('[data-req-status]:not([hidden])');
332
+ var bodyEmpty = bk.querySelector('.pm-bucket-body') && bk.querySelector('.pm-bucket-body').children.length === 0;
333
+ var isEmpty = visible.length === 0 && !bodyEmpty;
334
+ var body = bk.querySelector('.pm-bucket-body');
335
+ var emptyNote = body ? body.querySelector('.pm-bucket-empty-filter') : null;
336
+ if (isEmpty && status !== 'all') {
337
+ if (body && !emptyNote) {
338
+ emptyNote = document.createElement('p');
339
+ emptyNote.className = 'pm-bucket-empty pm-bucket-empty-filter';
340
+ emptyNote.innerHTML = '<em>0 requirements match this filter.</em>';
341
+ body.appendChild(emptyNote);
342
+ }
343
+ bk.setAttribute('data-pm-empty-under-filter', 'true');
344
+ emptyCount += 1;
345
+ } else {
346
+ if (emptyNote) emptyNote.parentNode.removeChild(emptyNote);
347
+ bk.removeAttribute('data-pm-empty-under-filter');
348
+ }
349
+ }
350
+ var activePanel = document.querySelector('#tab-product-map .pm-group:not([hidden])');
351
+ if (activePanel) {
352
+ var roll = activePanel.querySelector('.pm-empty-roll');
353
+ if (roll) {
354
+ var showBtn = roll.querySelector('.pm-empty-count');
355
+ if (emptyCount > 0 && status !== 'all') {
356
+ if (showBtn) showBtn.textContent = String(emptyCount);
357
+ roll.removeAttribute('hidden');
358
+ activePanel.classList.add('pm-hide-empty');
359
+ } else {
360
+ roll.setAttribute('hidden', '');
361
+ activePanel.classList.remove('pm-hide-empty');
362
+ }
363
+ }
364
+ }
365
+ return true;
366
+ }
367
+
368
+ function updatePmHash() {
369
+ if (!window.history || typeof window.history.pushState !== 'function') return;
370
+ var group = currentGroup();
371
+ var status = currentStatus();
372
+ var open = currentOpenBuckets();
373
+ var next = '#tab=product-map&group=' + group + '&status=' + status;
374
+ if (open.length > 0) next += '&open=' + encodeURIComponent(open.join(','));
375
+ if (window.location.hash === next && window.location.search === window.location.search) return;
376
+ // Preserve host query (?embed=, ?theme=, ?blueprint=, ?ticket=).
377
+ window.history.pushState(null, '', urlWithHash(next));
378
+ }
379
+
380
+ function openPmBuckets(ids) {
381
+ if (!ids || ids.length === 0) return;
382
+ var group = currentGroup();
383
+ var panel = pmGroupPanel(group);
384
+ if (!panel) return;
385
+ for (var i = 0; i < ids.length; i += 1) {
386
+ var raw = ids[i];
387
+ if (!raw) continue;
388
+ var node = panel.querySelector('details.pm-bucket[data-pm-bucket-id="' + raw.replace(/"/g, '\\"') + '"]');
389
+ if (node) node.open = true;
390
+ }
391
+ }
392
+
393
+ function wireProductMapWithin(root) {
394
+ root = root || document;
395
+ var buckets = root.querySelectorAll('details.pm-bucket');
396
+ for (var i = 0; i < buckets.length; i += 1) {
397
+ var bk = buckets[i];
398
+ if (bk.__rcfPmBucketWired) continue;
399
+ bk.__rcfPmBucketWired = true;
400
+ bk.addEventListener('toggle', function () {
401
+ if (window.__rcfPmSuppress) return;
402
+ updatePmHash();
403
+ });
404
+ }
405
+ var chips = root.querySelectorAll('.pm-jump-chip');
406
+ for (var j = 0; j < chips.length; j += 1) {
407
+ var chip = chips[j];
408
+ if (chip.__rcfPmChipWired) continue;
409
+ chip.__rcfPmChipWired = true;
410
+ chip.addEventListener('click', function (ev) {
411
+ var target = ev.currentTarget.getAttribute('data-pm-jump');
412
+ var groupAttr = ev.currentTarget.closest('.pm-jump-nav').getAttribute('data-pm-jump-group');
413
+ var panel = pmGroupPanel(groupAttr);
414
+ if (!panel) return;
415
+ var node = panel.querySelector('details.pm-bucket[data-pm-bucket-id="' + target.replace(/"/g, '\\"') + '"]');
416
+ if (!node) return;
417
+ node.open = true;
418
+ try { node.scrollIntoView({ block: 'start' }); } catch (e) { node.scrollIntoView(); }
419
+ });
420
+ }
421
+ var bulk = root.querySelectorAll('.pm-bulk-btn');
422
+ for (var b = 0; b < bulk.length; b += 1) {
423
+ var btn = bulk[b];
424
+ if (btn.__rcfPmBulkWired) continue;
425
+ btn.__rcfPmBulkWired = true;
426
+ btn.addEventListener('click', function (ev) {
427
+ var action = ev.currentTarget.getAttribute('data-pm-bulk');
428
+ var panel = document.querySelector('#tab-product-map .pm-group:not([hidden])');
429
+ if (!panel) return;
430
+ var all = panel.querySelectorAll('details.pm-bucket');
431
+ window.__rcfPmSuppress = true;
432
+ for (var i = 0; i < all.length; i += 1) all[i].open = (action === 'expand');
433
+ window.__rcfPmSuppress = false;
434
+ updatePmHash();
435
+ });
436
+ }
437
+ var rolls = root.querySelectorAll('.pm-empty-toggle');
438
+ for (var r = 0; r < rolls.length; r += 1) {
439
+ var rt = rolls[r];
440
+ if (rt.__rcfPmEmptyWired) continue;
441
+ rt.__rcfPmEmptyWired = true;
442
+ rt.addEventListener('click', function (ev) {
443
+ var panel = ev.currentTarget.closest('.pm-group');
444
+ if (!panel) return;
445
+ if (panel.classList.contains('pm-hide-empty')) {
446
+ panel.classList.remove('pm-hide-empty');
447
+ ev.currentTarget.textContent = 'Hide empty buckets';
448
+ } else {
449
+ panel.classList.add('pm-hide-empty');
450
+ var span = document.createElement('span');
451
+ span.className = 'pm-empty-count';
452
+ span.textContent = String(panel.querySelectorAll('details.pm-bucket[data-pm-empty-under-filter="true"]').length);
453
+ ev.currentTarget.textContent = '';
454
+ ev.currentTarget.appendChild(document.createTextNode('Show '));
455
+ ev.currentTarget.appendChild(span);
456
+ ev.currentTarget.appendChild(document.createTextNode(' empty buckets'));
457
+ }
458
+ });
459
+ }
460
+ }
461
+
462
+ function wireProductMap() {
463
+ var buttons = document.querySelectorAll('.pm-group-btn');
464
+ for (var i = 0; i < buttons.length; i += 1) {
465
+ if (buttons[i].__rcfPmWired) continue;
466
+ buttons[i].__rcfPmWired = true;
467
+ buttons[i].addEventListener('click', function (ev) {
468
+ var name = ev.currentTarget.getAttribute('data-pm-group');
469
+ if (activatePmGroup(name)) updatePmHash();
470
+ });
471
+ }
472
+ var select = document.querySelector('.pm-status-select');
473
+ if (select && !select.__rcfPmWired) {
474
+ select.__rcfPmWired = true;
475
+ select.addEventListener('change', function () {
476
+ applyPmStatusFilter(select.value);
477
+ updatePmHash();
478
+ });
479
+ }
480
+ wireProductMapWithin(document);
481
+ }
482
+
483
+ // ---- hash router ------------------------------------------------------
484
+ //
485
+ // PR 1 contract: #tab=<name>&sub=<name>&entity=<id>&... with bare
486
+ // #REQ-002 still resolving. Unknown params survive. Writes go through
487
+ // urlWithHash so the ?embed=/?theme= query is preserved. 'sub=' is
488
+ // owned by the active tab (Build tab in PR 5 for specs|dag); for PR 1
489
+ // we only read the value and leave acting on it to a later tab-side
490
+ // handler.
491
+
492
+ function resolveHash(hash) {
493
+ if (!hash) { activateTab('readiness'); return; }
494
+ var raw = hash.charAt(0) === '#' ? hash.slice(1) : hash;
495
+ // Decision 11 (PR 3): `#entity=<id>` without a tab key still
496
+ // resolves - we find the target, activate its tab and open ancestors.
497
+ if (raw.indexOf('=') !== -1 && raw.indexOf('tab=') === -1) {
498
+ var kv = parseHashParams(raw);
499
+ if (kv.entity) {
500
+ var entTarget = findByDocId(kv.entity);
501
+ if (entTarget) {
502
+ var entTab = tabForNode(entTarget);
503
+ if (entTab) activateTab(entTab);
504
+ openAncestorDetails(entTarget);
505
+ if (entTarget.tagName && entTarget.tagName.toLowerCase() === 'details') entTarget.open = true;
506
+ try { entTarget.scrollIntoView({ block: 'start' }); } catch (e) { entTarget.scrollIntoView(); }
507
+ return;
508
+ }
509
+ }
510
+ }
511
+ if (raw.indexOf('tab=') === 0 || raw.indexOf('tab=') > 0) {
512
+ // Fast path: tab is the first key.
513
+ var params = parseHashParams(raw);
514
+ var tab = params.tab;
515
+ if (tab && TABS.indexOf(tab) !== -1) {
516
+ activateTab(tab);
517
+ if (tab === 'product-map') {
518
+ var openIds = params.open ? decodeURIComponent(params.open).split(',').filter(Boolean) : [];
519
+ activatePmGroup(params.group || 'shape', {
520
+ after: function () {
521
+ if (params.status) applyPmStatusFilter(params.status);
522
+ openPmBuckets(openIds);
523
+ },
524
+ });
525
+ }
526
+ // Requirements tab: push the hash filter slots into the
527
+ // FilterBar inputs and re-run the row filter so the first paint
528
+ // reflects the URL exactly. #entity=... below opens the entity.
529
+ if (tab === 'requirements' && requirementsFilterBar()) {
530
+ applyRequirementsHash(params);
531
+ }
532
+ // Architecture tab: push the two FilterBar states + any
533
+ // `open=<tad-section>,<tad-section>...` deep-link so the first
534
+ // paint reflects the URL (PR 4, decisions 3 and 5).
535
+ if (tab === 'architecture' && (archBar('architecture-components') || archBar('architecture-decisions'))) {
536
+ applyArchitectureHash(params);
537
+ }
538
+ // Build tab (PR 5): activate the right sub-tab and push the
539
+ // Specs FilterBar state so the first paint reflects the URL.
540
+ if (tab === 'build') {
541
+ applyBuildHash(params);
542
+ }
543
+ // #tab=requirements&entity=REQ-002 opens the entity in place.
544
+ if (params.entity) {
545
+ var ent = findByDocId(params.entity);
546
+ if (ent) {
547
+ openAncestorDetails(ent);
548
+ if (ent.tagName && ent.tagName.toLowerCase() === 'details') ent.open = true;
549
+ try { ent.scrollIntoView({ block: 'start' }); } catch (e) { ent.scrollIntoView(); }
550
+ flashLookupTarget(ent);
551
+ }
552
+ }
553
+ return;
554
+ }
555
+ }
556
+ // Bare hash (#REQ-002 etc) stays supported.
557
+ var target = findByDocId(raw);
558
+ if (!target) { activateTab('readiness'); return; }
559
+ var tabName = tabForNode(target);
560
+ if (tabName) activateTab(tabName);
561
+ openAncestorDetails(target);
562
+ if (target.tagName && target.tagName.toLowerCase() === 'details') target.open = true;
563
+ try { target.scrollIntoView({ block: 'start' }); } catch (e) { target.scrollIntoView(); }
564
+ flashLookupTarget(target);
565
+ }
566
+
567
+ function onTabClick(ev) {
568
+ var btn = ev.currentTarget;
569
+ var name = btn.getAttribute('data-tab');
570
+ if (!name) return;
571
+ ev.preventDefault && ev.preventDefault();
572
+ activateTab(name);
573
+ if (name === 'product-map') {
574
+ activatePmGroup(currentGroup());
575
+ }
576
+ // The Build tab carries a SubTabStrip + FilterBar state the URL
577
+ // mirrors; re-emit the current fragment so #tab=build / UI stay in
578
+ // step (fixes the DAG-sticky case: previously `#tab=build` was
579
+ // written while DAG remained visible).
580
+ if (name === 'build' && buildSubTabStrip()) {
581
+ writeHash(buildHashFragment(), true);
582
+ return;
583
+ }
584
+ // Hash write preserves ?embed=/?theme=/... (Dex contract, PR 1).
585
+ writeHash('#tab=' + name, true);
586
+ }
587
+
588
+ function wireTabs() {
589
+ tabButtons().forEach(function (btn) {
590
+ if (btn.__rcfTabWired) return;
591
+ btn.__rcfTabWired = true;
592
+ btn.addEventListener('click', onTabClick);
593
+ });
594
+ }
595
+
596
+ // ---- shared toast helper (viewer UI refresh PR 2) --------------------
597
+ //
598
+ // The shell renders exactly one <div class="rcf-toast" data-toast> and
599
+ // keeps it outside #rcf-live-content so the SSE innerHTML swap does
600
+ // not blow it away. showToast() is idempotent across repeat calls:
601
+ // the latest message replaces whatever is showing, the fade-out
602
+ // timer resets, and the element clears when the fade completes.
603
+ var toastHideTimer = null;
604
+ function showToast(message, opts) {
605
+ var el = document.querySelector('[data-toast]');
606
+ if (!el) return;
607
+ var text = message == null ? '' : String(message);
608
+ el.textContent = text;
609
+ el.classList.add('show');
610
+ if (toastHideTimer) { clearTimeout(toastHideTimer); toastHideTimer = null; }
611
+ var durationMs = opts && typeof opts.durationMs === 'number' ? opts.durationMs : 2200;
612
+ toastHideTimer = setTimeout(function () {
613
+ el.classList.remove('show');
614
+ // Clear the text one fade-out later so a reader does not re-announce it.
615
+ toastHideTimer = setTimeout(function () {
616
+ if (!el.classList.contains('show')) el.textContent = '';
617
+ }, 200);
618
+ }, durationMs);
619
+ }
620
+
621
+ // ---- component fixture page wiring (viewer UI refresh PR 2) ----------
622
+ //
623
+ // The /_fixtures/components page carries a theme toggle and a demo
624
+ // button that fires showToast() so a reviewer can confirm the Toast
625
+ // round-trips end-to-end. Both guards against null elements so the
626
+ // helpers no-op on every other page.
627
+ function wireFixturePage() {
628
+ var themeBtns = document.querySelectorAll('[data-rcf-fixture-theme]');
629
+ for (var i = 0; i < themeBtns.length; i += 1) {
630
+ var btn = themeBtns[i];
631
+ if (btn.__rcfFixtureThemeWired) continue;
632
+ btn.__rcfFixtureThemeWired = true;
633
+ btn.addEventListener('click', function (ev) {
634
+ var mode = ev.currentTarget.getAttribute('data-rcf-fixture-theme');
635
+ applyTheme(mode === 'auto' ? null : mode);
636
+ var buttons = document.querySelectorAll('[data-rcf-fixture-theme]');
637
+ for (var j = 0; j < buttons.length; j += 1) {
638
+ var b = buttons[j];
639
+ var isTarget = b.getAttribute('data-rcf-fixture-theme') === mode;
640
+ b.setAttribute('aria-pressed', isTarget ? 'true' : 'false');
641
+ }
642
+ });
643
+ }
644
+ var toastBtns = document.querySelectorAll('[data-rcf-fixture-toast]');
645
+ for (var k = 0; k < toastBtns.length; k += 1) {
646
+ var tb = toastBtns[k];
647
+ if (tb.__rcfFixtureToastWired) continue;
648
+ tb.__rcfFixtureToastWired = true;
649
+ tb.addEventListener('click', function () {
650
+ showToast('Saved. (demo of the shared Toast helper)');
651
+ });
652
+ }
653
+ }
654
+
655
+ // ---- Requirements FilterBar + EntitySelector (viewer UI refresh PR 3) --
656
+ //
657
+ // The Requirements tab mounts a FilterBar (text, area, priority, status,
658
+ // Needs-work) and the PRD tab mounts an EntitySelector (type-ahead jump
659
+ // + area chips). Filter state lives in the hash so a filtered view is a
660
+ // link (decision 3). The hash slots this reads/writes:
661
+ // #tab=requirements[&q=...][&domain=...][&priority=...][&status=...][&needswork=1]
662
+ // Area chips in the PRD selector write #tab=requirements&domain=...;
663
+ // the type-ahead jump writes #tab=requirements&entity=<id>.
664
+
665
+ function requirementsListNode() {
666
+ return document.querySelector('[data-rcf-list="requirements"]');
667
+ }
668
+
669
+ function requirementsFilterBar() {
670
+ return document.querySelector('[data-rcf-filterbar="requirements"]');
671
+ }
672
+
673
+ function readRequirementsFilterState() {
674
+ var bar = requirementsFilterBar();
675
+ if (!bar) return null;
676
+ var text = bar.querySelector('.rcf-filter-text');
677
+ var state = { q: text ? text.value.trim() : '', needswork: false };
678
+ var selects = bar.querySelectorAll('.rcf-filter-select');
679
+ for (var i = 0; i < selects.length; i += 1) {
680
+ state[selects[i].getAttribute('data-filter-key') || 'select'] = selects[i].value;
681
+ }
682
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
683
+ for (var j = 0; j < toggles.length; j += 1) {
684
+ state[toggles[j].getAttribute('data-filter-key') || 'toggle'] = toggles[j].checked;
685
+ }
686
+ return state;
687
+ }
688
+
689
+ function writeRequirementsFilterState(state) {
690
+ var bar = requirementsFilterBar();
691
+ if (!bar) return;
692
+ var text = bar.querySelector('.rcf-filter-text');
693
+ if (text) text.value = state.q || '';
694
+ var selects = bar.querySelectorAll('.rcf-filter-select');
695
+ for (var i = 0; i < selects.length; i += 1) {
696
+ var key = selects[i].getAttribute('data-filter-key') || '';
697
+ selects[i].value = state[key] != null ? String(state[key]) : '';
698
+ }
699
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
700
+ for (var j = 0; j < toggles.length; j += 1) {
701
+ var tkey = toggles[j].getAttribute('data-filter-key') || '';
702
+ toggles[j].checked = state[tkey] === true || state[tkey] === 'true' || state[tkey] === '1';
703
+ }
704
+ }
705
+
706
+ function applyRequirementsFilter() {
707
+ var list = requirementsListNode();
708
+ if (!list) return;
709
+ var state = readRequirementsFilterState() || { q: '', domain: '', priority: '', status: '', needswork: false };
710
+ var qLower = (state.q || '').toLowerCase();
711
+ var rows = list.querySelectorAll(':scope > details.rcf-row[data-doc-id^="REQ-"]');
712
+ var visible = 0;
713
+ for (var i = 0; i < rows.length; i += 1) {
714
+ var row = rows[i];
715
+ var hide = false;
716
+ if (state.domain && row.getAttribute('data-domain') !== state.domain) hide = true;
717
+ if (!hide && state.priority && row.getAttribute('data-priority') !== state.priority) hide = true;
718
+ if (!hide && state.status && row.getAttribute('data-status') !== state.status) hide = true;
719
+ if (!hide && state.needswork && row.getAttribute('data-needswork') !== '1') hide = true;
720
+ if (!hide && qLower) {
721
+ var hay = row.getAttribute('data-text') || '';
722
+ if (hay.indexOf(qLower) === -1) hide = true;
723
+ }
724
+ if (hide) row.setAttribute('hidden', '');
725
+ else { row.removeAttribute('hidden'); visible += 1; }
726
+ }
727
+ var countEl = document.querySelector('[data-rcf-filterbar="requirements"] .rcf-filter-count');
728
+ if (countEl) countEl.textContent = String(visible) + ' of ' + String(rows.length) + ' visible';
729
+ }
730
+
731
+ function requirementsHashFragment(state) {
732
+ var parts = ['tab=requirements'];
733
+ if (state.q) parts.push('q=' + encodeURIComponent(state.q));
734
+ if (state.domain) parts.push('domain=' + encodeURIComponent(state.domain));
735
+ if (state.priority) parts.push('priority=' + encodeURIComponent(state.priority));
736
+ if (state.status) parts.push('status=' + encodeURIComponent(state.status));
737
+ if (state.needswork) parts.push('needswork=1');
738
+ if (state.entity) parts.push('entity=' + encodeURIComponent(state.entity));
739
+ // Decision 11: preserve unknown hash params through filter writes.
740
+ if (state.extraParts) parts = parts.concat(state.extraParts);
741
+ return '#' + parts.join('&');
742
+ }
743
+
744
+ function currentRequirementsHashExtras() {
745
+ // Read the live hash, keep every param not owned by the Requirements
746
+ // FilterBar so filter writes preserve the selected entity and any
747
+ // other extension (decision 11 preservation contract).
748
+ var raw = window.location.hash || '';
749
+ if (raw[0] === '#') raw = raw.slice(1);
750
+ if (!raw) return { entity: '', extraParts: [] };
751
+ var pairs = raw.split('&');
752
+ var entity = '';
753
+ var extras = [];
754
+ var owned = { tab: true, q: true, domain: true, priority: true, status: true, needswork: true, entity: true };
755
+ for (var i = 0; i < pairs.length; i += 1) {
756
+ var p = pairs[i];
757
+ if (!p) continue;
758
+ var eq = p.indexOf('=');
759
+ var k = eq === -1 ? p : p.slice(0, eq);
760
+ if (k === 'entity' && eq !== -1) { entity = decodeURIComponent(p.slice(eq + 1)); continue; }
761
+ if (owned[k]) continue;
762
+ extras.push(p);
763
+ }
764
+ return { entity: entity, extraParts: extras };
765
+ }
766
+
767
+ function writeRequirementsHash() {
768
+ var state = readRequirementsFilterState();
769
+ if (!state) return;
770
+ var extras = currentRequirementsHashExtras();
771
+ state.entity = extras.entity;
772
+ state.extraParts = extras.extraParts;
773
+ writeHash(requirementsHashFragment(state), true);
774
+ }
775
+
776
+ function applyRequirementsHash(params) {
777
+ var state = {
778
+ q: params.q ? decodeURIComponent(params.q) : '',
779
+ domain: params.domain ? decodeURIComponent(params.domain) : '',
780
+ priority: params.priority ? decodeURIComponent(params.priority) : '',
781
+ status: params.status ? decodeURIComponent(params.status) : '',
782
+ needswork: params.needswork === '1' || params.needswork === 'true',
783
+ };
784
+ writeRequirementsFilterState(state);
785
+ applyRequirementsFilter();
786
+ }
787
+
788
+ function expandAllRequirements(open) {
789
+ var list = requirementsListNode();
790
+ if (!list) return;
791
+ var rows = list.querySelectorAll(':scope > details.rcf-row');
792
+ for (var i = 0; i < rows.length; i += 1) {
793
+ if (rows[i].hasAttribute('hidden')) continue;
794
+ rows[i].open = !!open;
795
+ }
796
+ var btn = document.querySelector('[data-rcf-filterbar="requirements"] .rcf-filter-expand');
797
+ if (btn) {
798
+ btn.textContent = open ? 'Collapse all' : 'Expand all';
799
+ btn.setAttribute('data-expand-state', open ? 'expanded' : 'collapsed');
800
+ }
801
+ }
802
+
803
+ function wireRequirementsFilterBar() {
804
+ var bar = requirementsFilterBar();
805
+ if (!bar || bar.__rcfReqFilterWired) return;
806
+ bar.__rcfReqFilterWired = true;
807
+ var text = bar.querySelector('.rcf-filter-text');
808
+ if (text) {
809
+ var debounceTimer = null;
810
+ text.addEventListener('input', function () {
811
+ if (debounceTimer) clearTimeout(debounceTimer);
812
+ debounceTimer = setTimeout(function () {
813
+ applyRequirementsFilter();
814
+ writeRequirementsHash();
815
+ }, 150);
816
+ });
817
+ }
818
+ var selects = bar.querySelectorAll('.rcf-filter-select');
819
+ for (var i = 0; i < selects.length; i += 1) {
820
+ selects[i].addEventListener('change', function () {
821
+ applyRequirementsFilter();
822
+ writeRequirementsHash();
823
+ });
824
+ }
825
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
826
+ for (var j = 0; j < toggles.length; j += 1) {
827
+ toggles[j].addEventListener('change', function () {
828
+ applyRequirementsFilter();
829
+ writeRequirementsHash();
830
+ });
831
+ }
832
+ var expandBtn = bar.querySelector('.rcf-filter-expand');
833
+ if (expandBtn) {
834
+ expandBtn.addEventListener('click', function (ev) {
835
+ ev.preventDefault && ev.preventDefault();
836
+ var isCollapsed = expandBtn.getAttribute('data-expand-state') !== 'expanded';
837
+ expandAllRequirements(isCollapsed);
838
+ });
839
+ }
840
+ }
841
+
842
+ // ---- Architecture FilterBars (viewer UI refresh PR 4) ----------------
843
+ //
844
+ // The Architecture tab mounts two FilterBars: Components
845
+ // (architecture-components) and Decisions (architecture-decisions).
846
+ // Each is text + Status facet; state lives in the hash under the
847
+ // owning tab so the view is a link. Hash slots this reads/writes:
848
+ // #tab=architecture[&cq=...][&cstatus=...][&dq=...][&dstatus=...]
849
+ // [&open=components|decisions|<tad-section-key>]
850
+ // The `open=` key is a comma-separated set so a review link can
851
+ // deep-open one TAD section (e.g. open=integrationArchitecture).
852
+
853
+ var ARCH_HASH_KEYS = {
854
+ 'architecture-components': { q: 'cq', status: 'cstatus' },
855
+ 'architecture-decisions': { q: 'dq', status: 'dstatus' },
856
+ };
857
+
858
+ function archBar(hashKey) {
859
+ return document.querySelector('[data-rcf-filterbar="' + hashKey + '"]');
860
+ }
861
+
862
+ function archList(hashKey) {
863
+ return document.querySelector('[data-rcf-list="' + hashKey + '"]');
864
+ }
865
+
866
+ function readArchitectureFilterState(hashKey) {
867
+ var bar = archBar(hashKey);
868
+ if (!bar) return null;
869
+ var text = bar.querySelector('.rcf-filter-text');
870
+ var state = { q: text ? text.value.trim() : '' };
871
+ var selects = bar.querySelectorAll('.rcf-filter-select');
872
+ for (var i = 0; i < selects.length; i += 1) {
873
+ state[selects[i].getAttribute('data-filter-key') || 'select'] = selects[i].value;
874
+ }
875
+ return state;
876
+ }
877
+
878
+ function writeArchitectureFilterState(hashKey, state) {
879
+ var bar = archBar(hashKey);
880
+ if (!bar) return;
881
+ var text = bar.querySelector('.rcf-filter-text');
882
+ if (text) text.value = state.q || '';
883
+ var selects = bar.querySelectorAll('.rcf-filter-select');
884
+ for (var i = 0; i < selects.length; i += 1) {
885
+ var key = selects[i].getAttribute('data-filter-key') || '';
886
+ selects[i].value = state[key] != null ? String(state[key]) : '';
887
+ }
888
+ }
889
+
890
+ function applyArchitectureFilter(hashKey) {
891
+ var list = archList(hashKey);
892
+ if (!list) return;
893
+ var state = readArchitectureFilterState(hashKey) || { q: '', status: '' };
894
+ var qLower = (state.q || '').toLowerCase();
895
+ var rows = list.querySelectorAll(':scope > details.rcf-row');
896
+ var visible = 0;
897
+ for (var i = 0; i < rows.length; i += 1) {
898
+ var row = rows[i];
899
+ var hide = false;
900
+ if (state.status && row.getAttribute('data-status') !== state.status) hide = true;
901
+ if (!hide && qLower) {
902
+ var hay = row.getAttribute('data-text') || '';
903
+ if (hay.indexOf(qLower) === -1) hide = true;
904
+ }
905
+ if (hide) row.setAttribute('hidden', '');
906
+ else { row.removeAttribute('hidden'); visible += 1; }
907
+ }
908
+ var countEl = document.querySelector('[data-rcf-filterbar="' + hashKey + '"] .rcf-filter-count');
909
+ if (countEl) countEl.textContent = String(visible) + ' of ' + String(rows.length) + ' visible';
910
+ }
911
+
912
+ function architectureHashFragment() {
913
+ var parts = ['tab=architecture'];
914
+ for (var hk in ARCH_HASH_KEYS) {
915
+ if (!Object.prototype.hasOwnProperty.call(ARCH_HASH_KEYS, hk)) continue;
916
+ var state = readArchitectureFilterState(hk);
917
+ var map = ARCH_HASH_KEYS[hk];
918
+ if (!state) continue;
919
+ if (state.q) parts.push(map.q + '=' + encodeURIComponent(state.q));
920
+ if (state.status) parts.push(map.status + '=' + encodeURIComponent(state.status));
921
+ }
922
+ return '#' + parts.join('&');
923
+ }
924
+
925
+ function writeArchitectureHash() {
926
+ writeHash(architectureHashFragment(), true);
927
+ }
928
+
929
+ function applyArchitectureHash(params) {
930
+ var statesByBar = {
931
+ 'architecture-components': {
932
+ q: params.cq ? decodeURIComponent(params.cq) : '',
933
+ status: params.cstatus ? decodeURIComponent(params.cstatus) : '',
934
+ },
935
+ 'architecture-decisions': {
936
+ q: params.dq ? decodeURIComponent(params.dq) : '',
937
+ status: params.dstatus ? decodeURIComponent(params.dstatus) : '',
938
+ },
939
+ };
940
+ for (var hk in statesByBar) {
941
+ if (!Object.prototype.hasOwnProperty.call(statesByBar, hk)) continue;
942
+ writeArchitectureFilterState(hk, statesByBar[hk]);
943
+ applyArchitectureFilter(hk);
944
+ }
945
+ if (params.open) {
946
+ var openSet = decodeURIComponent(params.open).split(',').filter(Boolean);
947
+ openArchitectureSections(openSet);
948
+ }
949
+ }
950
+
951
+ function openArchitectureSections(keys) {
952
+ for (var i = 0; i < keys.length; i += 1) {
953
+ var el = document.querySelector('[data-rcf-tad-section="' + keys[i] + '"]');
954
+ if (el && el.tagName && el.tagName.toLowerCase() === 'details') el.open = true;
955
+ }
956
+ }
957
+
958
+ function expandAllArchitecture(hashKey, open) {
959
+ var list = archList(hashKey);
960
+ if (!list) return;
961
+ var rows = list.querySelectorAll(':scope > details.rcf-row');
962
+ for (var i = 0; i < rows.length; i += 1) {
963
+ if (rows[i].hasAttribute('hidden')) continue;
964
+ rows[i].open = !!open;
965
+ }
966
+ var btn = document.querySelector('[data-rcf-filterbar="' + hashKey + '"] .rcf-filter-expand');
967
+ if (btn) {
968
+ btn.textContent = open ? 'Collapse all' : 'Expand all';
969
+ btn.setAttribute('data-expand-state', open ? 'expanded' : 'collapsed');
970
+ }
971
+ }
972
+
973
+ function wireArchitectureFilterBar(hashKey) {
974
+ var bar = archBar(hashKey);
975
+ if (!bar || bar.__rcfArchFilterWired) return;
976
+ bar.__rcfArchFilterWired = true;
977
+ var text = bar.querySelector('.rcf-filter-text');
978
+ if (text) {
979
+ var debounceTimer = null;
980
+ text.addEventListener('input', function () {
981
+ if (debounceTimer) clearTimeout(debounceTimer);
982
+ debounceTimer = setTimeout(function () {
983
+ applyArchitectureFilter(hashKey);
984
+ writeArchitectureHash();
985
+ }, 150);
986
+ });
987
+ }
988
+ var selects = bar.querySelectorAll('.rcf-filter-select');
989
+ for (var i = 0; i < selects.length; i += 1) {
990
+ selects[i].addEventListener('change', function () {
991
+ applyArchitectureFilter(hashKey);
992
+ writeArchitectureHash();
993
+ });
994
+ }
995
+ var expandBtn = bar.querySelector('.rcf-filter-expand');
996
+ if (expandBtn) {
997
+ expandBtn.addEventListener('click', function (ev) {
998
+ ev.preventDefault && ev.preventDefault();
999
+ var isCollapsed = expandBtn.getAttribute('data-expand-state') !== 'expanded';
1000
+ expandAllArchitecture(hashKey, isCollapsed);
1001
+ });
1002
+ }
1003
+ }
1004
+
1005
+ function wireArchitectureFilterBars() {
1006
+ wireArchitectureFilterBar('architecture-components');
1007
+ wireArchitectureFilterBar('architecture-decisions');
1008
+ }
1009
+
1010
+ // ---- Build tab (viewer UI refresh PR 5) ------------------------------
1011
+ //
1012
+ // The Build tab carries a SubTabStrip (Specs | DAG; DAG is a PR 6
1013
+ // placeholder) and the Specs sub-tab mounts a FilterBar
1014
+ // (text, status, area, size, Buildable-now). Filter + sub-tab state
1015
+ // live in the hash so a filtered view is a link. Hash slots read /
1016
+ // written here:
1017
+ // #tab=build[&sub=specs|dag][&q=...][&status=...][&domain=...][&size=...][&buildable=1]
1018
+
1019
+ var BUILD_SUB = ['specs', 'dag'];
1020
+
1021
+ function buildBar() {
1022
+ return document.querySelector('[data-rcf-filterbar="build-specs"]');
1023
+ }
1024
+
1025
+ function buildListNode() {
1026
+ return document.querySelector('[data-rcf-list="build-specs"]');
1027
+ }
1028
+
1029
+ function buildSubTabStrip() {
1030
+ return document.querySelector('[data-rcf-subtabstrip="build"]');
1031
+ }
1032
+
1033
+ function buildSubPanel(sub) {
1034
+ return document.querySelector('[data-rcf-subpanel="' + sub + '"]');
1035
+ }
1036
+
1037
+ function activateBuildSub(sub) {
1038
+ if (BUILD_SUB.indexOf(sub) === -1) sub = 'specs';
1039
+ var strip = buildSubTabStrip();
1040
+ if (strip) {
1041
+ var btns = strip.querySelectorAll('[role="tab"]');
1042
+ for (var i = 0; i < btns.length; i += 1) {
1043
+ var isTarget = btns[i].getAttribute('data-sub') === sub;
1044
+ btns[i].setAttribute('aria-selected', isTarget ? 'true' : 'false');
1045
+ }
1046
+ }
1047
+ for (var j = 0; j < BUILD_SUB.length; j += 1) {
1048
+ var p = buildSubPanel(BUILD_SUB[j]);
1049
+ if (!p) continue;
1050
+ if (BUILD_SUB[j] === sub) p.removeAttribute('hidden');
1051
+ else p.setAttribute('hidden', '');
1052
+ }
1053
+ return sub;
1054
+ }
1055
+
1056
+ function currentBuildSub() {
1057
+ var strip = buildSubTabStrip();
1058
+ if (!strip) return 'specs';
1059
+ var active = strip.querySelector('[role="tab"][aria-selected="true"]');
1060
+ return (active && active.getAttribute('data-sub')) || 'specs';
1061
+ }
1062
+
1063
+ function readBuildFilterState() {
1064
+ var bar = buildBar();
1065
+ if (!bar) return null;
1066
+ var text = bar.querySelector('.rcf-filter-text');
1067
+ var state = { q: text ? text.value.trim() : '', buildable: false };
1068
+ var selects = bar.querySelectorAll('.rcf-filter-select');
1069
+ for (var i = 0; i < selects.length; i += 1) {
1070
+ state[selects[i].getAttribute('data-filter-key') || 'select'] = selects[i].value;
1071
+ }
1072
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
1073
+ for (var j = 0; j < toggles.length; j += 1) {
1074
+ state[toggles[j].getAttribute('data-filter-key') || 'toggle'] = toggles[j].checked;
1075
+ }
1076
+ return state;
1077
+ }
1078
+
1079
+ function writeBuildFilterState(state) {
1080
+ var bar = buildBar();
1081
+ if (!bar) return;
1082
+ var text = bar.querySelector('.rcf-filter-text');
1083
+ if (text) text.value = state.q || '';
1084
+ var selects = bar.querySelectorAll('.rcf-filter-select');
1085
+ for (var i = 0; i < selects.length; i += 1) {
1086
+ var key = selects[i].getAttribute('data-filter-key') || '';
1087
+ selects[i].value = state[key] != null ? String(state[key]) : '';
1088
+ }
1089
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
1090
+ for (var j = 0; j < toggles.length; j += 1) {
1091
+ var tkey = toggles[j].getAttribute('data-filter-key') || '';
1092
+ toggles[j].checked = state[tkey] === true || state[tkey] === 'true' || state[tkey] === '1';
1093
+ }
1094
+ }
1095
+
1096
+ function applyBuildFilter() {
1097
+ var list = buildListNode();
1098
+ if (!list) return;
1099
+ var state = readBuildFilterState() || { q: '', status: '', domain: '', size: '', buildable: false };
1100
+ var qLower = (state.q || '').toLowerCase();
1101
+ var rows = list.querySelectorAll(':scope > details.rcf-row');
1102
+ var visible = 0;
1103
+ for (var i = 0; i < rows.length; i += 1) {
1104
+ var row = rows[i];
1105
+ var hide = false;
1106
+ if (state.status && row.getAttribute('data-status') !== state.status) hide = true;
1107
+ if (!hide && state.domain && row.getAttribute('data-domain') !== state.domain) hide = true;
1108
+ if (!hide && state.size && row.getAttribute('data-size') !== state.size) hide = true;
1109
+ if (!hide && state.buildable && row.getAttribute('data-buildable') !== '1') hide = true;
1110
+ if (!hide && qLower) {
1111
+ var hay = row.getAttribute('data-text') || '';
1112
+ if (hay.indexOf(qLower) === -1) hide = true;
1113
+ }
1114
+ if (hide) row.setAttribute('hidden', '');
1115
+ else { row.removeAttribute('hidden'); visible += 1; }
1116
+ }
1117
+ var countEl = document.querySelector('[data-rcf-filterbar="build-specs"] .rcf-filter-count');
1118
+ if (countEl) countEl.textContent = String(visible) + ' of ' + String(rows.length) + ' visible';
1119
+ }
1120
+
1121
+ function currentBuildHashExtras() {
1122
+ // Read the live hash, keep every param not owned by the Build
1123
+ // FilterBar + SubTabStrip so sub-tab / filter writes preserve the
1124
+ // selected entity and any other extension (decision 11 preservation
1125
+ // contract; same shape as currentRequirementsHashExtras).
1126
+ var raw = window.location.hash || '';
1127
+ if (raw[0] === '#') raw = raw.slice(1);
1128
+ if (!raw) return { entity: '', extraParts: [] };
1129
+ var pairs = raw.split('&');
1130
+ var entity = '';
1131
+ var extras = [];
1132
+ var owned = { tab: true, sub: true, q: true, status: true, domain: true, size: true, buildable: true, entity: true };
1133
+ for (var i = 0; i < pairs.length; i += 1) {
1134
+ var p = pairs[i];
1135
+ if (!p) continue;
1136
+ var eq = p.indexOf('=');
1137
+ var k = eq === -1 ? p : p.slice(0, eq);
1138
+ if (k === 'entity' && eq !== -1) { entity = decodeURIComponent(p.slice(eq + 1)); continue; }
1139
+ if (owned[k]) continue;
1140
+ extras.push(p);
1141
+ }
1142
+ return { entity: entity, extraParts: extras };
1143
+ }
1144
+
1145
+ function currentDagHashExtras() {
1146
+ // On the DAG sub-tab, the Specs filter params (q/status/domain/size/
1147
+ // buildable) are UNKNOWN - the DAG does not own them. Preserve them
1148
+ // through DAG writes per the decision 11 preservation contract so
1149
+ // deep links like `#tab=build&sub=dag&entity=FBS-012&status=notStarted`
1150
+ // survive filter and selection changes.
1151
+ var raw = window.location.hash || '';
1152
+ if (raw[0] === '#') raw = raw.slice(1);
1153
+ if (!raw) return [];
1154
+ var pairs = raw.split('&');
1155
+ var extras = [];
1156
+ var owned = { tab: true, sub: true, entity: true };
1157
+ for (var i = 0; i < pairs.length; i += 1) {
1158
+ var p = pairs[i];
1159
+ if (!p) continue;
1160
+ var eq = p.indexOf('=');
1161
+ var k = eq === -1 ? p : p.slice(0, eq);
1162
+ if (owned[k]) continue;
1163
+ extras.push(p);
1164
+ }
1165
+ return extras;
1166
+ }
1167
+
1168
+ function buildHashFragment() {
1169
+ var parts = ['tab=build'];
1170
+ var sub = currentBuildSub();
1171
+ if (sub && sub !== 'specs') parts.push('sub=' + encodeURIComponent(sub));
1172
+ if (sub === 'dag') {
1173
+ var canvas = dagCanvas();
1174
+ var sel = canvas && canvas.getAttribute('data-rcf-dag-sel');
1175
+ if (sel) parts.push('entity=' + encodeURIComponent(sel));
1176
+ // Preserve any non-DAG-owned params (Specs filter keys etc.)
1177
+ // through DAG writes. Entity is already written above from the
1178
+ // live selection; do NOT re-append extras.entity.
1179
+ var dagExtras = currentDagHashExtras();
1180
+ if (dagExtras.length > 0) parts = parts.concat(dagExtras);
1181
+ return '#' + parts.join('&');
1182
+ }
1183
+ var state = readBuildFilterState();
1184
+ if (state) {
1185
+ if (state.q) parts.push('q=' + encodeURIComponent(state.q));
1186
+ if (state.status) parts.push('status=' + encodeURIComponent(state.status));
1187
+ if (state.domain) parts.push('domain=' + encodeURIComponent(state.domain));
1188
+ if (state.size) parts.push('size=' + encodeURIComponent(state.size));
1189
+ if (state.buildable) parts.push('buildable=1');
1190
+ }
1191
+ var extras = currentBuildHashExtras();
1192
+ if (extras.entity) parts.push('entity=' + encodeURIComponent(extras.entity));
1193
+ // Decision 11: preserve unknown hash params through filter writes.
1194
+ if (extras.extraParts && extras.extraParts.length > 0) parts = parts.concat(extras.extraParts);
1195
+ return '#' + parts.join('&');
1196
+ }
1197
+
1198
+ function writeBuildHash() {
1199
+ writeHash(buildHashFragment(), true);
1200
+ }
1201
+
1202
+ function applyBuildHash(params) {
1203
+ var sub = params.sub ? decodeURIComponent(params.sub) : 'specs';
1204
+ activateBuildSub(sub);
1205
+ if (sub === 'dag') {
1206
+ var canvas = dagCanvas();
1207
+ var entity = params.entity ? decodeURIComponent(params.entity) : '';
1208
+ if (canvas) {
1209
+ if (entity) {
1210
+ canvas.setAttribute('data-rcf-dag-sel', entity);
1211
+ // AC-204-4: a deep link to an unconnected FBS must land visibly.
1212
+ // Auto-press Show-unconnected so the lane renders and the node
1213
+ // is not display:none when applyDagFilters runs below.
1214
+ var payload = parseDagInspectorPayload();
1215
+ if (payload[entity] && payload[entity].unconnected) {
1216
+ var tunc = document.querySelector('[data-rcf-dag-toggle="unconnected"]');
1217
+ if (tunc && tunc.getAttribute('aria-pressed') !== 'true') tunc.setAttribute('aria-pressed', 'true');
1218
+ }
1219
+ } else {
1220
+ canvas.removeAttribute('data-rcf-dag-sel');
1221
+ }
1222
+ applyDagFilters();
1223
+ renderDagInspector();
1224
+ if (entity) {
1225
+ var el = canvas.querySelector('.rcf-dag-node[data-fbs-id="' + entity + '"]');
1226
+ if (el) { try { el.scrollIntoView({ block: 'center', inline: 'center' }); } catch (e) { el.scrollIntoView(); } }
1227
+ }
1228
+ }
1229
+ return;
1230
+ }
1231
+ var state = {
1232
+ q: params.q ? decodeURIComponent(params.q) : '',
1233
+ status: params.status ? decodeURIComponent(params.status) : '',
1234
+ domain: params.domain ? decodeURIComponent(params.domain) : '',
1235
+ size: params.size ? decodeURIComponent(params.size) : '',
1236
+ buildable: params.buildable === '1' || params.buildable === 'true',
1237
+ };
1238
+ if (buildBar()) {
1239
+ writeBuildFilterState(state);
1240
+ applyBuildFilter();
1241
+ }
1242
+ }
1243
+
1244
+ function expandAllBuildSpecs(open) {
1245
+ var list = buildListNode();
1246
+ if (!list) return;
1247
+ var rows = list.querySelectorAll(':scope > details.rcf-row');
1248
+ for (var i = 0; i < rows.length; i += 1) {
1249
+ if (rows[i].hasAttribute('hidden')) continue;
1250
+ rows[i].open = !!open;
1251
+ }
1252
+ var btn = document.querySelector('[data-rcf-filterbar="build-specs"] .rcf-filter-expand');
1253
+ if (btn) {
1254
+ btn.textContent = open ? 'Collapse all' : 'Expand all';
1255
+ btn.setAttribute('data-expand-state', open ? 'expanded' : 'collapsed');
1256
+ }
1257
+ }
1258
+
1259
+ function wireBuildFilterBar() {
1260
+ var bar = buildBar();
1261
+ if (!bar || bar.__rcfBuildFilterWired) return;
1262
+ bar.__rcfBuildFilterWired = true;
1263
+ var text = bar.querySelector('.rcf-filter-text');
1264
+ if (text) {
1265
+ var debounceTimer = null;
1266
+ text.addEventListener('input', function () {
1267
+ if (debounceTimer) clearTimeout(debounceTimer);
1268
+ debounceTimer = setTimeout(function () {
1269
+ applyBuildFilter();
1270
+ writeBuildHash();
1271
+ }, 150);
1272
+ });
1273
+ }
1274
+ var selects = bar.querySelectorAll('.rcf-filter-select');
1275
+ for (var i = 0; i < selects.length; i += 1) {
1276
+ selects[i].addEventListener('change', function () {
1277
+ applyBuildFilter();
1278
+ writeBuildHash();
1279
+ });
1280
+ }
1281
+ var toggles = bar.querySelectorAll('.rcf-filter-toggle input[type="checkbox"]');
1282
+ for (var j = 0; j < toggles.length; j += 1) {
1283
+ toggles[j].addEventListener('change', function () {
1284
+ applyBuildFilter();
1285
+ writeBuildHash();
1286
+ });
1287
+ }
1288
+ var expandBtn = bar.querySelector('.rcf-filter-expand');
1289
+ if (expandBtn) {
1290
+ expandBtn.addEventListener('click', function (ev) {
1291
+ ev.preventDefault && ev.preventDefault();
1292
+ var isCollapsed = expandBtn.getAttribute('data-expand-state') !== 'expanded';
1293
+ expandAllBuildSpecs(isCollapsed);
1294
+ });
1295
+ }
1296
+ }
1297
+
1298
+ function wireBuildSubTabStrip() {
1299
+ var strip = buildSubTabStrip();
1300
+ if (!strip || strip.__rcfBuildSubWired) return;
1301
+ strip.__rcfBuildSubWired = true;
1302
+ var btns = strip.querySelectorAll('[role="tab"]');
1303
+ for (var i = 0; i < btns.length; i += 1) {
1304
+ btns[i].addEventListener('click', function (ev) {
1305
+ ev.preventDefault && ev.preventDefault();
1306
+ var sub = ev.currentTarget.getAttribute('data-sub');
1307
+ if (!sub) return;
1308
+ activateBuildSub(sub);
1309
+ if (sub === 'dag' && dagCanvas()) {
1310
+ applyDagFilters();
1311
+ renderDagInspector();
1312
+ }
1313
+ writeBuildHash();
1314
+ });
1315
+ }
1316
+ }
1317
+
1318
+ function wireBuildTab() {
1319
+ wireBuildSubTabStrip();
1320
+ wireBuildFilterBar();
1321
+ wireBuildDag();
1322
+ }
1323
+
1324
+ // ---- Build / DAG (viewer UI refresh PR 6, TAC-4131, ADR-4133) --------
1325
+ //
1326
+ // Client-side wiring for the Build/DAG sub-tab. The server emits the
1327
+ // layout (toolbar, canvas with HTML nodes + SVG edges, inspector shell,
1328
+ // unconnected lane) plus an inline <script type="application/json"
1329
+ // data-rcf-dag-inspector-data> payload keyed by fbsId. The client:
1330
+ // - toggles filters (status chips, area, Buildable-now, Critical-path,
1331
+ // Show-unconnected) by setting data attributes on nodes and edges;
1332
+ // - handles click-to-highlight: selects a node, writes
1333
+ // `#tab=build&sub=dag&entity=<id>` through writeHash, outlines its
1334
+ // upstream closure in link colour and downstream in warning;
1335
+ // - fills the inspector from the inline payload (no outbound fetch,
1336
+ // no postMessage), with Open-in-Specs linking to
1337
+ // `#tab=build&sub=specs&entity=<id>` (REQ-002 / US-204 AC-204-7).
1338
+
1339
+ function dagRoot() { return document.querySelector('[data-rcf-dag="build"]'); }
1340
+ function dagCanvas() { return document.querySelector('[data-rcf-dag-canvas]'); }
1341
+ function dagToolbar() { return document.querySelector('[data-rcf-dag-toolbar]'); }
1342
+ function dagInspectorBody() { return document.querySelector('[data-rcf-dag-inspector-body]'); }
1343
+
1344
+ function parseDagInspectorPayload() {
1345
+ // PR 1 contract (standing criterion): payload rides on the inspector
1346
+ // shell as a `data-rcf-dag-inspector-data` attribute, not an inline
1347
+ // `<script>` body.
1348
+ var shell = document.querySelector('[data-rcf-dag-inspector-body]');
1349
+ if (!shell) return {};
1350
+ var raw = shell.getAttribute('data-rcf-dag-inspector-data');
1351
+ if (!raw) return {};
1352
+ try { return JSON.parse(raw); }
1353
+ catch (e) { return {}; }
1354
+ }
1355
+
1356
+ function dagEscape(s) {
1357
+ return String(s == null ? '' : s)
1358
+ .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
1359
+ .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
1360
+ }
1361
+
1362
+ function readDagState() {
1363
+ var state = {
1364
+ statuses: { notStarted: true, inProgress: true, complete: true, verified: true },
1365
+ domain: '',
1366
+ buildable: false,
1367
+ critical: false,
1368
+ unconnected: false,
1369
+ sel: null,
1370
+ };
1371
+ var bar = dagToolbar();
1372
+ if (bar) {
1373
+ var statusChips = bar.querySelectorAll('[data-rcf-dag-status]');
1374
+ for (var i = 0; i < statusChips.length; i += 1) {
1375
+ var k = statusChips[i].getAttribute('data-rcf-dag-status');
1376
+ state.statuses[k] = statusChips[i].getAttribute('aria-pressed') === 'true';
1377
+ }
1378
+ var dom = bar.querySelector('[data-rcf-dag-domain]');
1379
+ if (dom) state.domain = dom.value || '';
1380
+ var tbuild = bar.querySelector('[data-rcf-dag-toggle="buildable"]');
1381
+ if (tbuild) state.buildable = tbuild.getAttribute('aria-pressed') === 'true';
1382
+ var tcrit = bar.querySelector('[data-rcf-dag-toggle="critical"]');
1383
+ if (tcrit) state.critical = tcrit.getAttribute('aria-pressed') === 'true';
1384
+ var tunc = bar.querySelector('[data-rcf-dag-toggle="unconnected"]');
1385
+ if (tunc) state.unconnected = tunc.getAttribute('aria-pressed') === 'true';
1386
+ }
1387
+ var canvas = dagCanvas();
1388
+ if (canvas) state.sel = canvas.getAttribute('data-rcf-dag-sel') || null;
1389
+ return state;
1390
+ }
1391
+
1392
+ function dagClosure(payload, startId, dir) {
1393
+ var out = {};
1394
+ if (!payload[startId]) return out;
1395
+ var stack = (dir === 'up' ? payload[startId].needs : payload[startId].waits).slice();
1396
+ while (stack.length > 0) {
1397
+ var cur = stack.pop();
1398
+ if (out[cur]) continue;
1399
+ out[cur] = true;
1400
+ var p = payload[cur];
1401
+ if (!p) continue;
1402
+ var next = dir === 'up' ? p.needs : p.waits;
1403
+ for (var i = 0; i < next.length; i += 1) stack.push(next[i]);
1404
+ }
1405
+ return out;
1406
+ }
1407
+
1408
+ function applyDagFilters() {
1409
+ var canvas = dagCanvas();
1410
+ if (!canvas) return;
1411
+ var payload = parseDagInspectorPayload();
1412
+ var state = readDagState();
1413
+ if (state.unconnected) canvas.removeAttribute('data-rcf-dag-unconnected-hidden');
1414
+ else canvas.setAttribute('data-rcf-dag-unconnected-hidden', '1');
1415
+
1416
+ var ups = {};
1417
+ var downs = {};
1418
+ if (state.sel && payload[state.sel]) {
1419
+ ups = dagClosure(payload, state.sel, 'up');
1420
+ downs = dagClosure(payload, state.sel, 'down');
1421
+ }
1422
+ if (state.sel) canvas.setAttribute('data-rcf-dag-sel', state.sel);
1423
+ else canvas.removeAttribute('data-rcf-dag-sel');
1424
+
1425
+ var nodes = canvas.querySelectorAll('.rcf-dag-node');
1426
+ for (var i = 0; i < nodes.length; i += 1) {
1427
+ var el = nodes[i];
1428
+ var id = el.getAttribute('data-fbs-id');
1429
+ var status = el.getAttribute('data-status') || '';
1430
+ var domain = el.getAttribute('data-domain') || '';
1431
+ var buildable = el.getAttribute('data-buildable') === '1';
1432
+ var critical = el.getAttribute('data-critical') === '1';
1433
+ var unconnected = el.getAttribute('data-unconnected') === '1';
1434
+ var hide = false;
1435
+ if (state.statuses[status] === false) hide = true;
1436
+ if (!hide && state.domain && domain !== state.domain) hide = true;
1437
+ if (!hide && state.buildable && !buildable) hide = true;
1438
+ if (!hide && state.critical && !critical) hide = true;
1439
+ if (unconnected && !state.unconnected) hide = true;
1440
+ if (hide) el.setAttribute('data-rcf-dag-hidden', '1');
1441
+ else el.removeAttribute('data-rcf-dag-hidden');
1442
+ var role = '';
1443
+ if (state.sel) {
1444
+ if (id === state.sel) role = 'sel';
1445
+ else if (ups[id]) role = 'up';
1446
+ else if (downs[id]) role = 'down';
1447
+ }
1448
+ if (role) el.setAttribute('data-rcf-dag-role', role);
1449
+ else el.removeAttribute('data-rcf-dag-role');
1450
+ if (state.critical && critical) el.setAttribute('data-rcf-dag-critical', 'on');
1451
+ else el.removeAttribute('data-rcf-dag-critical');
1452
+ }
1453
+
1454
+ var edges = canvas.querySelectorAll('[data-rcf-dag-edge]');
1455
+ for (var j = 0; j < edges.length; j += 1) {
1456
+ var ed = edges[j];
1457
+ var from = ed.getAttribute('data-from');
1458
+ var to = ed.getAttribute('data-to');
1459
+ var fromNode = canvas.querySelector('.rcf-dag-node[data-fbs-id="' + from + '"]');
1460
+ var toNode = canvas.querySelector('.rcf-dag-node[data-fbs-id="' + to + '"]');
1461
+ var filtered = (fromNode && fromNode.getAttribute('data-rcf-dag-hidden') === '1')
1462
+ || (toNode && toNode.getAttribute('data-rcf-dag-hidden') === '1');
1463
+ if (filtered) ed.setAttribute('data-rcf-dag-hidden', '1');
1464
+ else ed.removeAttribute('data-rcf-dag-hidden');
1465
+ var erole = '';
1466
+ if (state.sel) {
1467
+ var fromUp = from === state.sel || ups[from];
1468
+ var toUp = to === state.sel || ups[to];
1469
+ var fromDown = from === state.sel || downs[from];
1470
+ var toDown = to === state.sel || downs[to];
1471
+ if (fromUp && toUp) erole = 'up';
1472
+ else if (fromDown && toDown) erole = 'down';
1473
+ }
1474
+ if (erole) ed.setAttribute('data-rcf-dag-edge-role', erole);
1475
+ else ed.removeAttribute('data-rcf-dag-edge-role');
1476
+ }
1477
+ }
1478
+
1479
+ function renderDagInspector() {
1480
+ var body = dagInspectorBody();
1481
+ if (!body) return;
1482
+ var payload = parseDagInspectorPayload();
1483
+ var state = readDagState();
1484
+ if (!state.sel || !payload[state.sel]) {
1485
+ body.innerHTML = '<div class="muted small">Select a build spec to see what it needs and what waits on it.</div>';
1486
+ return;
1487
+ }
1488
+ var f = payload[state.sel];
1489
+ var meta = '<div class="rcf-dag-inspector-meta">'
1490
+ + '<span class="rcf-pill rcf-pill--doc-status rcf-pill--' + dagEscape((f.status || '').toLowerCase()) + '">' + dagEscape(f.status || 'unknown') + '</span>'
1491
+ + (f.domain ? '<span class="rcf-badge rcf-badge--facet">' + dagEscape(f.domain) + '</span>' : '')
1492
+ + '<span class="rcf-badge rcf-badge--count">AC ' + (f.acCount || 0) + '</span>'
1493
+ + (f.size ? '<span class="rcf-badge rcf-badge--facet">' + dagEscape(f.size) + '</span>' : '')
1494
+ + '<span class="rcf-badge rcf-badge--count">order ' + (f.buildOrder != null ? f.buildOrder : '') + '</span>'
1495
+ + (f.buildable ? '<span class="rcf-pill rcf-pill--build-queue">buildable now</span>' : '')
1496
+ + (f.critical ? '<span class="rcf-pill rcf-pill--doc-status">critical path</span>' : '')
1497
+ + '</div>';
1498
+ var needsItems = (f.needsMeta || []).map(function (m) {
1499
+ return '<li><a class="mono" href="#" data-rcf-dag-go="' + dagEscape(m.id) + '">' + dagEscape(m.id) + '</a> <span>' + dagEscape(m.title) + '</span> <span class="rcf-pill rcf-pill--doc-status rcf-pill--' + dagEscape((m.status || '').toLowerCase()) + '">' + dagEscape(m.status || '?') + '</span></li>';
1500
+ }).join('');
1501
+ var needsBlock = '<h4>Needs first (' + (f.needs ? f.needs.length : 0) + ' direct, ' + (f.needsTotal || 0) + ' in total)</h4>'
1502
+ + (needsItems ? '<ul class="rcf-dag-inspector-list">' + needsItems + '</ul>' : '<div class="muted small">Nothing.</div>');
1503
+ var waitsItems = (f.waitsMeta || []).map(function (m) {
1504
+ return '<li><a class="mono" href="#" data-rcf-dag-go="' + dagEscape(m.id) + '">' + dagEscape(m.id) + '</a> <span>' + dagEscape(m.title) + '</span></li>';
1505
+ }).join('');
1506
+ var waitsBlock = '<h4>Waits on this (' + (f.waits ? f.waits.length : 0) + ' direct, ' + (f.waitsTotal || 0) + ' in total)</h4>'
1507
+ + (waitsItems ? '<ul class="rcf-dag-inspector-list">' + waitsItems + '</ul>' : '<div class="muted small">Nothing.</div>');
1508
+ var footer = '<p class="small" style="margin-top:0.8rem"><a href="#tab=build&sub=specs&entity=' + dagEscape(f.id) + '" data-rcf-dag-open-specs>Open in Specs</a> &middot; <a href="#" data-rcf-dag-go="" class="muted">Clear selection</a></p>';
1509
+ body.innerHTML = '<div class="mono small" style="color:var(--sv-link)">' + dagEscape(f.id) + '</div>'
1510
+ + '<h3>' + dagEscape(f.title) + '</h3>'
1511
+ + meta
1512
+ + needsBlock
1513
+ + waitsBlock
1514
+ + footer;
1515
+
1516
+ var goLinks = body.querySelectorAll('[data-rcf-dag-go]');
1517
+ for (var i = 0; i < goLinks.length; i += 1) {
1518
+ goLinks[i].addEventListener('click', function (ev) {
1519
+ ev.preventDefault && ev.preventDefault();
1520
+ var next = ev.currentTarget.getAttribute('data-rcf-dag-go');
1521
+ if (!next) selectDagNode(null);
1522
+ else selectDagNode(next);
1523
+ });
1524
+ }
1525
+ var specsLink = body.querySelector('[data-rcf-dag-open-specs]');
1526
+ if (specsLink) {
1527
+ specsLink.addEventListener('click', function (ev) {
1528
+ ev.preventDefault && ev.preventDefault();
1529
+ var href = ev.currentTarget.getAttribute('href') || '';
1530
+ writeHash(href, false);
1531
+ resolveHash(window.location.hash);
1532
+ });
1533
+ }
1534
+ }
1535
+
1536
+ function selectDagNode(id) {
1537
+ var canvas = dagCanvas();
1538
+ if (!canvas) return;
1539
+ var cur = canvas.getAttribute('data-rcf-dag-sel') || null;
1540
+ var payload = parseDagInspectorPayload();
1541
+ var next = id === cur ? null : id;
1542
+ if (next && !payload[next]) next = null;
1543
+ if (next) canvas.setAttribute('data-rcf-dag-sel', next);
1544
+ else canvas.removeAttribute('data-rcf-dag-sel');
1545
+ if (next && payload[next] && payload[next].unconnected) {
1546
+ var tunc = document.querySelector('[data-rcf-dag-toggle="unconnected"]');
1547
+ if (tunc && tunc.getAttribute('aria-pressed') !== 'true') tunc.setAttribute('aria-pressed', 'true');
1548
+ }
1549
+ applyDagFilters();
1550
+ renderDagInspector();
1551
+ writeBuildHash();
1552
+ if (next) {
1553
+ var el = canvas.querySelector('.rcf-dag-node[data-fbs-id="' + next + '"]');
1554
+ if (el) { try { el.scrollIntoView({ block: 'center', inline: 'center' }); } catch (e) { el.scrollIntoView(); } }
1555
+ }
1556
+ }
1557
+
1558
+ function wireBuildDag() {
1559
+ var root = dagRoot();
1560
+ if (!root || root.__rcfBuildDagWired) return;
1561
+ root.__rcfBuildDagWired = true;
1562
+ var canvas = dagCanvas();
1563
+ if (canvas) {
1564
+ var nodes = canvas.querySelectorAll('.rcf-dag-node');
1565
+ for (var i = 0; i < nodes.length; i += 1) {
1566
+ nodes[i].addEventListener('click', function (ev) {
1567
+ ev.preventDefault && ev.preventDefault();
1568
+ var id = ev.currentTarget.getAttribute('data-fbs-id');
1569
+ if (id) selectDagNode(id);
1570
+ });
1571
+ }
1572
+ }
1573
+ var bar = dagToolbar();
1574
+ if (bar) {
1575
+ var statusChips = bar.querySelectorAll('[data-rcf-dag-status]');
1576
+ for (var j = 0; j < statusChips.length; j += 1) {
1577
+ statusChips[j].addEventListener('click', function (ev) {
1578
+ var btn = ev.currentTarget;
1579
+ btn.setAttribute('aria-pressed', btn.getAttribute('aria-pressed') === 'true' ? 'false' : 'true');
1580
+ applyDagFilters();
1581
+ });
1582
+ }
1583
+ var dom = bar.querySelector('[data-rcf-dag-domain]');
1584
+ if (dom) dom.addEventListener('change', function () { applyDagFilters(); });
1585
+ var toggles = bar.querySelectorAll('[data-rcf-dag-toggle]');
1586
+ for (var k = 0; k < toggles.length; k += 1) {
1587
+ toggles[k].addEventListener('click', function (ev) {
1588
+ var btn = ev.currentTarget;
1589
+ btn.setAttribute('aria-pressed', btn.getAttribute('aria-pressed') === 'true' ? 'false' : 'true');
1590
+ applyDagFilters();
1591
+ });
1592
+ }
1593
+ }
1594
+ applyDagFilters();
1595
+ renderDagInspector();
1596
+ }
1597
+
1598
+ // ---- EntitySelector (viewer UI refresh PR 3, decision 4) -----
1599
+
1600
+ function parseEntitySelectorPayload(root) {
1601
+ // Payload rides on the container as a `data-items` attribute so
1602
+ // the shell carries no inline <script> body (PR 1 contract).
1603
+ var raw = root.getAttribute('data-items');
1604
+ if (!raw) return [];
1605
+ try { return JSON.parse(raw); }
1606
+ catch (e) { return []; }
1607
+ }
1608
+
1609
+ function wireEntitySelector(root) {
1610
+ if (!root || root.__rcfEntitySelectorWired) return;
1611
+ root.__rcfEntitySelectorWired = true;
1612
+ var input = root.querySelector('.rcf-entity-selector-input');
1613
+ var results = root.querySelector('.rcf-entity-selector-results');
1614
+ var targetTab = root.getAttribute('data-target-tab') || 'requirements';
1615
+ var items = parseEntitySelectorPayload(root);
1616
+ if (!input || !results || items.length === 0) return;
1617
+
1618
+ function escapeHtml(s) {
1619
+ return String(s == null ? '' : s)
1620
+ .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
1621
+ .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
1622
+ }
1623
+
1624
+ function render(matches) {
1625
+ if (matches.length === 0) {
1626
+ results.innerHTML = '<div class="rcf-entity-selector-empty muted small">No match.</div>';
1627
+ results.removeAttribute('hidden');
1628
+ return;
1629
+ }
1630
+ var html = '';
1631
+ for (var i = 0; i < matches.length; i += 1) {
1632
+ var m = matches[i];
1633
+ var hash = '#tab=' + encodeURIComponent(targetTab) + '&entity=' + encodeURIComponent(m.id);
1634
+ html += '<a class="rcf-entity-selector-result" href="' + escapeHtml(hash) + '" role="option" data-entity-id="' + escapeHtml(m.id) + '">'
1635
+ + '<span class="rcf-entity-selector-result-id">' + escapeHtml(m.id) + '</span>'
1636
+ + '<span class="rcf-entity-selector-result-title">' + escapeHtml(m.title) + '</span>'
1637
+ + (m.facet ? '<span class="rcf-entity-selector-result-facet">' + escapeHtml(m.facet) + '</span>' : '')
1638
+ + '</a>';
1639
+ }
1640
+ results.innerHTML = html;
1641
+ results.removeAttribute('hidden');
1642
+ }
1643
+
1644
+ function run() {
1645
+ var q = (input.value || '').trim().toLowerCase();
1646
+ if (!q) { results.innerHTML = ''; results.setAttribute('hidden', ''); return; }
1647
+ var out = [];
1648
+ for (var i = 0; i < items.length && out.length < 12; i += 1) {
1649
+ var it = items[i];
1650
+ var idL = (it.id || '').toLowerCase();
1651
+ var tL = (it.title || '').toLowerCase();
1652
+ if (idL.indexOf(q) === 0 || tL.indexOf(q) !== -1) out.push(it);
1653
+ }
1654
+ render(out);
1655
+ }
1656
+
1657
+ input.addEventListener('input', run);
1658
+ input.addEventListener('focus', function () { if (input.value.trim()) run(); });
1659
+ input.addEventListener('blur', function () {
1660
+ setTimeout(function () { results.setAttribute('hidden', ''); }, 150);
1661
+ });
1662
+ input.addEventListener('keydown', function (ev) {
1663
+ if (ev.key !== 'Enter') return;
1664
+ var first = results.querySelector('.rcf-entity-selector-result');
1665
+ if (!first) return;
1666
+ ev.preventDefault && ev.preventDefault();
1667
+ // Navigate via the Router: writes to hash so #entity=... resolves.
1668
+ var href = first.getAttribute('href');
1669
+ if (href) {
1670
+ writeHash(href, false);
1671
+ resolveHash(window.location.hash);
1672
+ }
1673
+ });
1674
+ }
1675
+
1676
+ function wireEntitySelectors() {
1677
+ var selectors = document.querySelectorAll('[data-rcf-entity-selector]');
1678
+ for (var i = 0; i < selectors.length; i += 1) wireEntitySelector(selectors[i]);
1679
+ }
1680
+
1681
+ // ---- ID lookup (viewer UI refresh PR 7, TAC-4132) --------------------
1682
+ //
1683
+ // SearchButton + LookupModal + Cmd/Ctrl+F. The index at `./index.json`
1684
+ // is fetched lazily on first open; the SSE tree-update broadcast sets
1685
+ // __rcfLookupDirty so the next open refetches. Rank order (design
1686
+ // doc section 6): a single character searches ids only; otherwise ids
1687
+ // rank first (exact > prefix > contains), then every query word must
1688
+ // match title or snippet, title above snippet; 20 results; matches
1689
+ // marked. A pick writes `#tab=<tab>&entity=<id>` through writeHash so
1690
+ // `?embed=` and `?theme=` survive (Dex contract, PR 1).
1691
+
1692
+ var lookupRows = null;
1693
+ var lookupFetching = false;
1694
+ var lookupLastQuery = null;
1695
+ var lookupResults = [];
1696
+ var lookupActiveIdx = -1;
1697
+ var lookupPrevFocus = null;
1698
+ var lookupLoadError = false;
1699
+ var lookupKeybindWired = false;
1700
+
1701
+ function lookupModal() { return document.querySelector('[data-rcf-lookup]'); }
1702
+ function lookupInput() { return document.querySelector('[data-rcf-lookup-input]'); }
1703
+ function lookupResultsList() { return document.querySelector('[data-rcf-lookup-results]'); }
1704
+ function lookupEmpty() { return document.querySelector('[data-rcf-lookup-empty]'); }
1705
+ function lookupEmptyMsg() { return document.querySelector('[data-rcf-lookup-empty-msg]'); }
1706
+ function lookupReload() { return document.querySelector('[data-rcf-lookup-reload]'); }
1707
+ function lookupStatus() { return document.querySelector('[data-rcf-lookup-status]'); }
1708
+
1709
+ function lookupEscapeHtml(s) {
1710
+ if (typeof s !== 'string') return '';
1711
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1712
+ }
1713
+
1714
+ function lookupMarkMatches(text, needles) {
1715
+ if (!text) return '';
1716
+ var lower = text.toLowerCase();
1717
+ var marks = [];
1718
+ for (var i = 0; i < needles.length; i += 1) {
1719
+ var n = needles[i];
1720
+ if (!n) continue;
1721
+ var from = 0;
1722
+ while (from <= lower.length) {
1723
+ var at = lower.indexOf(n, from);
1724
+ if (at === -1) break;
1725
+ marks.push([at, at + n.length]);
1726
+ from = at + n.length;
1727
+ }
1728
+ }
1729
+ if (marks.length === 0) return lookupEscapeHtml(text);
1730
+ marks.sort(function (a, b) { return a[0] - b[0]; });
1731
+ var merged = [];
1732
+ for (var j = 0; j < marks.length; j += 1) {
1733
+ var last = merged[merged.length - 1];
1734
+ if (last && marks[j][0] <= last[1]) last[1] = Math.max(last[1], marks[j][1]);
1735
+ else merged.push(marks[j].slice());
1736
+ }
1737
+ var out = '';
1738
+ var cursor = 0;
1739
+ for (var k = 0; k < merged.length; k += 1) {
1740
+ var start = merged[k][0];
1741
+ var end = merged[k][1];
1742
+ if (cursor < start) out += lookupEscapeHtml(text.slice(cursor, start));
1743
+ out += '<mark>' + lookupEscapeHtml(text.slice(start, end)) + '</mark>';
1744
+ cursor = end;
1745
+ }
1746
+ if (cursor < text.length) out += lookupEscapeHtml(text.slice(cursor));
1747
+ return out;
1748
+ }
1749
+
1750
+ function lookupRank(query, rows) {
1751
+ if (!query || !rows) return [];
1752
+ var q = String(query).trim().toLowerCase();
1753
+ if (!q) return [];
1754
+ var scored = [];
1755
+ // Single-character query: id-only match (design doc section 6).
1756
+ if (q.length === 1) {
1757
+ for (var i = 0; i < rows.length; i += 1) {
1758
+ var r = rows[i];
1759
+ var idLow = (r.id || '').toLowerCase();
1760
+ if (idLow.indexOf(q) !== -1) {
1761
+ var score = 0;
1762
+ if (idLow === q) score = 1000;
1763
+ else if (idLow.indexOf(q) === 0) score = 500;
1764
+ else score = 100;
1765
+ scored.push({ row: r, score: score, needles: [q] });
1766
+ }
1767
+ }
1768
+ } else {
1769
+ var words = q.split(/\s+/).filter(Boolean);
1770
+ for (var i2 = 0; i2 < rows.length; i2 += 1) {
1771
+ var r2 = rows[i2];
1772
+ var idLow2 = (r2.id || '').toLowerCase();
1773
+ var titleLow = (r2.title || '').toLowerCase();
1774
+ var snipLow = (r2.snippet || '').toLowerCase();
1775
+ var score2 = 0;
1776
+ // Id first: exact / prefix / contains against the full query.
1777
+ if (idLow2 === q) score2 = 10000;
1778
+ else if (idLow2.indexOf(q) === 0) score2 = 5000;
1779
+ else if (idLow2.indexOf(q) !== -1) score2 = 2500;
1780
+ else {
1781
+ // Word-match pass: every word must hit title or snippet.
1782
+ var titleHits = 0;
1783
+ var snipHits = 0;
1784
+ var allHit = true;
1785
+ for (var w = 0; w < words.length; w += 1) {
1786
+ var word = words[w];
1787
+ var inTitle = titleLow.indexOf(word) !== -1;
1788
+ var inSnip = snipLow.indexOf(word) !== -1;
1789
+ if (inTitle) titleHits += 1;
1790
+ else if (inSnip) snipHits += 1;
1791
+ else { allHit = false; break; }
1792
+ }
1793
+ if (!allHit) continue;
1794
+ // Title above snippet: title hits weighted higher than snippet.
1795
+ score2 = 1000 + titleHits * 50 + snipHits * 10;
1796
+ }
1797
+ if (score2 > 0) scored.push({ row: r2, score: score2, needles: words });
1798
+ }
1799
+ }
1800
+ scored.sort(function (a, b) {
1801
+ if (b.score !== a.score) return b.score - a.score;
1802
+ return (a.row.id || '').localeCompare(b.row.id || '');
1803
+ });
1804
+ return scored.slice(0, 20);
1805
+ }
1806
+
1807
+ function lookupKindLabel(kind) {
1808
+ switch (kind) {
1809
+ case 'prd': return 'PRD';
1810
+ case 'req': return 'REQ';
1811
+ case 'us': return 'US';
1812
+ case 'ac': return 'AC';
1813
+ case 'tad': return 'TAD';
1814
+ case 'tac': return 'TAC';
1815
+ case 'adr': return 'ADR';
1816
+ case 'bs': return 'BS';
1817
+ case 'fbs': return 'FBS';
1818
+ case 'ts': return 'TS';
1819
+ default: return kind || '';
1820
+ }
1821
+ }
1822
+
1823
+ function lookupRenderResults(results) {
1824
+ var list = lookupResultsList();
1825
+ var empty = lookupEmpty();
1826
+ var emptyMsg = lookupEmptyMsg();
1827
+ var reload = lookupReload();
1828
+ var status = lookupStatus();
1829
+ if (!list) return;
1830
+ if (results.length === 0) {
1831
+ list.innerHTML = '';
1832
+ list.hidden = true;
1833
+ var hasQuery = (lookupLastQuery || '').trim().length > 0;
1834
+ if (empty) empty.hidden = !lookupLoadError && !hasQuery;
1835
+ if (emptyMsg) emptyMsg.textContent = lookupLoadError ? 'The index could not be loaded.' : 'No matches.';
1836
+ if (reload) reload.hidden = !lookupLoadError;
1837
+ if (status) {
1838
+ if (lookupLoadError) status.textContent = 'Index failed to load.';
1839
+ else if (hasQuery) status.textContent = 'No matches.';
1840
+ else status.textContent = (lookupRows ? 'Type an id or a few words.' : 'Loading index...');
1841
+ }
1842
+ return;
1843
+ }
1844
+ if (empty) empty.hidden = true;
1845
+ if (reload) reload.hidden = true;
1846
+ list.hidden = false;
1847
+ var html = '';
1848
+ for (var i = 0; i < results.length; i += 1) {
1849
+ var scored = results[i];
1850
+ var r = scored.row;
1851
+ var needles = scored.needles || [];
1852
+ var active = i === lookupActiveIdx ? ' is-active' : '';
1853
+ var markedId = lookupMarkMatches(r.id || '', needles);
1854
+ var markedTitle = lookupMarkMatches(r.title || '', needles);
1855
+ var markedSnip = lookupMarkMatches(r.snippet || '', needles);
1856
+ var parentHtml = r.parent ? ' <span class="rcf-lookup-parent">in ' + lookupEscapeHtml(r.parent) + '</span>' : '';
1857
+ html += '<li class="rcf-lookup-row' + active + '" role="option"'
1858
+ + (i === lookupActiveIdx ? ' aria-selected="true"' : '')
1859
+ + ' data-rcf-lookup-row data-rcf-lookup-id="' + lookupEscapeHtml(r.id || '')
1860
+ + '" data-rcf-lookup-tab="' + lookupEscapeHtml(r.tab || '')
1861
+ + '" data-rcf-lookup-kind="' + lookupEscapeHtml(r.kind || '')
1862
+ + '" data-rcf-lookup-parent="' + lookupEscapeHtml(r.parent || '') + '" data-rcf-lookup-idx="' + i + '">'
1863
+ + '<span class="rcf-lookup-kind rcf-lookup-kind-' + lookupEscapeHtml(r.kind || '') + '">' + lookupKindLabel(r.kind) + '</span>'
1864
+ + '<span class="rcf-lookup-id">' + markedId + '</span>'
1865
+ + (r.title ? '<span class="rcf-lookup-title">' + markedTitle + '</span>' : '')
1866
+ + parentHtml
1867
+ + (r.snippet ? '<p class="rcf-lookup-snippet">' + markedSnip + '</p>' : '')
1868
+ + '</li>';
1869
+ }
1870
+ list.innerHTML = html;
1871
+ if (status) status.textContent = results.length + ' result' + (results.length === 1 ? '' : 's') + '.';
1872
+ }
1873
+
1874
+ function lookupRun() {
1875
+ var input = lookupInput();
1876
+ if (!input) return;
1877
+ var query = input.value || '';
1878
+ lookupLastQuery = query;
1879
+ if (!lookupRows) {
1880
+ lookupResults = [];
1881
+ lookupActiveIdx = -1;
1882
+ var list = lookupResultsList();
1883
+ if (list) { list.innerHTML = ''; list.hidden = true; }
1884
+ var empty = lookupEmpty();
1885
+ var emptyMsg = lookupEmptyMsg();
1886
+ var reload = lookupReload();
1887
+ if (empty) empty.hidden = false;
1888
+ if (emptyMsg) emptyMsg.textContent = lookupLoadError ? 'The index could not be loaded.' : (lookupFetching ? 'Loading index...' : 'Index not loaded.');
1889
+ if (reload) reload.hidden = !lookupLoadError;
1890
+ return;
1891
+ }
1892
+ lookupResults = lookupRank(query, lookupRows);
1893
+ lookupActiveIdx = lookupResults.length > 0 ? 0 : -1;
1894
+ lookupRenderResults(lookupResults);
1895
+ }
1896
+
1897
+ function lookupLoad(force) {
1898
+ if (lookupFetching) return;
1899
+ if (lookupRows && !force && !window.__rcfLookupDirty) { lookupRun(); return; }
1900
+ lookupFetching = true;
1901
+ lookupLoadError = false;
1902
+ var status = lookupStatus();
1903
+ if (status) status.textContent = 'Loading index...';
1904
+ var xhr = new XMLHttpRequest();
1905
+ xhr.open('GET', './index.json', true);
1906
+ xhr.onreadystatechange = function () {
1907
+ if (xhr.readyState !== 4) return;
1908
+ lookupFetching = false;
1909
+ var ok = xhr.status >= 200 && xhr.status < 300;
1910
+ var parsed = null;
1911
+ if (ok) {
1912
+ try { parsed = JSON.parse(xhr.responseText); } catch (e) { parsed = null; }
1913
+ }
1914
+ if (!ok || !parsed || !Array.isArray(parsed.rows)) {
1915
+ lookupLoadError = true;
1916
+ lookupRows = null;
1917
+ lookupRun();
1918
+ return;
1919
+ }
1920
+ lookupLoadError = false;
1921
+ lookupRows = parsed.rows;
1922
+ window.__rcfLookupDirty = false;
1923
+ lookupRun();
1924
+ };
1925
+ try { xhr.send(); } catch (e) { lookupFetching = false; lookupLoadError = true; lookupRun(); }
1926
+ }
1927
+
1928
+ function lookupOpen() {
1929
+ var modal = lookupModal();
1930
+ if (!modal) return;
1931
+ if (modal.hidden === false) return;
1932
+ lookupPrevFocus = document.activeElement;
1933
+ modal.hidden = false;
1934
+ document.documentElement.setAttribute('data-rcf-lookup-open', '1');
1935
+ var input = lookupInput();
1936
+ if (input) {
1937
+ input.value = '';
1938
+ try { input.focus(); } catch (e) { /* soft */ }
1939
+ }
1940
+ lookupLastQuery = '';
1941
+ lookupResults = [];
1942
+ lookupActiveIdx = -1;
1943
+ var list = lookupResultsList();
1944
+ if (list) { list.innerHTML = ''; list.hidden = true; }
1945
+ var empty = lookupEmpty();
1946
+ if (empty) empty.hidden = true;
1947
+ lookupLoad(false);
1948
+ }
1949
+
1950
+ function lookupClose() {
1951
+ var modal = lookupModal();
1952
+ if (!modal || modal.hidden) return;
1953
+ modal.hidden = true;
1954
+ document.documentElement.removeAttribute('data-rcf-lookup-open');
1955
+ if (lookupPrevFocus && typeof lookupPrevFocus.focus === 'function') {
1956
+ try { lookupPrevFocus.focus(); } catch (e) { /* soft */ }
1957
+ }
1958
+ lookupPrevFocus = null;
1959
+ }
1960
+
1961
+ function lookupMove(delta) {
1962
+ if (lookupResults.length === 0) return;
1963
+ var next = lookupActiveIdx + delta;
1964
+ if (next < 0) next = lookupResults.length - 1;
1965
+ else if (next >= lookupResults.length) next = 0;
1966
+ lookupActiveIdx = next;
1967
+ lookupRenderResults(lookupResults);
1968
+ var row = document.querySelector('[data-rcf-lookup-row][data-rcf-lookup-idx="' + next + '"]');
1969
+ if (row && typeof row.scrollIntoView === 'function') {
1970
+ try { row.scrollIntoView({ block: 'nearest' }); } catch (e) { /* soft */ }
1971
+ }
1972
+ }
1973
+
1974
+ function lookupPick(row) {
1975
+ if (!row) return;
1976
+ var id = row.getAttribute('data-rcf-lookup-id');
1977
+ var tab = row.getAttribute('data-rcf-lookup-tab');
1978
+ if (!id || !tab) return;
1979
+ // Design decision 6: test suites render inside their owning US (not
1980
+ // a Build sub-tab). A TS pick re-routes to the US id so the Router
1981
+ // opens the US and the TS card inside it (viewer stream carry).
1982
+ var kind = row.getAttribute('data-rcf-lookup-kind');
1983
+ var parentId = row.getAttribute('data-rcf-lookup-parent');
1984
+ if (kind === 'ts' && parentId) { id = parentId; tab = 'requirements'; }
1985
+ lookupClose();
1986
+ // writeHash preserves ?embed=/?theme=/... (Dex contract, PR 1); the
1987
+ // Router's hashchange listener then activates the tab and opens
1988
+ // every ancestor DocRow (resolveHash).
1989
+ writeHash('#tab=' + encodeURIComponent(tab) + '&entity=' + encodeURIComponent(id), false);
1990
+ // If the hash was already the same (user picked the current entity
1991
+ // again), writeHash is a no-op and no hashchange fires. Re-resolve
1992
+ // to re-flash the target in that case.
1993
+ resolveHash(window.location.hash);
1994
+ }
1995
+
1996
+ function lookupOnKeydown(ev) {
1997
+ if (ev.key === 'Escape') {
1998
+ ev.preventDefault && ev.preventDefault();
1999
+ lookupClose();
2000
+ return;
2001
+ }
2002
+ if (ev.key === 'ArrowDown') {
2003
+ ev.preventDefault && ev.preventDefault();
2004
+ lookupMove(1);
2005
+ return;
2006
+ }
2007
+ if (ev.key === 'ArrowUp') {
2008
+ ev.preventDefault && ev.preventDefault();
2009
+ lookupMove(-1);
2010
+ return;
2011
+ }
2012
+ if (ev.key === 'Enter') {
2013
+ ev.preventDefault && ev.preventDefault();
2014
+ if (lookupActiveIdx < 0 || lookupActiveIdx >= lookupResults.length) return;
2015
+ var row = document.querySelector('[data-rcf-lookup-row][data-rcf-lookup-idx="' + lookupActiveIdx + '"]');
2016
+ lookupPick(row);
2017
+ }
2018
+ }
2019
+
2020
+ function lookupOnInput() {
2021
+ lookupRun();
2022
+ }
2023
+
2024
+ // Readiness StageLegend (viewer UI refresh PR 8). Any element carrying
2025
+ // `data-rcf-stage-ref="Dn"` opens the stage legend dialog focused on
2026
+ // that row. The dialog is server-rendered (readiness/stage-legend.js);
2027
+ // this wiring is purely a click + <dialog>.showModal() delegation.
2028
+ var stageLegendWired = false;
2029
+ function wireStageLegend() {
2030
+ if (stageLegendWired) return;
2031
+ stageLegendWired = true;
2032
+ document.addEventListener('click', function (ev) {
2033
+ var el = ev.target;
2034
+ while (el && el !== document.body) {
2035
+ if (el.getAttribute && el.getAttribute('data-rcf-stage-ref') !== null) {
2036
+ var stage = el.getAttribute('data-rcf-stage-ref');
2037
+ var dialog = document.getElementById('rcf-stage-legend');
2038
+ if (!dialog) return;
2039
+ var rows = dialog.querySelectorAll('tr[data-stage]');
2040
+ for (var i = 0; i < rows.length; i += 1) {
2041
+ if (rows[i].getAttribute('data-stage') === stage) {
2042
+ rows[i].classList.add('rcf-stage-legend__highlighted');
2043
+ } else {
2044
+ rows[i].classList.remove('rcf-stage-legend__highlighted');
2045
+ }
2046
+ }
2047
+ if (typeof dialog.showModal === 'function' && !dialog.open) {
2048
+ ev.preventDefault && ev.preventDefault();
2049
+ dialog.showModal();
2050
+ } else if (!dialog.open) {
2051
+ ev.preventDefault && ev.preventDefault();
2052
+ dialog.setAttribute('open', '');
2053
+ }
2054
+ return;
2055
+ }
2056
+ el = el.parentNode;
2057
+ }
2058
+ });
2059
+ }
2060
+
2061
+ function wireLookup() {
2062
+ var modal = lookupModal();
2063
+ if (modal && !modal.__rcfLookupWired) {
2064
+ modal.__rcfLookupWired = true;
2065
+ var input = lookupInput();
2066
+ if (input) {
2067
+ input.addEventListener('input', lookupOnInput);
2068
+ input.addEventListener('keydown', lookupOnKeydown);
2069
+ }
2070
+ var closeBtn = document.querySelector('[data-rcf-lookup-close]');
2071
+ if (closeBtn) closeBtn.addEventListener('click', function (ev) { ev.preventDefault && ev.preventDefault(); lookupClose(); });
2072
+ var backdrop = document.querySelector('[data-rcf-lookup-backdrop]');
2073
+ if (backdrop) backdrop.addEventListener('click', function () { lookupClose(); });
2074
+ var reload = lookupReload();
2075
+ if (reload) reload.addEventListener('click', function (ev) { ev.preventDefault && ev.preventDefault(); lookupLoad(true); });
2076
+ var list = lookupResultsList();
2077
+ if (list) {
2078
+ list.addEventListener('click', function (ev) {
2079
+ var el = ev.target;
2080
+ while (el && el !== list) {
2081
+ if (el.getAttribute && el.getAttribute('data-rcf-lookup-row') !== null) {
2082
+ ev.preventDefault && ev.preventDefault();
2083
+ lookupPick(el);
2084
+ return;
2085
+ }
2086
+ el = el.parentNode;
2087
+ }
2088
+ });
2089
+ list.addEventListener('mousemove', function (ev) {
2090
+ var el = ev.target;
2091
+ while (el && el !== list) {
2092
+ if (el.getAttribute && el.getAttribute('data-rcf-lookup-idx') !== null) {
2093
+ var idx = Number(el.getAttribute('data-rcf-lookup-idx'));
2094
+ if (!Number.isNaN(idx) && idx !== lookupActiveIdx) {
2095
+ lookupActiveIdx = idx;
2096
+ lookupRenderResults(lookupResults);
2097
+ }
2098
+ return;
2099
+ }
2100
+ el = el.parentNode;
2101
+ }
2102
+ });
2103
+ }
2104
+ }
2105
+ var btn = document.querySelector('[data-rcf-search]');
2106
+ if (btn && !btn.__rcfLookupWired) {
2107
+ btn.__rcfLookupWired = true;
2108
+ btn.addEventListener('click', function (ev) { ev.preventDefault && ev.preventDefault(); lookupOpen(); });
2109
+ }
2110
+ if (!lookupKeybindWired) {
2111
+ lookupKeybindWired = true;
2112
+ // Cmd/Ctrl+F opens the modal; Cmd/Ctrl+Shift+F stays the browser's
2113
+ // in-page find (design doc section 11 recommendation 1).
2114
+ document.addEventListener('keydown', function (ev) {
2115
+ var mod = ev.ctrlKey || ev.metaKey;
2116
+ if (!mod) return;
2117
+ if (ev.shiftKey) return;
2118
+ if ((ev.key === 'f' || ev.key === 'F')) {
2119
+ ev.preventDefault && ev.preventDefault();
2120
+ var modalEl = lookupModal();
2121
+ if (modalEl && modalEl.hidden === false) {
2122
+ var inp = lookupInput();
2123
+ if (inp) try { inp.focus(); inp.select && inp.select(); } catch (e) { /* soft */ }
2124
+ } else {
2125
+ lookupOpen();
2126
+ }
2127
+ }
2128
+ });
2129
+ }
2130
+ }
2131
+
2132
+ var hashchangeWired = false;
2133
+
2134
+ // AC-205-5: a mount URL of `?tab=requirements&entity=US-304` lands on the
2135
+ // same position at first paint. The hash-router owns tab + entity, so we
2136
+ // promote the tab/sub/entity query params into the hash fragment at boot
2137
+ // when no explicit hash is already set. embed/theme stay in the query so
2138
+ // urlWithHash keeps the Dex contract.
2139
+ function bootHashFromQuery() {
2140
+ if (window.location.hash) return;
2141
+ var q = parseQuery(window.location.search);
2142
+ var parts = [];
2143
+ if (q.tab) parts.push('tab=' + encodeURIComponent(q.tab));
2144
+ if (q.sub) parts.push('sub=' + encodeURIComponent(q.sub));
2145
+ if (q.entity) parts.push('entity=' + encodeURIComponent(q.entity));
2146
+ if (parts.length === 0) return;
2147
+ try {
2148
+ if (window.history && typeof window.history.replaceState === 'function') {
2149
+ window.history.replaceState(null, '', window.location.pathname + window.location.search + '#' + parts.join('&'));
2150
+ } else {
2151
+ window.location.hash = parts.join('&');
2152
+ }
2153
+ } catch (err) { /* best effort; resolveHash will no-op on empty hash */ }
2154
+ }
2155
+
2156
+ function onReady() {
2157
+ initShellFromQuery();
2158
+ bootHashFromQuery();
2159
+ wireThemeMessages();
2160
+ initMermaid();
2161
+ wireTabs();
2162
+ wireProductMap();
2163
+ wireRequirementsFilterBar();
2164
+ wireArchitectureFilterBars();
2165
+ wireBuildTab();
2166
+ wireEntitySelectors();
2167
+ wireFixturePage();
2168
+ wireLookup();
2169
+ wireStageLegend();
2170
+ resolveHash(window.location.hash);
2171
+ if (!hashchangeWired) {
2172
+ hashchangeWired = true;
2173
+ window.addEventListener('hashchange', function () {
2174
+ resolveHash(window.location.hash);
2175
+ });
2176
+ }
2177
+ }
2178
+
2179
+ window.rcfPage = window.rcfPage || {};
2180
+ window.rcfPage.init = onReady;
2181
+ // Shared helpers available for later tabs to call. The toast helper
2182
+ // is the one the fixture page demos; later PRs reuse it for the
2183
+ // ID-lookup copy-id confirmation and the DAG inspector "linked"
2184
+ // acknowledgement.
2185
+ window.rcfView = window.rcfView || {};
2186
+ window.rcfView.showToast = showToast;
2187
+
2188
+ if (document.readyState === 'loading') {
2189
+ document.addEventListener('DOMContentLoaded', onReady);
2190
+ } else {
2191
+ onReady();
2192
+ }
2193
+ })();