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
@@ -45,7 +45,8 @@
45
45
 
46
46
  import { computeQueue } from '../build/queue.js';
47
47
  import { isOptedOut } from '../req-baseline/opt-out.js';
48
- import { BRIEF_KINDS } from '../define/ledgers.js';
48
+ import { BRIEF_KINDS, parseResolvedBy } from '../define/ledgers.js';
49
+ import { applicableConcernsForShapes } from '../define/concern-catalogue.js';
49
50
 
50
51
  /** Canonical stage order (proposal §3.2). */
51
52
  export const STAGE_ORDER = /** @type {const} */ (['D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8']);
@@ -91,6 +92,329 @@ export const INTERFACE_KINDS = /** @type {const} */ ([
91
92
  'port', 'fileFormat', 'fixture', 'other',
92
93
  ]);
93
94
 
95
+ /**
96
+ * Owning persona for every stage-gate check in 0.29.0 (ADR-4126).
97
+ *
98
+ * Two values: `productOwner` (the person who owns what the product
99
+ * must do) and `engineer` (the person who owns how it is built).
100
+ * There is no `either` / `shared` / `both`; a check that would need
101
+ * both is split, which is what happens to `skeleton:reqFields`
102
+ * (becomes `skeleton:reqIntent` + `skeleton:reqShape`) and
103
+ * `decisions:allAnswered` (becomes `decisions:wellFormed` +
104
+ * `decisions:allAnswered`). A failing item inherits its check's
105
+ * persona; there is no per-item override.
106
+ *
107
+ * The `notApplicable` placeholder (`stage:<D>:scope`) carries the
108
+ * per-stage fallback persona from `STAGE_FALLBACK_PERSONA` below.
109
+ * It is always ok so it never affects a level verdict.
110
+ */
111
+ export const CHECK_PERSONA = /** @type {const} */ ({
112
+ // D1 Brief: every check is PO (the brief is the PO's statement of intent).
113
+ 'brief:sinceFreeze': 'productOwner',
114
+ 'brief:kinds': 'productOwner',
115
+ 'brief:openQuestions': 'productOwner',
116
+ 'brief:profile': 'productOwner',
117
+ // D2 Skeleton: resolvedBy + reqIntent are PO; reqShape, tadPersistence, deployAdr, standardsCited are engineer.
118
+ 'skeleton:resolvedBy': 'productOwner',
119
+ 'skeleton:reqIntent': 'productOwner',
120
+ 'skeleton:reqShape': 'engineer',
121
+ 'skeleton:tadPersistence': 'engineer',
122
+ 'skeleton:deployAdr': 'engineer',
123
+ 'skeleton:standardsCited': 'engineer',
124
+ // D3 Shapes: every check is engineer (shapes are the engineer's first act after hand-over).
125
+ 'shapes:tacHasInterface': 'engineer',
126
+ 'shapes:kindVocabulary': 'engineer',
127
+ 'shapes:draftSettled': 'engineer',
128
+ 'shapes:templateMarkers': 'engineer',
129
+ 'shapes:entityJoin': 'engineer',
130
+ 'shapes:pathsResolve': 'engineer',
131
+ // D4 Stories: reqHasUs is PO ("what does someone do with this?"); the floors, closed sets and ownerRef resolution are engineer.
132
+ 'stories:reqHasUs': 'productOwner',
133
+ 'stories:usFloors': 'engineer',
134
+ 'stories:closedSets': 'engineer',
135
+ 'stories:ownerRefResolves': 'engineer',
136
+ // D5 Crosscut: TAD + concern-ledger content and the catalogue walk are engineering.
137
+ 'crosscut:securityArchitecture': 'engineer',
138
+ 'crosscut:operationalConcerns': 'engineer',
139
+ 'crosscut:concernsResolved': 'engineer',
140
+ 'crosscut:catalogue': 'engineer',
141
+ // D6 Consistency: schema validity, probes and the four scans are engineer.
142
+ 'consistency:validateClean': 'engineer',
143
+ 'consistency:probeCount': 'engineer',
144
+ 'consistency:contradictions': 'engineer',
145
+ 'consistency:unsatisfiable': 'engineer',
146
+ 'consistency:duplicates': 'engineer',
147
+ 'consistency:orphanInterfaces': 'engineer',
148
+ // D7 Decisions: enumeration is PO (the PO answers or lets the default stand);
149
+ // zero-open is the engineer's hand-over condition.
150
+ 'decisions:wellFormed': 'productOwner',
151
+ 'decisions:allAnswered': 'engineer',
152
+ // D8 Freeze: every check is mechanical / engineering.
153
+ 'freeze:priorGates': 'engineer',
154
+ 'freeze:acFbsOwnership': 'engineer',
155
+ 'freeze:queueHead': 'engineer',
156
+ 'freeze:validateClean': 'engineer',
157
+ });
158
+
159
+ /**
160
+ * Per-check heading question in the owning persona's register
161
+ * (ADR-4126, proposal section 1.1). The text report and the
162
+ * Readiness tab print the question as the heading of each check's
163
+ * findings list. Static per check in 0.29.0; per-item plain-English
164
+ * wording is step 3's guided elicitation.
165
+ */
166
+ export const CHECK_QUESTION = /** @type {const} */ ({
167
+ 'brief:sinceFreeze': 'What has changed, or what is this project for?',
168
+ 'brief:kinds': 'Is this a capability, a constraint, an actor, or something else?',
169
+ 'brief:openQuestions': 'Any open questions in the brief, resolved or promoted to a decision?',
170
+ 'brief:profile': 'How do you want to review, and who are you writing for?',
171
+ 'skeleton:resolvedBy': 'Does this statement become a requirement, an entity, or an omission?',
172
+ 'skeleton:reqIntent': 'What does this requirement mean and where does it sit?',
173
+ 'skeleton:reqShape': 'Every requirement in scope carries a shape classification.',
174
+ 'skeleton:tadPersistence': 'TAD data architecture lists dataStores and coreEntities for persistence REQs.',
175
+ 'skeleton:deployAdr': 'Exactly one Deploy target or Deploy deferral ADR exists.',
176
+ 'skeleton:standardsCited': 'Every registered standards pack is cited in a REQ rationale or an ADR, or waived by a concern-ledger entry.',
177
+ 'shapes:tacHasInterface': 'Every TAC in scope has at least one interface.',
178
+ 'shapes:kindVocabulary': 'Every interface kind is in the closed vocabulary.',
179
+ 'shapes:draftSettled': 'Every draft interface has been settled (the [draft] marker is removed).',
180
+ 'shapes:templateMarkers': 'Every interface description carries the per-kind markers (recordShape fields:, httpRoute method/path/request/response/errors, and so on).',
181
+ 'shapes:entityJoin': 'Every core entity is named by exactly one recordShape.',
182
+ 'shapes:pathsResolve': 'Every path: token in an interface description resolves on disk or the description is authoredAt D3.',
183
+ 'stories:reqHasUs': 'What does someone do with this requirement?',
184
+ 'stories:usFloors': 'Every story in scope meets the class, tacIds and testability floors.',
185
+ 'stories:closedSets': 'Every acceptance criterion that invites a set of values names the set or points to an owner.',
186
+ 'stories:ownerRefResolves': 'Every ownerRef on an acceptance criterion resolves to an interface on the owning TAC.',
187
+ 'crosscut:securityArchitecture': 'TAD.securityArchitecture is present when an auth or httpApi REQ exists.',
188
+ 'crosscut:operationalConcerns': 'TAD.operationalConcerns is present when a deployed-scope AC exists.',
189
+ 'crosscut:concernsResolved': 'Every concern-ledger entry on a REQ in scope is applied or waived.',
190
+ 'crosscut:catalogue': 'Every applicable crosscut concern for a REQ in scope has a concern-ledger entry applied or waived.',
191
+ 'consistency:validateClean': 'Validate is clean tree-wide.',
192
+ 'consistency:probeCount': 'Zero open probe-ledger entries.',
193
+ 'consistency:contradictions': 'No two acceptance criteria on one story share a when clause with a negated then.',
194
+ 'consistency:unsatisfiable': 'Every then names a field some recordShape defines.',
195
+ 'consistency:duplicates': 'No two acceptance criteria across stories share an identical description.',
196
+ 'consistency:orphanInterfaces': 'Every interface is reached by an AC ownerRef or a REQ deliveredBy.',
197
+ 'decisions:wellFormed': 'Every decision is enumerated (question, two or more options, a default).',
198
+ 'decisions:allAnswered': 'Zero decisions are open.',
199
+ 'freeze:priorGates': 'Every prior stage passed or is acknowledged at the current hash.',
200
+ 'freeze:acFbsOwnership': 'Every AC is owned by exactly one FBS.',
201
+ 'freeze:queueHead': 'Queue head is actionable and not a placeholder.',
202
+ 'freeze:validateClean': 'Validate is clean tree-wide.',
203
+ });
204
+
205
+ /**
206
+ * Per-stage fallback persona for the `stage:<D>:scope` placeholder
207
+ * check that `notApplicable` envelopes carry. The placeholder is
208
+ * always ok so this never affects a level, but keeps "every check
209
+ * has a persona" true for consumers and the table test (ADR-4126
210
+ * decision 10).
211
+ */
212
+ export const STAGE_FALLBACK_PERSONA = /** @type {const} */ ({
213
+ D1: 'productOwner',
214
+ D2: 'productOwner',
215
+ D3: 'engineer',
216
+ D4: 'productOwner',
217
+ D5: 'engineer',
218
+ D6: 'engineer',
219
+ D7: 'productOwner',
220
+ D8: 'engineer',
221
+ });
222
+
223
+ /**
224
+ * Look up the question heading for a check name.
225
+ * @param {string} name
226
+ * @returns {string}
227
+ */
228
+ export function checkQuestion(name) {
229
+ return /** @type {any} */ (CHECK_QUESTION)[name] ?? '';
230
+ }
231
+
232
+ /**
233
+ * Look up the owning persona for a check name.
234
+ * @param {string} name
235
+ * @returns {'productOwner' | 'engineer' | null}
236
+ */
237
+ export function checkPersona(name) {
238
+ const v = /** @type {any} */ (CHECK_PERSONA)[name];
239
+ return v === 'productOwner' || v === 'engineer' ? v : null;
240
+ }
241
+
242
+ /**
243
+ * Draft marker (ADR-4126 for `TAC.interfaces[].description` in 0.29.0;
244
+ * REQ-188 extends it to `TAC.purpose` and `coreEntities[].description`
245
+ * in 0.30.0). A description that starts with `[draft]` after optional
246
+ * leading whitespace is pre-populated engineer entry material; the
247
+ * engineer removes the marker when the shape is settled. Decision 6
248
+ * uses the same bracket-prefix convention for AC class.
249
+ */
250
+ const INTERFACE_DRAFT_RE = /^\[draft\]/;
251
+
252
+ /**
253
+ * True when a string carries the leading `[draft]` marker
254
+ * (whitespace tolerated). Pure string test used by every draft-home
255
+ * reader below.
256
+ *
257
+ * @param {unknown} value
258
+ * @returns {boolean}
259
+ */
260
+ export function hasDraftMarker(value) {
261
+ if (typeof value !== 'string') return false;
262
+ return INTERFACE_DRAFT_RE.test(value.trimStart());
263
+ }
264
+
265
+ /**
266
+ * True when an interface's `description` carries the leading
267
+ * `[draft]` marker (whitespace tolerated). Thin wrapper over
268
+ * `hasDraftMarker` kept for ADR-4126 call sites; REQ-188 adds
269
+ * `parseTacPurposeDraft` and `parseCoreEntityDraft` for the two new
270
+ * homes.
271
+ *
272
+ * @param {unknown} iface
273
+ * @returns {boolean}
274
+ */
275
+ export function parseInterfaceDraft(iface) {
276
+ if (!iface || typeof iface !== 'object') return false;
277
+ return hasDraftMarker(/** @type {any} */ (iface).description);
278
+ }
279
+
280
+ /**
281
+ * True when a TAC's `purpose` carries the leading `[draft]` marker
282
+ * (whitespace tolerated). REQ-188 draft home; the engineer removes
283
+ * the marker when the TAC's purpose is owned.
284
+ *
285
+ * @param {unknown} tac
286
+ * @returns {boolean}
287
+ */
288
+ export function parseTacPurposeDraft(tac) {
289
+ if (!tac || typeof tac !== 'object') return false;
290
+ return hasDraftMarker(/** @type {any} */ (tac).purpose);
291
+ }
292
+
293
+ /**
294
+ * True when a coreEntities entry's `description` carries the
295
+ * leading `[draft]` marker (whitespace tolerated). REQ-188 draft
296
+ * home; the engineer removes the marker when the entity is owned.
297
+ *
298
+ * @param {unknown} entity
299
+ * @returns {boolean}
300
+ */
301
+ export function parseCoreEntityDraft(entity) {
302
+ if (!entity || typeof entity !== 'object') return false;
303
+ return hasDraftMarker(/** @type {any} */ (entity).description);
304
+ }
305
+
306
+ /**
307
+ * Per-kind required marker tokens on `interfaces[].description` for
308
+ * the `shapes:templateMarkers` D3 bite check (ADR-4131, spec section 4
309
+ * row "D3 template parser"). A marker is "present" when a line of the
310
+ * description matches the marker's own regex: a `<name>:` prefix for
311
+ * `fields:`, `instances:`, `payload:`, `usage:` and `format:`; a
312
+ * `method`, `path`, `request`, `response`, `errors` or `protocol`
313
+ * token on an httpRoute, uiRoute or port (word-bounded, case-sensitive,
314
+ * tolerating a trailing colon or whitespace); `other` requires a
315
+ * non-empty description after the optional `[draft]` prefix (its
316
+ * "note"). The regexes are deliberately permissive so a plain
317
+ * `method: POST` and a bullet list `- method: POST` both qualify, and
318
+ * so a `[draft]` prefix never masks the marker scan.
319
+ */
320
+ const INTERFACE_TEMPLATE_MARKERS = /** @type {const} */ ({
321
+ recordShape: [{ name: 'fields', re: /(^|\n)\s*(?:[-*]\s*)?fields\s*:/ }],
322
+ httpRoute: [
323
+ { name: 'method', re: /(^|\n|\s)method\s*[:=]/ },
324
+ { name: 'path', re: /(^|\n|\s)path\s*[:=]/ },
325
+ { name: 'request', re: /(^|\n|\s)request\s*[:=]/ },
326
+ { name: 'response', re: /(^|\n|\s)response\s*[:=]/ },
327
+ { name: 'errors', re: /(^|\n|\s)errors\s*[:=]/ },
328
+ ],
329
+ fixture: [{ name: 'instances', re: /(^|\n)\s*(?:[-*]\s*)?instances\s*:/ }],
330
+ event: [{ name: 'payload', re: /(^|\n)\s*(?:[-*]\s*)?payload\s*:/ }],
331
+ cliCommand: [{ name: 'usage', re: /(^|\n)\s*(?:[-*]\s*)?usage\s*:/ }],
332
+ uiRoute: [{ name: 'path', re: /(^|\n|\s)path\s*[:=]/ }],
333
+ port: [{ name: 'protocol', re: /(^|\n|\s)protocol\s*[:=]/ }],
334
+ fileFormat: [{ name: 'format', re: /(^|\n)\s*(?:[-*]\s*)?format\s*:/ }],
335
+ other: [],
336
+ });
337
+
338
+ /**
339
+ * Strip a leading `[draft]` marker from a description so the marker
340
+ * scan sees the real text underneath. Pure.
341
+ *
342
+ * @param {string} desc
343
+ * @returns {string}
344
+ */
345
+ function stripDraftPrefix(desc) {
346
+ return desc.replace(/^\s*\[draft\]\s*/, '');
347
+ }
348
+
349
+ /**
350
+ * ADR-4131 (0.30.0 PR 5): per-kind marker presence on an interface.
351
+ * Returns `{ kind, missing: string[] }` naming the markers that are
352
+ * absent from `iface.description`. For `other` the "note" is any
353
+ * non-empty description after the optional `[draft]` prefix. For an
354
+ * interface whose kind is outside INTERFACE_KINDS the function returns
355
+ * `{ kind, missing: [] }` so the caller can treat vocabulary errors
356
+ * through `shapes:kindVocabulary` alone.
357
+ *
358
+ * @param {unknown} iface
359
+ * @returns {{ kind: string|null, missing: string[] }}
360
+ */
361
+ export function parseInterfaceTemplate(iface) {
362
+ if (!iface || typeof iface !== 'object') return { kind: null, missing: [] };
363
+ const kind = typeof (/** @type {any} */ (iface).kind) === 'string' ? /** @type {any} */ (iface).kind : null;
364
+ const descRaw = typeof (/** @type {any} */ (iface).description) === 'string'
365
+ ? /** @type {any} */ (iface).description
366
+ : '';
367
+ const desc = stripDraftPrefix(descRaw);
368
+ if (kind === 'other') {
369
+ const note = desc.trim();
370
+ return { kind, missing: note.length === 0 ? ['note'] : [] };
371
+ }
372
+ const markers = /** @type {any} */ (INTERFACE_TEMPLATE_MARKERS)[kind];
373
+ if (!Array.isArray(markers)) return { kind, missing: [] };
374
+ const missing = [];
375
+ for (const marker of markers) {
376
+ if (!marker.re.test(desc)) missing.push(marker.name);
377
+ }
378
+ return { kind, missing };
379
+ }
380
+
381
+ /**
382
+ * Rough `path:` token scanner for an interface description. Returns
383
+ * every candidate path token the description names so the CLI can
384
+ * resolve them on disk and the gate can decide `shapes:pathsResolve`
385
+ * against the resolved map (ADR-4131). A candidate is any text that
386
+ * follows a `path:` or `path =` marker and looks like a repo-relative
387
+ * path (contains a `/` or ends with a file extension, no scheme). The
388
+ * scanner is deliberately conservative: an http URL, a bare word, a
389
+ * glob or a template placeholder is not a candidate. Exported for the
390
+ * CLI's resolve-on-disk pass.
391
+ *
392
+ * @param {string} description
393
+ * @returns {string[]}
394
+ */
395
+ export function extractInterfacePathTokens(description) {
396
+ if (typeof description !== 'string' || description.length === 0) return [];
397
+ const text = stripDraftPrefix(description);
398
+ const out = [];
399
+ const re = /\bpath\s*[:=]\s*["'`]?([^\s"'`,;)\]]+)/g;
400
+ let m;
401
+ while ((m = re.exec(text)) !== null) {
402
+ const token = m[1];
403
+ if (!token) continue;
404
+ if (/^[a-z]+:\/\//i.test(token)) continue;
405
+ if (token.startsWith('{') || token.startsWith('<') || token.includes('*')) continue;
406
+ // Skip HTTP / UI route-ish tokens: a leading slash with no file
407
+ // extension is a route path (an httpRoute or uiRoute's `path:`
408
+ // marker), not a repo path. A legitimate file path lands as
409
+ // `src/x.js` or `packages/rcf-lite/CHANGELOG.md`; those don't
410
+ // start with `/`.
411
+ if (token.startsWith('/') && !/\.[a-zA-Z0-9]+$/.test(token)) continue;
412
+ if (!/\//.test(token) && !/\.[a-zA-Z0-9]+$/.test(token)) continue;
413
+ out.push(token);
414
+ }
415
+ return out;
416
+ }
417
+
94
418
  /** Warn-with-ack stages in 0.29.0 (ADR-4122). */
95
419
  const WARN_WITH_ACK = new Set(['D3', 'D5', 'D6']);
96
420
 
@@ -108,6 +432,21 @@ export function stagePolicy(stage) {
108
432
  return WARN_WITH_ACK.has(stage) ? 'warnWithAck' : 'blocking';
109
433
  }
110
434
 
435
+ /**
436
+ * ADR-4131 (0.30.0 PR 5): the three gates that accept a recorded
437
+ * `--ack` override. `stagePolicy` keeps returning `blocking` for every
438
+ * stage so the readyToBuild fold stays untouched; `ackable(stage)` is
439
+ * the companion signal the readiness and freeze CLIs read to decide
440
+ * whether a failing stage honours an acknowledgement at the current
441
+ * hash. True for D3, D5 and D6; false for everything else.
442
+ *
443
+ * @param {string} stage
444
+ * @returns {boolean}
445
+ */
446
+ export function ackable(stage) {
447
+ return WARN_WITH_ACK.has(stage);
448
+ }
449
+
111
450
  /**
112
451
  * Scaffold TODO placeholder marker: uppercase "TODO" followed by a
113
452
  * colon, matching every scaffold string `rcf init` and `rcf define
@@ -124,6 +463,192 @@ const TODO_RE = /\bTODO:/;
124
463
  /** Bracketed AC-class prefix (Baz decision 6, proposal §3.2 D4). */
125
464
  const AC_CLASS_RE = /^\[(happy|edge|failure|must-not|non-functional)\]/;
126
465
 
466
+ /**
467
+ * Enumeration cues for `stories:closedSets` (spec section 4 row 'D4
468
+ * closed-set and ownerRef as findings', 0.30.0 PR 6). An AC description
469
+ * that contains any of these cues outside a quoted string, with no
470
+ * inline bracketed list or ownerRef, invites an unlisted value and
471
+ * fails the check. The cues are matched case-insensitively against the
472
+ * raw description (minus any leading [class] marker and any
473
+ * double-quoted substrings).
474
+ */
475
+ const CLOSED_SET_CUES = Object.freeze([
476
+ 'one of',
477
+ 'any of',
478
+ 'the following',
479
+ 'types of',
480
+ 'status is',
481
+ ]);
482
+ // Word-boundary matchers for each cue so a longer word that happens
483
+ // to contain the cue as a substring (e.g. "status issue" containing
484
+ // "status is") does not trip the gate.
485
+ const CLOSED_SET_CUE_RES = Object.freeze(
486
+ CLOSED_SET_CUES.map((cue) => new RegExp(`\\b${cue.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\b`, 'i')),
487
+ );
488
+
489
+ /**
490
+ * Inline bracketed list regex for the closed-sets check: a square-
491
+ * bracketed group whose contents look like a list of two or more
492
+ * tokens separated by commas, slashes or pipes. A bare `[happy]`
493
+ * class marker is NOT a list (one token, no separator); `[a, b]`,
494
+ * `[a | b | c]` and `[a/b]` are.
495
+ */
496
+ const INLINE_LIST_RE = /\[[^\]\n]*[,|\/][^\]\n]*\]/;
497
+
498
+ /**
499
+ * ownerRef marker: a cheap presence check for the structured
500
+ * `{ tacId, field: "interfaces[<name>]" }` pointer. True when the AC
501
+ * carries an ownerRef object (consistency-lint and PR 6 both read the
502
+ * same field).
503
+ *
504
+ * @param {unknown} ac
505
+ * @returns {boolean}
506
+ */
507
+ function acHasOwnerRef(ac) {
508
+ const ref = ac && typeof ac === 'object' ? /** @type {any} */ (ac).ownerRef : null;
509
+ if (!ref || typeof ref !== 'object') return false;
510
+ // R11 (spec section 17, 2026-10-03): an ownerRef may name a TAC
511
+ // (via tacId) OR an ADR (via adrId). Pre-R11 code only recognised
512
+ // tacId; the ADR branch was dropped silently.
513
+ return typeof ref.tacId === 'string' || typeof ref.adrId === 'string';
514
+ }
515
+
516
+ /**
517
+ * Strip double-quoted substrings so a quoted cue inside the AC text
518
+ * does not fire the closed-sets check (shared with D6's negation guard
519
+ * convention). Matches `"..."` with no embedded unescaped double
520
+ * quote; the regex is deliberately permissive. The strip is only for
521
+ * the cue scan; the inline-list scan reads the full description.
522
+ *
523
+ * @param {string} desc
524
+ * @returns {string}
525
+ */
526
+ function stripQuotedSubstrings(desc) {
527
+ return desc.replace(/"[^"\n]*"/g, '');
528
+ }
529
+
530
+ /**
531
+ * True when the AC description carries an enumeration cue outside a
532
+ * quoted substring, with no inline bracketed list and no ownerRef
533
+ * pointer. Pure.
534
+ *
535
+ * @param {unknown} ac
536
+ * @returns {boolean}
537
+ */
538
+ function failsClosedSets(ac) {
539
+ const descRaw = ac && typeof ac === 'object' ? /** @type {any} */ (ac).description : null;
540
+ if (typeof descRaw !== 'string' || descRaw.length === 0) return false;
541
+ if (acHasOwnerRef(ac)) return false;
542
+ const descNoClass = descRaw.replace(AC_CLASS_RE, '').trim();
543
+ if (INLINE_LIST_RE.test(descNoClass)) return false;
544
+ const descForCues = stripQuotedSubstrings(descNoClass);
545
+ for (const re of CLOSED_SET_CUE_RES) {
546
+ if (re.test(descForCues)) return true;
547
+ }
548
+ return false;
549
+ }
550
+
551
+ /**
552
+ * Parse an `interfaces[<name>]` field pointer into its interface
553
+ * name. Accepts any non-empty name between the brackets (interface
554
+ * names routinely carry dots, slashes and spaces); returns null for
555
+ * an unparseable pointer.
556
+ *
557
+ * @param {unknown} field
558
+ * @returns {string | null}
559
+ */
560
+ function parseOwnerRefInterfaceField(field) {
561
+ if (typeof field !== 'string') return null;
562
+ const m = field.match(/^interfaces\[([^\]\n]+)\]$/);
563
+ return m ? m[1] : null;
564
+ }
565
+
566
+ /**
567
+ * R11 field grammar (spec section 17, 2026-10-03). An `ownerRef` or
568
+ * object-form `deliveredBy` `{ tacId | adrId, field }` resolves when
569
+ * `field` names an existing field path on the owning document in
570
+ * bracket grammar:
571
+ *
572
+ * - `interfaces[<name>]` resolves when `doc.interfaces[].name` matches.
573
+ * - `responsibilities[<n>]` resolves when `doc.responsibilities[n]`
574
+ * exists (non-negative integer index, zero-based).
575
+ * - `dependencies[<name>]` resolves when `doc.dependencies[].name` matches.
576
+ * - `alternativesConsidered[<n>]` resolves when the ADR has an
577
+ * alternative at that index.
578
+ * - A bare schema field name (`purpose`, `internalStructure`,
579
+ * `decision`, `name`, `context`, `consequences`, `tradeoffs`,
580
+ * `notes`, `description`, `responsibilities`, `dependencies`,
581
+ * `interfaces`, `alternativesConsidered`) resolves when the
582
+ * document carries a non-empty value under that key.
583
+ *
584
+ * Dotted grammar (`interfaces.name`, `responsibilities.foo`) is NOT
585
+ * accepted: callers of the R11 widening MUST rewrite to bracket
586
+ * grammar first. A path that does not match any arm returns false.
587
+ *
588
+ * `AC-17405-2` is unchanged in effect: `interfaces[loan]` on a TAC
589
+ * carrying an interface named `loan` resolves; `interfaces[missing]`
590
+ * fails.
591
+ *
592
+ * @param {unknown} doc - the owning TAC or ADR document.
593
+ * @param {unknown} field - the ownerRef/deliveredBy field string.
594
+ * @returns {boolean}
595
+ */
596
+ export function resolveOwnerRefField(doc, field) {
597
+ if (!doc || typeof doc !== 'object') return false;
598
+ if (typeof field !== 'string' || field.length === 0) return false;
599
+ const d = /** @type {any} */ (doc);
600
+ // interfaces[<name>] -- preserved from the 0.29.0 helper.
601
+ const ifaceMatch = field.match(/^interfaces\[([^\]\n]+)\]$/);
602
+ if (ifaceMatch) {
603
+ const name = ifaceMatch[1];
604
+ return Array.isArray(d.interfaces)
605
+ && d.interfaces.some((iface) => iface && typeof iface === 'object' && iface.name === name);
606
+ }
607
+ // dependencies[<name>] (TAC.dependencies[].name).
608
+ const depMatch = field.match(/^dependencies\[([^\]\n]+)\]$/);
609
+ if (depMatch) {
610
+ const name = depMatch[1];
611
+ return Array.isArray(d.dependencies)
612
+ && d.dependencies.some((dep) => dep && typeof dep === 'object' && dep.name === name);
613
+ }
614
+ // responsibilities[<n>] (zero-based integer index on the strings array).
615
+ const respMatch = field.match(/^responsibilities\[(\d+)\]$/);
616
+ if (respMatch) {
617
+ const idx = Number(respMatch[1]);
618
+ return Array.isArray(d.responsibilities) && idx < d.responsibilities.length
619
+ && typeof d.responsibilities[idx] === 'string'
620
+ && d.responsibilities[idx].length > 0;
621
+ }
622
+ // alternativesConsidered[<n>] (ADR).
623
+ const altMatch = field.match(/^alternativesConsidered\[(\d+)\]$/);
624
+ if (altMatch) {
625
+ const idx = Number(altMatch[1]);
626
+ return Array.isArray(d.alternativesConsidered) && idx < d.alternativesConsidered.length
627
+ && d.alternativesConsidered[idx] && typeof d.alternativesConsidered[idx] === 'object';
628
+ }
629
+ // Bare schema field name. Must be in the TAC/ADR schema and present
630
+ // and non-empty on the document. The accepted set covers the schema
631
+ // fields the spec names and the extras TAC/ADR carry; a field name
632
+ // outside the set returns false.
633
+ const BARE_FIELDS = new Set([
634
+ // TAC fields.
635
+ 'purpose', 'internalStructure', 'tradeoffs', 'notes', 'name',
636
+ 'responsibilities', 'interfaces', 'dependencies',
637
+ // ADR fields.
638
+ 'decision', 'context', 'consequences', 'title',
639
+ 'alternativesConsidered',
640
+ // Common.
641
+ 'description',
642
+ ]);
643
+ if (!BARE_FIELDS.has(field)) return false;
644
+ const v = d[field];
645
+ if (v == null) return false;
646
+ if (typeof v === 'string') return v.length > 0;
647
+ if (Array.isArray(v)) return v.length > 0;
648
+ if (typeof v === 'object') return Object.keys(v).length > 0;
649
+ return true;
650
+ }
651
+
127
652
  /**
128
653
  * Parse the leading bracketed class marker on `ac.description`.
129
654
  * Returns the class token, or null when no marker is present.
@@ -156,12 +681,26 @@ export function parseAcClass(ac) {
156
681
  * twentieth failure. `ok` is likewise derived from the untruncated
157
682
  * count. The section 2.4 shape stays intact -- `failing` remains the
158
683
  * display array; no new field is exported.
159
- * @returns {{ name: string, ok: boolean, over: 'delta'|'tree', pass: number, total: number, failing: Array<{ id: string, why: string }> }}
684
+ * @returns {{ name: string, ok: boolean, over: 'delta'|'tree', pass: number, total: number, failing: Array<{ id: string, why: string }>, persona: 'productOwner'|'engineer', question: string }}
160
685
  */
161
686
  function makeCheck(name, over, total, failing, totalFailingCount) {
162
687
  const nFailing = typeof totalFailingCount === 'number' ? totalFailingCount : failing.length;
163
688
  const pass = Math.max(0, total - nFailing);
164
- return { name, ok: nFailing === 0, over, pass, total, failing: [...failing] };
689
+ // Resolve persona + question for the check. For stage placeholders
690
+ // (`stage:<D>:scope`) the persona comes from STAGE_FALLBACK_PERSONA.
691
+ // Unknown names fall back to engineer with an empty question so
692
+ // consumers never see null; the table test catches any new check
693
+ // that forgets to register in CHECK_PERSONA / CHECK_QUESTION.
694
+ let persona = /** @type {any} */ (CHECK_PERSONA)[name];
695
+ if (!persona) {
696
+ const stageMatch = /^stage:(D[1-8]):scope$/.exec(name);
697
+ persona = stageMatch
698
+ ? /** @type {any} */ (STAGE_FALLBACK_PERSONA)[stageMatch[1]]
699
+ : 'engineer';
700
+ }
701
+ const question = /** @type {any} */ (CHECK_QUESTION)[name]
702
+ ?? (name.startsWith('stage:') ? 'No documents of this stage’s type are in scope.' : '');
703
+ return { name, ok: nFailing === 0, over, pass, total, failing: [...failing], persona, question };
165
704
  }
166
705
 
167
706
  /**
@@ -232,6 +771,11 @@ function asSet(scope) {
232
771
  * @property {{ skipReviewFor?: string } | undefined} profile parsed profile switches (light shape)
233
772
  * @property {string | null | undefined} currentTreeHash for warn-with-ack acknowledgement match
234
773
  * @property {Array<{ state: string }> | undefined} priorStages D8 reads earlier stage states from this
774
+ * @property {Set<string> | undefined} resolvedPaths ADR-4131 (0.30.0 PR 5): set of repo-relative paths the CLI
775
+ * already resolved on disk; `shapes:pathsResolve` reads this to decide
776
+ * whether a `path:` token on an interface description resolves. Empty or
777
+ * undefined means no path is known-resolved, so every candidate token
778
+ * fails unless the interface description carries `authoredAt: D3`.
235
779
  */
236
780
 
237
781
  /**
@@ -342,57 +886,68 @@ export function checkD2Skeleton(ctx) {
342
886
 
343
887
  const checks = [];
344
888
 
345
- // Check 1: every capability/constraint/entity/... statement resolves
346
- // (the statement carries `resolvedBy` naming a REQ / TAD entity / TAC
347
- // / recorded omission id, OR its text matches an existing REQ title).
348
- // Cheap check: a `resolvedBy` string or a name-hit on titles.
349
- const resolvedByStmt = (s) => {
889
+ // Check 1 (0.30.0): every capability/constraint/entity/... statement
890
+ // resolves to a closed-grammar pointer in `resolvedBy`:
891
+ // REQ-nnn | TAD.entity:<name> | PRD.user:<name>
892
+ // | TAD.system:<name> | TAC-nnnn | omitted:<reason>
893
+ // The 0.29.0 REQ-title fallback is dropped (decision 3; a title hit
894
+ // becomes a suggestion the PR 2 computeQuestions surface returns).
895
+ // A statement with no `resolvedBy` fails; a statement with a
896
+ // `resolvedBy` outside the grammar fails with 'pointer does not
897
+ // resolve'.
898
+ /** @type {Array<{ id: string, why: string }>} */
899
+ const unresolvedFailing = [];
900
+ for (const s of resolvingStmts) {
350
901
  const rb = s?.resolvedBy;
351
- if (typeof rb === 'string' && rb.length > 0) return true;
352
- if (rb && typeof rb === 'object' && Object.keys(rb).length > 0) return true;
353
- const text = typeof s?.text === 'string' ? s.text.trim().toLowerCase() : '';
354
- if (!text) return false;
355
- for (const req of tree.requirements ?? []) {
356
- const title = typeof req?.title === 'string' ? req.title.toLowerCase() : '';
357
- if (title && text.includes(title)) return true;
358
- }
359
- return false;
360
- };
361
- const unresolvedStmts = resolvingStmts.filter((s) => !resolvedByStmt(s));
902
+ if (typeof rb !== 'string' || rb.length === 0) {
903
+ unresolvedFailing.push({ id: `brief:${s.id}`, why: `${s.kind} statement has no resolvedBy` });
904
+ continue;
905
+ }
906
+ const parsed = parseResolvedBy(rb, tree);
907
+ if (!parsed.ok) {
908
+ unresolvedFailing.push({ id: `brief:${s.id}`, why: 'pointer does not resolve' });
909
+ }
910
+ }
362
911
  checks.push(makeCheck(
363
912
  'skeleton:resolvedBy',
364
913
  'delta',
365
914
  resolvingStmts.length,
366
- unresolvedStmts.map((s) => ({ id: `brief:${s.id}`, why: `${s.kind} statement has no resolvedBy and no REQ-title hit` })),
915
+ unresolvedFailing,
367
916
  ));
368
917
 
369
- // Check 2: every REQ in scope has description, shapeClassification, domain.
918
+ // Checks 2a / 2b: the former `skeleton:reqFields` split into two
919
+ // homogeneous checks (ADR-4126, proposal section 1.3). Each
920
+ // evaluates every REQ in scope independently so a REQ with a TODO
921
+ // description still has its shapes reported, and vice versa.
922
+ const reqIntentFail = [];
370
923
  const reqShapeFail = [];
371
924
  for (const req of reqInScope) {
925
+ // reqIntent (productOwner): description without a TODO + domain
926
+ // (what the requirement means and where it sits).
372
927
  if (typeof req.description !== 'string' || req.description.length === 0 || TODO_RE.test(req.description)) {
373
- reqShapeFail.push({ id: req.reqId, why: 'description missing or contains TODO placeholder' });
374
- continue;
928
+ reqIntentFail.push({ id: req.reqId, why: 'description missing or contains TODO placeholder' });
929
+ } else if (typeof req.domain !== 'string' || req.domain.length === 0) {
930
+ reqIntentFail.push({ id: req.reqId, why: 'domain missing' });
375
931
  }
932
+ // reqShape (engineer): shapeClassification.shapes classification.
376
933
  if (!req.shapeClassification || !Array.isArray(req.shapeClassification.shapes)) {
377
934
  reqShapeFail.push({ id: req.reqId, why: 'shapeClassification.shapes missing' });
378
- continue;
379
- }
380
- if (typeof req.domain !== 'string' || req.domain.length === 0) {
381
- reqShapeFail.push({ id: req.reqId, why: 'domain missing' });
382
935
  }
383
936
  }
384
- checks.push(makeCheck('skeleton:reqFields', 'delta', reqInScope.length, reqShapeFail));
937
+ checks.push(makeCheck('skeleton:reqIntent', 'delta', reqInScope.length, reqIntentFail));
938
+ checks.push(makeCheck('skeleton:reqShape', 'delta', reqInScope.length, reqShapeFail));
385
939
 
386
- // Check 3: TAD.dataStores + coreEntities present when any persistence
940
+ // Check 3: TAD.dataArchitecture.dataStores + coreEntities present when any
387
941
  // REQ exists tree-wide.
388
942
  const persistenceReq = (tree.requirements ?? []).some((r) => Array.isArray(r?.shapeClassification?.shapes) && r.shapeClassification.shapes.includes('persistence'));
389
943
  const tadFail = [];
390
944
  if (persistenceReq) {
391
945
  const tad = tree.tad ?? {};
392
- const dataStores = Array.isArray(tad.dataStores) ? tad.dataStores : [];
393
- const coreEntities = Array.isArray(tad.coreEntities) ? tad.coreEntities : [];
394
- if (dataStores.length === 0) tadFail.push({ id: 'TAD.dataStores', why: 'TAD.dataStores empty while persistence REQ exists' });
395
- if (coreEntities.length === 0) tadFail.push({ id: 'TAD.coreEntities', why: 'TAD.coreEntities empty while persistence REQ exists' });
946
+ const dataArch = tad?.dataArchitecture ?? {};
947
+ const dataStores = Array.isArray(dataArch.dataStores) ? dataArch.dataStores : [];
948
+ const coreEntities = Array.isArray(dataArch.coreEntities) ? dataArch.coreEntities : [];
949
+ if (dataStores.length === 0) tadFail.push({ id: 'TAD.dataArchitecture.dataStores', why: 'TAD.dataArchitecture.dataStores empty while persistence REQ exists' });
950
+ if (coreEntities.length === 0) tadFail.push({ id: 'TAD.dataArchitecture.coreEntities', why: 'TAD.dataArchitecture.coreEntities empty while persistence REQ exists' });
396
951
  }
397
952
  checks.push(makeCheck('skeleton:tadPersistence', 'tree', persistenceReq ? 2 : 0, tadFail));
398
953
 
@@ -407,6 +962,50 @@ export function checkD2Skeleton(ctx) {
407
962
  else if (deployAdrs.length > 1) deployFail.push({ id: 'ADR:deploy', why: `${deployAdrs.length} Deploy ADRs found; expected exactly one` });
408
963
  checks.push(makeCheck('skeleton:deployAdr', 'tree', 1, deployFail));
409
964
 
965
+ // Check 5 (0.30.0 PR 6): skeleton:standardsCited (engineer, over
966
+ // tree). Every standards pack registered through `rcf define
967
+ // standards` (manifest.standards[].slug) is cited in a REQ
968
+ // `rationale` or an ADR, or waived by a concern-ledger entry keyed
969
+ // `standards:<pack>`. Fail ids `standards:<pack>` with 'uncited and
970
+ // unwaived'. Citation is a case-sensitive substring match of the
971
+ // slug against each REQ.rationale and each ADR document (the ADR
972
+ // may name a pack in its title, context, decision or consequences;
973
+ // the serialised document is scanned once per ADR to cover every
974
+ // field). A waiver entry on the concern ledger reads `concern:
975
+ // 'standards:<pack>'` with disposition 'applied' or 'waived'.
976
+ const standardsList = Array.isArray(tree.manifest?.standards)
977
+ ? /** @type {any[]} */ (tree.manifest.standards)
978
+ : [];
979
+ /** @type {Array<{ id: string, why: string }>} */
980
+ const standardsFail = [];
981
+ if (standardsList.length > 0) {
982
+ const reqRationales = (tree.requirements ?? [])
983
+ .map((r) => (typeof r?.rationale === 'string' ? r.rationale : ''))
984
+ .join('\n');
985
+ const adrDocs = (tree.adrs ?? []).map((a) => {
986
+ try { return JSON.stringify(a); } catch { return ''; }
987
+ }).join('\n');
988
+ const concernsBody = /** @type {any} */ (ctx.ledgers?.concerns);
989
+ const concernList = Array.isArray(concernsBody?.concerns) ? concernsBody.concerns : [];
990
+ const waiverSlugs = new Set();
991
+ for (const entry of concernList) {
992
+ if (!entry || typeof entry.concern !== 'string') continue;
993
+ const disposition = typeof entry.disposition === 'string' ? entry.disposition : null;
994
+ if (disposition !== 'applied' && disposition !== 'waived') continue;
995
+ const m = entry.concern.match(/^standards:(.+)$/);
996
+ if (m) waiverSlugs.add(m[1]);
997
+ }
998
+ for (const pack of standardsList) {
999
+ const slug = typeof pack?.slug === 'string' ? pack.slug : null;
1000
+ if (!slug) continue;
1001
+ if (waiverSlugs.has(slug)) continue;
1002
+ if (reqRationales.includes(slug)) continue;
1003
+ if (adrDocs.includes(slug)) continue;
1004
+ standardsFail.push({ id: `standards:${slug}`, why: 'uncited and unwaived' });
1005
+ }
1006
+ }
1007
+ checks.push(makeCheck('skeleton:standardsCited', 'tree', Math.max(standardsList.length, 1), standardsFail));
1008
+
410
1009
  return foldState('D2', gate, checks, {
411
1010
  currentTreeHash: ctx.currentTreeHash ?? null,
412
1011
  freezeGates: /** @type {any} */ (ctx.freeze?.gates),
@@ -421,14 +1020,20 @@ export function checkD2Skeleton(ctx) {
421
1020
  const INTERFACE_KINDS_SET = new Set(INTERFACE_KINDS);
422
1021
 
423
1022
  /**
424
- * D3 -- Interface contracts and shapes. 0.29.0 runs only the cheap
425
- * presence + closed-vocabulary checks.
1023
+ * D3 -- Interface contracts and shapes. 0.29.0 runs the cheap
1024
+ * presence, closed-vocabulary and draft-marker checks
1025
+ * (`shapes:draftSettled` per ADR-4126 scans the `[draft]` prefix).
1026
+ * REQ-188 (0.30.0): the draft marker extends to `TAC.purpose` and
1027
+ * `TAD.dataArchitecture.coreEntities[].description`; `shapes:draftSettled`
1028
+ * enumerates all three homes with ids `<tacId>:<name>`, `<tacId>`
1029
+ * and `TAD.entity:<name>` respectively. `tacHasInterface` and
1030
+ * `kindVocabulary` apply to drafts unchanged.
426
1031
  *
427
1032
  * SEAM 0.30: template markers per kind (recordShape.fields:, httpRoute
428
1033
  * method/path/request/response/errors, fixture.instances:); entity-name
429
- * join across TAD.coreEntities and TAC.interfaces[]; ownerRef and
430
- * `authoredAt` path resolution. Those add checks to this stage; the
431
- * fold shape stays the same.
1034
+ * join across TAD.dataArchitecture.coreEntities and TAC.interfaces[];
1035
+ * ownerRef and `authoredAt` path resolution. Those add checks to this
1036
+ * stage; the fold shape stays the same.
432
1037
  *
433
1038
  * @param {StageContext} ctx
434
1039
  */
@@ -443,8 +1048,17 @@ export function checkD3Shapes(ctx) {
443
1048
  return shapes.includes('httpApi') || shapes.includes('persistence') || shapes.includes('auth');
444
1049
  });
445
1050
 
446
- if (tacsInScope.length === 0 && shapedReqInScope.length === 0) {
447
- return notApplicable('D3', gate, 'no TAC and no shaped REQ (httpApi/persistence/auth) in scope');
1051
+ // Core entities on TAD.dataArchitecture come from the whole tree,
1052
+ // not the scope: an entity's draft marker is a tree-wide draft home
1053
+ // (the engineer owns every entity in one place) and reporting it
1054
+ // under D3 does not depend on which TAC a change touched.
1055
+ const coreEntities = Array.isArray(tree.tad?.dataArchitecture?.coreEntities)
1056
+ ? /** @type {any[]} */ (tree.tad.dataArchitecture.coreEntities)
1057
+ : [];
1058
+ const draftEntities = coreEntities.filter(parseCoreEntityDraft);
1059
+
1060
+ if (tacsInScope.length === 0 && shapedReqInScope.length === 0 && draftEntities.length === 0) {
1061
+ return notApplicable('D3', gate, 'no TAC, no shaped REQ (httpApi/persistence/auth) and no [draft] core entity in scope');
448
1062
  }
449
1063
 
450
1064
  const checks = [];
@@ -459,18 +1073,139 @@ export function checkD3Shapes(ctx) {
459
1073
  ));
460
1074
 
461
1075
  // Check 2: every interface kind is in the closed vocabulary.
1076
+ // Check 3: no description across the three draft homes still
1077
+ // carries the `[draft]` marker. A draft shape is entry material
1078
+ // the agent pre-populates after L1; the engineer removes the
1079
+ // marker when the shape is settled. `tacHasInterface` and
1080
+ // `kindVocabulary` apply equally to drafts.
462
1081
  let totalInterfaces = 0;
463
1082
  const badKinds = [];
1083
+ const draftFindings = [];
464
1084
  for (const tac of tacsInScope) {
1085
+ if (parseTacPurposeDraft(tac)) {
1086
+ draftFindings.push({ id: tac.tacId, why: 'draft TAC purpose pre-populated at L1, not yet settled' });
1087
+ }
465
1088
  for (const iface of tac.interfaces ?? []) {
466
1089
  totalInterfaces += 1;
467
1090
  const kind = iface?.kind;
468
1091
  if (typeof kind !== 'string' || !INTERFACE_KINDS_SET.has(kind)) {
469
1092
  badKinds.push({ id: `${tac.tacId}:${iface?.name ?? '(unnamed)'}`, why: `unknown interface kind ${JSON.stringify(kind)}` });
470
1093
  }
1094
+ if (parseInterfaceDraft(iface)) {
1095
+ draftFindings.push({ id: `${tac.tacId}:${iface?.name ?? '(unnamed)'}`, why: 'draft interface pre-populated at L1, not yet settled' });
1096
+ }
471
1097
  }
472
1098
  }
1099
+ for (const entity of draftEntities) {
1100
+ draftFindings.push({ id: `TAD.entity:${entity?.name ?? '(unnamed)'}`, why: 'draft core entity pre-populated at L1, not yet settled' });
1101
+ }
1102
+ // Total for the draft check is every draft home that could carry
1103
+ // the marker on an in-scope TAC plus every core entity (tree-wide):
1104
+ // the TAC itself (its purpose) + every interface on it, plus the
1105
+ // coreEntities list.
1106
+ const totalDraftHomes = tacsInScope.length + totalInterfaces + coreEntities.length;
473
1107
  checks.push(makeCheck('shapes:kindVocabulary', 'delta', totalInterfaces, badKinds));
1108
+ checks.push(makeCheck('shapes:draftSettled', 'delta', totalDraftHomes, draftFindings));
1109
+
1110
+ // ADR-4131 (0.30.0 PR 5): three D3 bite checks follow.
1111
+ // Check 4: shapes:templateMarkers (engineer, over delta). For every
1112
+ // interface on an in-scope TAC, parseInterfaceTemplate reports which
1113
+ // per-kind markers are missing from the description; a draft marker
1114
+ // is stripped before the scan so a [draft] recordShape without
1115
+ // `fields:` fails exactly as a settled one. An interface whose kind
1116
+ // is outside INTERFACE_KINDS is left to shapes:kindVocabulary (the
1117
+ // marker map returns `{missing: []}` for an unknown kind so this
1118
+ // check does not double-report the vocabulary miss).
1119
+ /** @type {Array<{ id: string, why: string }>} */
1120
+ const templateFindings = [];
1121
+ for (const tac of tacsInScope) {
1122
+ for (const iface of tac.interfaces ?? []) {
1123
+ const result = parseInterfaceTemplate(iface);
1124
+ if (!result.kind) continue;
1125
+ for (const marker of result.missing) {
1126
+ templateFindings.push({
1127
+ id: `${tac.tacId}:${iface?.name ?? '(unnamed)'}`,
1128
+ why: `missing marker ${marker}`,
1129
+ });
1130
+ }
1131
+ }
1132
+ }
1133
+ checks.push(makeCheck('shapes:templateMarkers', 'delta', totalInterfaces, templateFindings));
1134
+
1135
+ // Check 5: shapes:entityJoin (engineer, over tree). Every entry in
1136
+ // TAD.dataArchitecture.coreEntities must be named by exactly one
1137
+ // recordShape across the whole tree (not just the delta scope),
1138
+ // matching on the recordShape's `name` field or on an `entity:` line
1139
+ // in its description. A `[draft]` prefix is stripped before the
1140
+ // entity-line scan so a draft recordShape still joins.
1141
+ /** @type {Array<{ id: string, why: string }>} */
1142
+ const joinFindings = [];
1143
+ const treeTacs = tree.tacs ?? [];
1144
+ const recordShapesByEntity = new Map();
1145
+ for (const tac of treeTacs) {
1146
+ for (const iface of tac.interfaces ?? []) {
1147
+ if (iface?.kind !== 'recordShape') continue;
1148
+ const ownerLabel = `${tac.tacId}:${iface?.name ?? '(unnamed)'}`;
1149
+ const names = new Set();
1150
+ if (typeof iface?.name === 'string') names.add(iface.name);
1151
+ const desc = typeof iface?.description === 'string' ? stripDraftPrefix(iface.description) : '';
1152
+ const entityRe = /(^|\n)\s*(?:[-*]\s*)?entity\s*[:=]\s*["'`]?([A-Za-z_][A-Za-z0-9_]*)/g;
1153
+ let em;
1154
+ while ((em = entityRe.exec(desc)) !== null) {
1155
+ if (em[2]) names.add(em[2]);
1156
+ }
1157
+ for (const name of names) {
1158
+ const owners = recordShapesByEntity.get(name) ?? [];
1159
+ owners.push(ownerLabel);
1160
+ recordShapesByEntity.set(name, owners);
1161
+ }
1162
+ }
1163
+ }
1164
+ for (const entity of coreEntities) {
1165
+ const name = typeof entity?.name === 'string' ? entity.name : null;
1166
+ if (!name) continue;
1167
+ const owners = recordShapesByEntity.get(name) ?? [];
1168
+ if (owners.length === 0) {
1169
+ joinFindings.push({ id: `TAD.entity:${name}`, why: 'no record shape' });
1170
+ } else if (owners.length > 1) {
1171
+ joinFindings.push({ id: `TAD.entity:${name}`, why: `${owners.length} record shapes` });
1172
+ }
1173
+ }
1174
+ checks.push(makeCheck('shapes:entityJoin', 'tree', coreEntities.length, joinFindings));
1175
+
1176
+ // Check 6: shapes:pathsResolve (engineer, over delta). Any path:
1177
+ // token on an in-scope interface description must either resolve
1178
+ // against `resolvedPaths` (the CLI's on-disk pass) or the
1179
+ // description must carry an `authoredAt: D3` marker (the engineer
1180
+ // owns the path even when the file is yet to land). The marker is
1181
+ // a token in the description text (`authoredAt: D3` or
1182
+ // `authoredAt = D3`), not a separate schema field; the TAC schema
1183
+ // keeps interfaces to { name, kind, description }. Over delta,
1184
+ // one failing entry per unresolved (tacId:name, path) pair.
1185
+ const resolvedPaths = ctx.resolvedPaths instanceof Set ? ctx.resolvedPaths : new Set();
1186
+ /** @type {Array<{ id: string, why: string }>} */
1187
+ const pathFindings = [];
1188
+ let totalPathChecks = 0;
1189
+ for (const tac of tacsInScope) {
1190
+ for (const iface of tac.interfaces ?? []) {
1191
+ const desc = typeof iface?.description === 'string' ? iface.description : '';
1192
+ const tokens = extractInterfacePathTokens(desc);
1193
+ if (tokens.length === 0) continue;
1194
+ const authoredAtD3 = /\bauthoredAt\s*[:=]\s*["'`]?D3\b/.test(stripDraftPrefix(desc));
1195
+ for (const token of tokens) {
1196
+ totalPathChecks += 1;
1197
+ if (authoredAtD3) continue;
1198
+ if (resolvedPaths.has(token)) continue;
1199
+ pathFindings.push({
1200
+ id: `${tac.tacId}:${iface?.name ?? '(unnamed)'}`,
1201
+ why: `path does not resolve: ${token}`,
1202
+ });
1203
+ }
1204
+ }
1205
+ }
1206
+ // Keep total >= 1 so the chip prints a sensible ratio when no
1207
+ // interface in scope names a path.
1208
+ checks.push(makeCheck('shapes:pathsResolve', 'delta', Math.max(totalPathChecks, 1), pathFindings));
474
1209
 
475
1210
  return foldState('D3', gate, checks, {
476
1211
  currentTreeHash: ctx.currentTreeHash ?? null,
@@ -551,6 +1286,72 @@ export function checkD4Stories(ctx) {
551
1286
  }
552
1287
  checks.push(makeCheck('stories:usFloors', 'delta', usInScope.length, usFail));
553
1288
 
1289
+ // Check 3 (0.30.0 PR 6): stories:closedSets (engineer, over delta).
1290
+ // Every AC on a US in scope whose description contains an enumeration
1291
+ // cue (one of | any of | the following | types of | status is)
1292
+ // without an inline bracketed list of two or more tokens AND without
1293
+ // an ownerRef fails. The quoted-cue guard strips `"..."` substrings
1294
+ // before the cue scan so prose that quotes a cue does not fire the
1295
+ // check.
1296
+ /** @type {Array<{ id: string, why: string }>} */
1297
+ const closedSetFindings = [];
1298
+ let totalClosedSetAcs = 0;
1299
+ for (const us of usInScope) {
1300
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1301
+ for (const ac of acs) {
1302
+ if (typeof ac?.description !== 'string' || ac.description.length === 0) continue;
1303
+ totalClosedSetAcs += 1;
1304
+ if (failsClosedSets(ac)) {
1305
+ closedSetFindings.push({
1306
+ id: ac.id ?? us.usId,
1307
+ why: 'enumeration cue without a closed set',
1308
+ });
1309
+ }
1310
+ }
1311
+ }
1312
+ checks.push(makeCheck('stories:closedSets', 'delta', totalClosedSetAcs, closedSetFindings));
1313
+
1314
+ // Check 4 (0.30.0 PR 6): stories:ownerRefResolves (engineer, over
1315
+ // delta plus tree for ownerRef targets). Every AC on a US in scope
1316
+ // whose ownerRef is set must point to an interface by name on the
1317
+ // named TAC. Ids `<acId>:<field>`; why 'ownerRef does not resolve'.
1318
+ /** @type {Array<{ id: string, why: string }>} */
1319
+ const ownerRefFindings = [];
1320
+ let totalOwnerRefAcs = 0;
1321
+ // R11 (spec section 17, 2026-10-03): the ownerRef field grammar
1322
+ // widens beyond `interfaces[<name>]` to every bracket-grammar path
1323
+ // that names an existing field on the owning TAC or ADR. The owner
1324
+ // may now be a TAC (via tacId) or an ADR (via adrId); the resolver
1325
+ // handles the bracket forms (`interfaces[<name>]`,
1326
+ // `responsibilities[<n>]`, `dependencies[<name>]`,
1327
+ // `alternativesConsidered[<n>]`) and bare schema fields (`purpose`,
1328
+ // `internalStructure`, `decision`, etc.). A path that does not
1329
+ // match any arm still fails. AC-17405-2 is unchanged in effect.
1330
+ for (const us of usInScope) {
1331
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1332
+ for (const ac of acs) {
1333
+ if (!acHasOwnerRef(ac)) continue;
1334
+ totalOwnerRefAcs += 1;
1335
+ const ref = /** @type {any} */ (ac).ownerRef;
1336
+ let owner = null;
1337
+ if (typeof ref.tacId === 'string') {
1338
+ owner = (tree.tacs ?? []).find((t) => t?.tacId === ref.tacId) ?? null;
1339
+ } else if (typeof ref.adrId === 'string') {
1340
+ owner = (tree.adrs ?? []).find((a) => a?.adrId === ref.adrId) ?? null;
1341
+ }
1342
+ const resolves = !!(owner && resolveOwnerRefField(owner, ref.field));
1343
+ if (!resolves) {
1344
+ ownerRefFindings.push({
1345
+ id: `${ac.id ?? us.usId}:${ref.field ?? '(no field)'}`,
1346
+ why: 'ownerRef does not resolve',
1347
+ });
1348
+ }
1349
+ }
1350
+ }
1351
+ // Keep total >= 1 so the chip prints a sensible ratio when no AC in
1352
+ // scope carries an ownerRef.
1353
+ checks.push(makeCheck('stories:ownerRefResolves', 'delta', Math.max(totalOwnerRefAcs, 1), ownerRefFindings));
1354
+
554
1355
  return foldState('D4', gate, checks, {
555
1356
  currentTreeHash: ctx.currentTreeHash ?? null,
556
1357
  freezeGates: /** @type {any} */ (ctx.freeze?.gates),
@@ -621,6 +1422,52 @@ export function checkD5Crosscut(ctx) {
621
1422
  openInScope.map((c) => ({ id: `concern:${c.id}`, why: `open concern on ${c.reqId}: ${c.concern}` })),
622
1423
  ));
623
1424
 
1425
+ // Check 4 (0.30.0 PR 6): crosscut:catalogue (engineer, over tree).
1426
+ // For every REQ in scope, enumerate applicable (reqShape, concern)
1427
+ // pairs via src/define/concern-catalogue.js; each pair needs a
1428
+ // concern-ledger entry keyed <REQ>:<concern> with disposition
1429
+ // applied or waived (a waived entry carries a reason). Fail ids are
1430
+ // `<REQ>:<concern>`; the why names the missing concern. A waived
1431
+ // entry without a reason also fails. Keys shared with the baseline
1432
+ // catalogue where names coincide (today only `auth`).
1433
+ const entriesByKey = new Map();
1434
+ for (const entry of concernEntries) {
1435
+ if (!entry || typeof entry.reqId !== 'string' || typeof entry.concern !== 'string') continue;
1436
+ entriesByKey.set(`${entry.reqId}:${entry.concern}`, entry);
1437
+ }
1438
+ /** @type {Array<{ id: string, why: string }>} */
1439
+ const catalogueFindings = [];
1440
+ let totalCataloguePairs = 0;
1441
+ for (const req of reqInScope) {
1442
+ const shapes = Array.isArray(req?.shapeClassification?.shapes)
1443
+ ? req.shapeClassification.shapes.filter((s) => typeof s === 'string')
1444
+ : [];
1445
+ const applicable = applicableConcernsForShapes(shapes);
1446
+ for (const concern of applicable) {
1447
+ totalCataloguePairs += 1;
1448
+ const key = `${req.reqId}:${concern}`;
1449
+ const entry = entriesByKey.get(key);
1450
+ if (!entry) {
1451
+ catalogueFindings.push({ id: key, why: `missing concern-ledger entry for ${concern}` });
1452
+ continue;
1453
+ }
1454
+ const disposition = typeof entry.disposition === 'string' ? entry.disposition : null;
1455
+ if (disposition !== 'applied' && disposition !== 'waived') {
1456
+ catalogueFindings.push({ id: key, why: `concern-ledger entry disposition is ${disposition ?? '(unset)'}` });
1457
+ continue;
1458
+ }
1459
+ if (disposition === 'waived') {
1460
+ const reason = typeof entry.reason === 'string' ? entry.reason.trim() : '';
1461
+ if (reason.length === 0) {
1462
+ catalogueFindings.push({ id: key, why: 'waived without a reason' });
1463
+ }
1464
+ }
1465
+ }
1466
+ }
1467
+ // Keep total >= 1 so the chip prints a sensible ratio when no REQ in
1468
+ // scope has applicable concerns (every REQ carries shape 'other').
1469
+ checks.push(makeCheck('crosscut:catalogue', 'tree', Math.max(totalCataloguePairs, 1), catalogueFindings));
1470
+
624
1471
  return foldState('D5', gate, checks, {
625
1472
  currentTreeHash: ctx.currentTreeHash ?? null,
626
1473
  freezeGates: /** @type {any} */ (ctx.freeze?.gates),
@@ -632,14 +1479,14 @@ export function checkD5Crosscut(ctx) {
632
1479
  // ---------------------------------------------------------------------------
633
1480
 
634
1481
  /**
635
- * D6 -- Consistency and satisfiability probe. 0.29.0 runs only the
636
- * validate-clean tree-wide check and the probe-ledger open count.
637
- *
638
- * SEAM 0.30: contradiction-lite across criteria on one story and
639
- * across their TACs' ADRs; unsatisfiable-lite (a `then` naming
640
- * undefined state); duplicate scan; orphan-interface scan;
641
- * regeneration probe runner injectable like `mutationRunner` in
642
- * src/review/index.js.
1482
+ * D6 -- Consistency and satisfiability probe. 0.29.0 ran the
1483
+ * validate-clean tree-wide check and the probe-ledger open count;
1484
+ * 0.30.0 PR 7 (ADR-4131 extended, spec section 4 row 'D6 scans and the
1485
+ * injectable probe runner') adds the four mechanical scans
1486
+ * consistency:contradictions, consistency:unsatisfiable,
1487
+ * consistency:duplicates and consistency:orphanInterfaces. The probe
1488
+ * runner lives on the readiness compute (TAC-4123); the gate reads the
1489
+ * merged probes.probes[] it ends up with.
643
1490
  *
644
1491
  * @param {StageContext} ctx
645
1492
  */
@@ -683,12 +1530,350 @@ export function checkD6Consistency(ctx) {
683
1530
  // uses a single representative entry regardless.
684
1531
  checks.push(makeCheck('consistency:probeCount', 'tree', Math.max(effectiveOpen, 1), failing, effectiveOpen));
685
1532
 
1533
+ // ADR-4131 extended (0.30.0 PR 7): the four D6 scans.
1534
+ const scope = asSet(ctx.scope);
1535
+ const tree = ctx.tree;
1536
+ const usInScope = (tree.userStories ?? []).filter((us) => scope.has(us.usId));
1537
+
1538
+ // Scan 1: consistency:contradictions (engineer, over delta). Two ACs
1539
+ // on one story share a `when` clause and one of their `then` clauses
1540
+ // is a negation of the other. The quoted-cue guard strips
1541
+ // double-quoted substrings before the negation scan so prose that
1542
+ // quotes a negation inside a `then` does not fire the check.
1543
+ /** @type {Array<{ id: string, why: string }>} */
1544
+ const contradictionFindings = [];
1545
+ let totalStoriesScanned = 0;
1546
+ for (const us of usInScope) {
1547
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1548
+ if (acs.length < 2) continue;
1549
+ totalStoriesScanned += 1;
1550
+ const parsed = acs
1551
+ .map((ac) => ({ ac, parts: parseWhenThen(ac?.description) }))
1552
+ .filter((p) => p.parts !== null);
1553
+ const reported = new Set();
1554
+ for (let i = 0; i < parsed.length; i += 1) {
1555
+ for (let j = i + 1; j < parsed.length; j += 1) {
1556
+ const a = parsed[i];
1557
+ const b = parsed[j];
1558
+ if (normaliseClause(a.parts.when) !== normaliseClause(b.parts.when)) continue;
1559
+ if (!thensNegateEachOther(a.parts.then, b.parts.then)) continue;
1560
+ const pairKey = `${us.usId}:${a.ac.id ?? '?'}:${b.ac.id ?? '?'}`;
1561
+ if (reported.has(pairKey)) continue;
1562
+ reported.add(pairKey);
1563
+ const idA = a.ac.id ?? us.usId;
1564
+ const idB = b.ac.id ?? us.usId;
1565
+ contradictionFindings.push({
1566
+ id: us.usId,
1567
+ why: `ACs ${idA} and ${idB} share a when clause with a negated then`,
1568
+ });
1569
+ }
1570
+ }
1571
+ }
1572
+ checks.push(makeCheck(
1573
+ 'consistency:contradictions',
1574
+ 'delta',
1575
+ Math.max(totalStoriesScanned, 1),
1576
+ contradictionFindings,
1577
+ ));
1578
+
1579
+ // Scan 2: consistency:unsatisfiable (engineer, over delta). A `then`
1580
+ // naming a field that no recordShape anywhere in the tree defines
1581
+ // fails the AC with id `<acId>:<field>`. A field defined in a
1582
+ // `[draft]` recordShape counts as defined (the engineer owns the
1583
+ // draft; its `fields:` list is honest about what the then may name).
1584
+ const definedFields = collectRecordShapeFields(tree);
1585
+ /** @type {Array<{ id: string, why: string }>} */
1586
+ const unsatisfiableFindings = [];
1587
+ let totalThenFieldChecks = 0;
1588
+ for (const us of usInScope) {
1589
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1590
+ for (const ac of acs) {
1591
+ const parts = parseWhenThen(ac?.description);
1592
+ if (!parts) continue;
1593
+ const fields = extractThenFieldTokens(parts.then);
1594
+ for (const field of fields) {
1595
+ totalThenFieldChecks += 1;
1596
+ if (definedFields.has(field)) continue;
1597
+ unsatisfiableFindings.push({
1598
+ id: `${ac.id ?? us.usId}:${field}`,
1599
+ why: `then names field ${field} that no recordShape defines`,
1600
+ });
1601
+ }
1602
+ }
1603
+ }
1604
+ checks.push(makeCheck(
1605
+ 'consistency:unsatisfiable',
1606
+ 'delta',
1607
+ Math.max(totalThenFieldChecks, 1),
1608
+ unsatisfiableFindings,
1609
+ ));
1610
+
1611
+ // Scan 3: consistency:duplicates (engineer, over tree). Identical AC
1612
+ // descriptions across stories fail both ACs. The comparison trims
1613
+ // leading whitespace and the leading `[class]` marker.
1614
+ /** @type {Map<string, Array<{ usId: string, acId: string }>>} */
1615
+ const descBuckets = new Map();
1616
+ const allUs = tree.userStories ?? [];
1617
+ let totalDupAcs = 0;
1618
+ for (const us of allUs) {
1619
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1620
+ for (const ac of acs) {
1621
+ const desc = typeof ac?.description === 'string' ? ac.description.trim() : '';
1622
+ if (desc.length === 0) continue;
1623
+ totalDupAcs += 1;
1624
+ const normalised = desc.replace(AC_CLASS_RE, '').trim().toLowerCase();
1625
+ if (normalised.length === 0) continue;
1626
+ const bucket = descBuckets.get(normalised) ?? [];
1627
+ bucket.push({ usId: us.usId, acId: ac.id ?? us.usId });
1628
+ descBuckets.set(normalised, bucket);
1629
+ }
1630
+ }
1631
+ /** @type {Array<{ id: string, why: string }>} */
1632
+ const duplicateFindings = [];
1633
+ for (const bucket of descBuckets.values()) {
1634
+ if (bucket.length < 2) continue;
1635
+ const stories = [...new Set(bucket.map((b) => b.usId))];
1636
+ if (stories.length < 2) continue;
1637
+ for (const entry of bucket) {
1638
+ duplicateFindings.push({
1639
+ id: entry.acId,
1640
+ why: `duplicate description (also on ${bucket.filter((b) => b.acId !== entry.acId).map((b) => b.acId).join(', ')})`,
1641
+ });
1642
+ }
1643
+ }
1644
+ checks.push(makeCheck(
1645
+ 'consistency:duplicates',
1646
+ 'tree',
1647
+ Math.max(totalDupAcs, 1),
1648
+ duplicateFindings,
1649
+ ));
1650
+
1651
+ // Scan 4: consistency:orphanInterfaces (engineer, over tree). An
1652
+ // interface on any TAC that no AC `ownerRef` points at AND that no
1653
+ // REQ `deliveredBy` reaches fails. Shares the `interfaces[<name>]`
1654
+ // pointer grammar with D4 `stories:ownerRefResolves`. A REQ's
1655
+ // `deliveredBy` reaches an interface when it names the owning TAC id
1656
+ // (either as a `tacId` string or as a `TAC-nnnn:<name>` pointer).
1657
+ const reachedInterfaces = collectReachedInterfaces(tree);
1658
+ /** @type {Array<{ id: string, why: string }>} */
1659
+ const orphanFindings = [];
1660
+ let totalInterfacesScanned = 0;
1661
+ for (const tac of tree.tacs ?? []) {
1662
+ const list = Array.isArray(tac?.interfaces) ? tac.interfaces : [];
1663
+ for (const iface of list) {
1664
+ const name = typeof iface?.name === 'string' ? iface.name : null;
1665
+ if (!name) continue;
1666
+ totalInterfacesScanned += 1;
1667
+ const key = `${tac.tacId}:${name}`;
1668
+ if (reachedInterfaces.has(key)) continue;
1669
+ orphanFindings.push({
1670
+ id: key,
1671
+ why: 'no AC ownerRef and no REQ deliveredBy reaches it',
1672
+ });
1673
+ }
1674
+ }
1675
+ checks.push(makeCheck(
1676
+ 'consistency:orphanInterfaces',
1677
+ 'tree',
1678
+ Math.max(totalInterfacesScanned, 1),
1679
+ orphanFindings,
1680
+ ));
1681
+
686
1682
  return foldState('D6', gate, checks, {
687
1683
  currentTreeHash: ctx.currentTreeHash ?? null,
688
1684
  freezeGates: /** @type {any} */ (ctx.freeze?.gates),
689
1685
  });
690
1686
  }
691
1687
 
1688
+ /**
1689
+ * Parse an AC description into { when, then } clause strings. Accepts
1690
+ * the common "given ... when ... then ..." shape used across the ACs
1691
+ * of this codebase; returns null when the description does not carry
1692
+ * both a `when` and a `then` segment. The leading `[class]` marker is
1693
+ * stripped before the scan. The match is case-insensitive on the
1694
+ * keywords only; the clause bodies keep their original casing.
1695
+ *
1696
+ * @param {unknown} desc
1697
+ * @returns {{ when: string, then: string } | null}
1698
+ */
1699
+ function parseWhenThen(desc) {
1700
+ if (typeof desc !== 'string' || desc.length === 0) return null;
1701
+ const stripped = desc.replace(AC_CLASS_RE, '').trim();
1702
+ const re = /\bwhen\b([\s\S]*?)\bthen\b([\s\S]*)$/i;
1703
+ const m = stripped.match(re);
1704
+ if (!m) return null;
1705
+ const when = m[1].trim();
1706
+ const then = m[2].trim();
1707
+ if (when.length === 0 || then.length === 0) return null;
1708
+ return { when, then };
1709
+ }
1710
+
1711
+ /**
1712
+ * Normalise a clause for the contradictions scan: lower-case, trim,
1713
+ * collapse whitespace. A clause is "the same" between two ACs when
1714
+ * their normalised forms match.
1715
+ *
1716
+ * @param {string} clause
1717
+ * @returns {string}
1718
+ */
1719
+ function normaliseClause(clause) {
1720
+ return clause.toLowerCase().replace(/\s+/g, ' ').trim();
1721
+ }
1722
+
1723
+ /**
1724
+ * Strip double-quoted substrings and then test whether one `then`
1725
+ * clause is the negation of the other. "Negation" is a cheap test: one
1726
+ * clause begins (or carries, after a verb) a `not`, `no`, `does not`,
1727
+ * `is not`, `never`, `must not` token where the other clause does not;
1728
+ * or the two clauses are the same body with one carrying such a token.
1729
+ * The quoted-substring strip is the shared guard with D4.
1730
+ *
1731
+ * @param {string} a
1732
+ * @param {string} b
1733
+ * @returns {boolean}
1734
+ */
1735
+ function thensNegateEachOther(a, b) {
1736
+ const aPlain = normaliseClause(stripQuotedSubstrings(a));
1737
+ const bPlain = normaliseClause(stripQuotedSubstrings(b));
1738
+ if (aPlain === bPlain) return false;
1739
+ const NEG_RE = /\b(?:not|no|never|does not|is not|must not|cannot|won't|will not)\b/;
1740
+ const aNeg = NEG_RE.test(aPlain);
1741
+ const bNeg = NEG_RE.test(bPlain);
1742
+ if (aNeg === bNeg) return false;
1743
+ // One side negates; test the negated body against the positive one.
1744
+ const positive = aNeg ? bPlain : aPlain;
1745
+ const negative = aNeg ? aPlain : bPlain;
1746
+ const negativeStripped = negative.replace(NEG_RE, '').replace(/\s+/g, ' ').trim();
1747
+ // A sufficiently similar body is "the same claim with a negation".
1748
+ // We treat the shorter being a prefix / suffix / substring of the
1749
+ // longer, or sharing 80% of its tokens, as "same body".
1750
+ if (negativeStripped.length === 0) return false;
1751
+ if (positive.includes(negativeStripped) || negativeStripped.includes(positive)) return true;
1752
+ const posTokens = new Set(positive.split(/\s+/).filter((t) => t.length > 2));
1753
+ const negTokens = negativeStripped.split(/\s+/).filter((t) => t.length > 2);
1754
+ if (negTokens.length === 0) return false;
1755
+ const shared = negTokens.filter((t) => posTokens.has(t)).length;
1756
+ return shared / negTokens.length >= 0.6;
1757
+ }
1758
+
1759
+ /**
1760
+ * Collect every field name defined by any `recordShape` interface in
1761
+ * the tree. A `fields:` marker in the interface description introduces
1762
+ * a list of field names; each name is a token on a bullet, a line, or
1763
+ * a comma-separated list. Draft recordShapes are included (the
1764
+ * engineer owns the draft and its fields: list is honest).
1765
+ *
1766
+ * @param {import('#core/store/walker.js').TreeModel} tree
1767
+ * @returns {Set<string>}
1768
+ */
1769
+ function collectRecordShapeFields(tree) {
1770
+ const out = new Set();
1771
+ for (const tac of tree.tacs ?? []) {
1772
+ for (const iface of tac.interfaces ?? []) {
1773
+ if (iface?.kind !== 'recordShape') continue;
1774
+ const desc = typeof iface?.description === 'string' ? iface.description : '';
1775
+ const stripped = stripDraftPrefix(desc);
1776
+ // Find the `fields:` segment and read until the next `:` or end.
1777
+ const match = stripped.match(/(^|\n)\s*(?:[-*]\s*)?fields\s*:\s*([\s\S]*?)(?=(?:\n\s*(?:[-*]\s*)?[a-zA-Z][a-zA-Z0-9_]*\s*:)|$)/);
1778
+ if (!match) continue;
1779
+ const body = match[2];
1780
+ for (const token of body.split(/[\s,]+/)) {
1781
+ const name = token.replace(/^[-*]/, '').replace(/[:(){}\[\]]/g, '').trim();
1782
+ if (!name) continue;
1783
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) out.add(name);
1784
+ }
1785
+ }
1786
+ }
1787
+ return out;
1788
+ }
1789
+
1790
+ /**
1791
+ * Pull field tokens out of a `then` clause. A field token is a word
1792
+ * that follows a verb like `set`, `write`, `include`, `return`,
1793
+ * `contain`, `name` or appears as the direct object of a `then`'s
1794
+ * verb phrase; a cheap approximation uses `then <subject> <verb>
1795
+ * <field>` plus `field <name>`, `<name> field` and `field: <name>`
1796
+ * patterns. The scan is deliberately conservative so a plain English
1797
+ * sentence yields a small set.
1798
+ *
1799
+ * @param {string} thenClause
1800
+ * @returns {string[]}
1801
+ */
1802
+ function extractThenFieldTokens(thenClause) {
1803
+ if (typeof thenClause !== 'string' || thenClause.length === 0) return [];
1804
+ const text = stripQuotedSubstrings(thenClause);
1805
+ /** @type {Set<string>} */
1806
+ const tokens = new Set();
1807
+ // Pattern 1: backticked identifier (`then `balance` is set`). The
1808
+ // primary signal; prose that quotes a field name under backticks is
1809
+ // the convention this check expects.
1810
+ for (const m of text.matchAll(/`([A-Za-z_][A-Za-z0-9_]*)`/g)) {
1811
+ if (m[1]) tokens.add(m[1]);
1812
+ }
1813
+ // Pattern 2: `<name> field` (adjective-form naming). An English
1814
+ // "stop word" skip keeps "the field", "a field" and "its field" from
1815
+ // tripping the check.
1816
+ const STOP = new Set(['the', 'a', 'an', 'this', 'that', 'its', 'our', 'their', 'any', 'no', 'some', 'each', 'every', 'another']);
1817
+ for (const m of text.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\s+field\b/g)) {
1818
+ const token = m[1];
1819
+ if (!token) continue;
1820
+ if (STOP.has(token.toLowerCase())) continue;
1821
+ tokens.add(token);
1822
+ }
1823
+ // Pattern 3: `field: <name>` or `field = <name>` (schema-like
1824
+ // notation inside a then clause).
1825
+ for (const m of text.matchAll(/\bfield\s*[:=]\s*([A-Za-z_][A-Za-z0-9_]*)/g)) {
1826
+ if (m[1]) tokens.add(m[1]);
1827
+ }
1828
+ return [...tokens];
1829
+ }
1830
+
1831
+ /**
1832
+ * Collect every interface the tree "reaches" from an AC `ownerRef` or
1833
+ * a REQ `deliveredBy` (REQ-174 companion field). The result is a Set
1834
+ * of `<tacId>:<name>` keys. A `deliveredBy` on a REQ can take two
1835
+ * shapes: an array of `TAC-nnnn:<name>` pointer strings, or an array
1836
+ * of plain TAC ids ("delivered by this TAC"); the second shape reaches
1837
+ * every interface on the named TAC.
1838
+ *
1839
+ * @param {import('#core/store/walker.js').TreeModel} tree
1840
+ * @returns {Set<string>}
1841
+ */
1842
+ function collectReachedInterfaces(tree) {
1843
+ const out = new Set();
1844
+ // AC ownerRefs.
1845
+ for (const us of tree.userStories ?? []) {
1846
+ const acs = Array.isArray(us.acceptanceCriteria) ? us.acceptanceCriteria : [];
1847
+ for (const ac of acs) {
1848
+ if (!acHasOwnerRef(ac)) continue;
1849
+ const ref = /** @type {any} */ (ac).ownerRef;
1850
+ const name = parseOwnerRefInterfaceField(ref?.field);
1851
+ if (!name || typeof ref?.tacId !== 'string') continue;
1852
+ out.add(`${ref.tacId}:${name}`);
1853
+ }
1854
+ }
1855
+ // REQ deliveredBy (optional field; shapes above).
1856
+ for (const req of tree.requirements ?? []) {
1857
+ const deliveredBy = /** @type {any} */ (req)?.deliveredBy;
1858
+ if (!Array.isArray(deliveredBy)) continue;
1859
+ for (const entry of deliveredBy) {
1860
+ if (typeof entry !== 'string' || entry.length === 0) continue;
1861
+ const m = entry.match(/^(TAC-[A-Za-z0-9-]+):(.+)$/);
1862
+ if (m) {
1863
+ out.add(`${m[1]}:${m[2]}`);
1864
+ continue;
1865
+ }
1866
+ // Plain TAC id: every interface on that TAC is reached.
1867
+ const tac = (tree.tacs ?? []).find((t) => t?.tacId === entry);
1868
+ if (!tac) continue;
1869
+ for (const iface of tac.interfaces ?? []) {
1870
+ if (typeof iface?.name === 'string') out.add(`${tac.tacId}:${iface.name}`);
1871
+ }
1872
+ }
1873
+ }
1874
+ return out;
1875
+ }
1876
+
692
1877
  // ---------------------------------------------------------------------------
693
1878
  // D7 -- Decisions and review (blocking in 0.29.0).
694
1879
  // ---------------------------------------------------------------------------
@@ -713,6 +1898,31 @@ export function checkD7Decisions(ctx) {
713
1898
  }
714
1899
 
715
1900
  const checks = [];
1901
+ // Check 1: `decisions:wellFormed` (productOwner, over tree) --
1902
+ // every decision is enumerated (ADR-4126, proposal section 1.3):
1903
+ // a non-empty question, at least two options, a default that
1904
+ // names one of the option letters.
1905
+ const wellFormedFail = [];
1906
+ for (const d of decisionEntries) {
1907
+ const why = 'decision is not enumerated (question, two or more options, a default)';
1908
+ const id = `decision:${d?.id ?? '?'}`;
1909
+ if (typeof d?.question !== 'string' || d.question.length === 0) {
1910
+ wellFormedFail.push({ id, why });
1911
+ continue;
1912
+ }
1913
+ if (!Array.isArray(d.options) || d.options.length < 2) {
1914
+ wellFormedFail.push({ id, why });
1915
+ continue;
1916
+ }
1917
+ const letters = new Set(d.options.map((o) => (o && typeof o === 'object') ? /** @type {any} */ (o).letter : undefined));
1918
+ if (typeof d.default !== 'string' || !letters.has(d.default)) {
1919
+ wellFormedFail.push({ id, why });
1920
+ }
1921
+ }
1922
+ checks.push(makeCheck('decisions:wellFormed', 'tree', decisionEntries.length, wellFormedFail));
1923
+
1924
+ // Check 2: `decisions:allAnswered` (engineer, over tree) -- zero
1925
+ // open decisions. The hand-over condition for build.
716
1926
  checks.push(makeCheck(
717
1927
  'decisions:allAnswered',
718
1928
  'tree',