rcf-lite 0.29.0 → 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.
- package/CHANGELOG.md +87 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-007.json +1 -1
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-009.json +1 -1
- package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +4 -4
- package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +2 -2
- package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +2 -2
- package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +7 -7
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +3 -15
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +2 -10
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25111.json +3 -6
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25112.json +4 -4
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-001.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-002.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-003.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-004.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-005.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-006.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-007.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-008.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-009.json +1 -1
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-014.json +1 -1
- package/blueprints/application-admin-console/contributions/tacs/tac-2201-application-admin-console-shell.json +4 -4
- package/blueprints/application-admin-console/contributions/tacs/tac-2202-application-admin-console-capability-discovery.json +7 -7
- package/blueprints/application-admin-console/contributions/tacs/tac-2203-application-admin-console-permission-matrix.json +2 -2
- package/blueprints/application-admin-console/contributions/tacs/tac-2204-application-admin-console-audit-view.json +2 -2
- package/blueprints/application-admin-console/contributions/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +3 -2
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21107.json +2 -2
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21111.json +3 -11
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21112.json +4 -4
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21815.json +2 -2
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21816.json +2 -2
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-001.json +1 -1
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-002.json +1 -2
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-004.json +1 -1
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-008.json +1 -1
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-016.json +1 -1
- package/blueprints/application-api-rest/contributions/tacs/tac-301-application-api-rest-request-pipeline.json +4 -4
- package/blueprints/application-api-rest/contributions/tacs/tac-302-application-api-rest-auth-middleware.json +4 -4
- package/blueprints/application-api-rest/contributions/tacs/tac-303-application-api-rest-contract-surface.json +4 -4
- package/blueprints/application-api-rest/contributions/tacs/tac-304-application-api-rest-resource-layer.json +4 -4
- package/blueprints/application-api-rest/contributions/tacs/tac-305-application-api-rest-observability.json +4 -4
- package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +4 -4
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2102.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2104.json +4 -4
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2105.json +2 -2
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2110.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2111.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2118.json +1 -1
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2119.json +2 -2
- package/blueprints/application-charts/contributions/tacs/tac-1901-application-charts-render-shell.json +4 -4
- package/blueprints/application-charts/contributions/tacs/tac-1902-application-charts-keyboard-traversal.json +4 -4
- package/blueprints/application-charts/contributions/user-stories/application-charts-us-18105.json +1 -1
- package/blueprints/application-dashboard/contributions/tacs/tac-2001-application-dashboard-tile-grid.json +4 -4
- package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +4 -4
- package/blueprints/application-dashboard/contributions/tacs/tac-2003-application-dashboard-export-handle.json +2 -2
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +1 -1
- package/blueprints/application-datatable/contributions/tacs/tac-1801-application-datatable-shell.json +4 -4
- package/blueprints/application-datatable/contributions/tacs/tac-1802-application-datatable-query-adapter.json +4 -4
- package/blueprints/application-datatable/contributions/tacs/tac-1803-application-datatable-selection-model.json +2 -2
- package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17101.json +1 -1
- package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17102.json +1 -1
- package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17103.json +1 -1
- package/blueprints/application-datatable/contributions/user-stories/application-datatable-us-17105.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +2 -2
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-006.json +1 -1
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-007.json +2 -2
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +5 -5
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +2 -2
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +5 -5
- package/blueprints/application-error-handling/contributions/tacs/tac-1701-application-error-handling-boundary.json +6 -6
- package/blueprints/application-error-handling/contributions/tacs/tac-1702-application-error-handling-record-factory.json +4 -4
- package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16101.json +1 -1
- package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16107.json +4 -4
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +1 -1
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +1 -1
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +1 -1
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +1 -1
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +1 -1
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-006.json +2 -2
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-007.json +2 -2
- package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +7 -7
- package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +8 -8
- package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +11 -11
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +1 -1
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +1 -1
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-006.json +2 -2
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +7 -7
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +4 -4
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +4 -4
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-001.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-002.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-003.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-004.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-005.json +2 -2
- package/blueprints/application-notifications-in-app/contributions/requirements/application-notifications-in-app-req-006.json +2 -2
- package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +6 -6
- package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +9 -9
- package/blueprints/application-notifications-in-app/contributions/tacs/tac-2103-application-notifications-in-app-preferences.json +4 -4
- package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20101.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20102.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20103.json +2 -2
- package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +4 -4
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-005.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-006.json +1 -1
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +4 -4
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +2 -2
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +2 -2
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26108.json +2 -2
- package/blueprints/application-spa/contributions/requirements/application-spa-req-004.json +1 -2
- package/blueprints/application-spa/contributions/requirements/application-spa-req-007.json +1 -1
- package/blueprints/application-spa/contributions/requirements/application-spa-req-014.json +1 -1
- package/blueprints/application-spa/contributions/requirements/application-spa-req-015.json +1 -1
- package/blueprints/application-spa/contributions/requirements/application-spa-req-017.json +1 -1
- package/blueprints/application-spa/contributions/requirements/application-spa-req-018.json +1 -1
- package/blueprints/application-spa/contributions/tacs/tac-201-application-spa-app-shell.json +4 -4
- package/blueprints/application-spa/contributions/tacs/tac-202-application-spa-theme-system.json +4 -4
- package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +6 -6
- package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +6 -6
- package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +6 -6
- package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +8 -8
- package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +8 -8
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1101.json +2 -2
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1102.json +1 -1
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1107.json +1 -1
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1117.json +1 -1
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1129.json +4 -4
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1130.json +4 -4
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +1 -1
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1132.json +6 -6
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1133.json +5 -5
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1134.json +2 -2
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-001.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-002.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-003.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-005.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-006.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-007.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-008.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-009.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-010.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-011.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-012.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-013.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-014.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-015.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-016.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-017.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-018.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-019.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-020.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-021.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-022.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-023.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-701-delivery-ci-workflows-gate-runner.json +6 -6
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-702-delivery-ci-workflows-gate-report.json +4 -4
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-703-delivery-ci-workflows-aggregate-report.json +4 -4
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-704-delivery-ci-workflows-workflow-materialiser.json +6 -6
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-705-delivery-ci-workflows-release-workflow.json +6 -6
- package/blueprints/delivery-ci-workflows/contributions/tacs/tac-706-delivery-ci-workflows-scheduled-audit.json +4 -4
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6101.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6102.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6103.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6104.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6106.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6107.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6109.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6110.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6111.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6113.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6115.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6116.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6117.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6118.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6119.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6120.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6122.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6123.json +1 -1
- package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6124.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-001.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-002.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-003.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-004.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-005.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-006.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-007.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-008.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-009.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-010.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-011.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-012.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-013.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-014.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1301-deploy-cloudflare-workers-deploy-adapter.json +6 -6
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1302-deploy-cloudflare-workers-wrangler-manifest.json +8 -8
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1303-deploy-cloudflare-workers-preview-url-resolver.json +6 -6
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1304-deploy-cloudflare-workers-promote-gate.json +8 -8
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1305-deploy-cloudflare-workers-served-surface-verifier.json +8 -8
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1306-deploy-cloudflare-workers-deploy-ci-workflows.json +8 -8
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12101.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12102.json +2 -2
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12105.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12109.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12113.json +2 -2
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12114.json +1 -1
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12115.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-001.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-002.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-003.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-004.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-005.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-006.json +1 -1
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json +3 -2
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +3 -2
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +3 -2
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +3 -2
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37101.json +4 -4
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37102.json +3 -3
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37103.json +4 -4
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37104.json +2 -2
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37105.json +2 -2
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37106.json +3 -3
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37107.json +2 -2
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37108.json +2 -2
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37109.json +2 -2
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-001.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-002.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-003.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-004.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-005.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-006.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-007.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +6 -4
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +3 -2
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +3 -2
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +3 -2
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34101.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34102.json +5 -5
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34103.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34104.json +3 -3
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34105.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34106.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34107.json +5 -5
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34110.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-001.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-002.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-003.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-004.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-005.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +6 -4
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +3 -2
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +3 -2
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36101.json +2 -2
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36103.json +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36104.json +6 -6
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36106.json +2 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-001.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-002.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-003.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-004.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-005.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-006.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-007.json +1 -1
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +3 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +3 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +3 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4004-edge-cloudflare-tunnel-zone-and-hostname-apply.json +3 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39101.json +3 -3
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39102.json +2 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39103.json +4 -4
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39104.json +2 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39105.json +2 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39106.json +5 -5
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39107.json +2 -2
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39108.json +3 -3
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39109.json +4 -4
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39110.json +3 -3
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-001.json +1 -1
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-002.json +1 -1
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-003.json +1 -1
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-004.json +1 -1
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-005.json +1 -1
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +3 -2
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +9 -6
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +3 -2
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35101.json +3 -3
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35102.json +4 -4
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35103.json +6 -6
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35104.json +2 -2
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35105.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-001.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-002.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-003.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-004.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-005.json +1 -1
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-006.json +1 -1
- package/blueprints/email-smtp-resend/contributions/tacs/tac-401-email-smtp-resend-send-adapter.json +8 -8
- package/blueprints/email-smtp-resend/contributions/tacs/tac-402-email-smtp-resend-webhook-verifier.json +10 -10
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4101.json +1 -1
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4102.json +1 -1
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4103.json +1 -1
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4105.json +1 -1
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4106.json +2 -2
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-001.json +1 -1
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-002.json +1 -1
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-003.json +1 -1
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-004.json +1 -1
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-005.json +1 -1
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-006.json +1 -1
- package/blueprints/jobs-background/contributions/tacs/tac-3101-jobs-background-job-definition.json +4 -4
- package/blueprints/jobs-background/contributions/tacs/tac-3102-jobs-background-scheduler.json +6 -6
- package/blueprints/jobs-background/contributions/tacs/tac-3103-jobs-background-run-log.json +6 -6
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30101.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30102.json +3 -3
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30103.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30104.json +4 -4
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30105.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30106.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30107.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30108.json +1 -1
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30109.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-001.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-002.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-003.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-004.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-005.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3001-messaging-queue-cloudflare-producer-facade.json +6 -6
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3002-messaging-queue-cloudflare-consumer-registration.json +2 -2
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3003-messaging-queue-cloudflare-event-sink.json +2 -2
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29101.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29102.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29103.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29104.json +2 -2
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29105.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29106.json +2 -2
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29107.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29108.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +1 -1
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-101.json +1 -1
- package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +6 -6
- package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +2 -2
- package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +2 -2
- package/blueprints/object-storage-s3/contributions/tacs/tac-2904-object-storage-s3-hetzner-endpoint-helper.json +2 -2
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +1 -1
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +1 -1
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +2 -2
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +1 -1
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +2 -2
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +1 -1
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28110.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-003.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-004.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-005.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-006.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-007.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-008.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-009.json +1 -1
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-010.json +1 -1
- package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +4 -4
- package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +12 -12
- package/blueprints/observability-essentials/contributions/tacs/tac-803-observability-essentials-status-page.json +6 -6
- package/blueprints/observability-essentials/contributions/tacs/tac-804-observability-essentials-notification-outcome.json +8 -8
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +1 -1
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7103.json +3 -3
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7106.json +2 -2
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7107.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-001.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-002.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-003.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-004.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-005.json +1 -1
- package/blueprints/observability-logging/contributions/requirements/observability-logging-req-006.json +8 -2
- package/blueprints/observability-logging/contributions/tacs/tac-1601-observability-logging-logger-factory.json +6 -6
- package/blueprints/observability-logging/contributions/tacs/tac-1602-observability-logging-redaction-boundary.json +2 -2
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15101.json +4 -4
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15103.json +2 -2
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15104.json +2 -2
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15105.json +1 -1
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15106.json +1 -1
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15107.json +2 -2
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15108.json +1 -1
- package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15109.json +3 -3
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-001.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-002.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-003.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-004.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-005.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-006.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-007.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-008.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1501-observability-probe-endpoints-profile-resolver.json +6 -6
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1502-observability-probe-endpoints-handler-set.json +4 -4
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1503-observability-probe-endpoints-listener-topology.json +6 -6
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json +4 -4
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14101.json +2 -2
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +1 -1
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14105.json +3 -3
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-001.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-002.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-003.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-004.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-005.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-006.json +1 -1
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-007.json +1 -1
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1401-persistence-data-d1-facade.json +6 -6
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1402-persistence-data-d1-migration-catalog.json +4 -4
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1403-persistence-data-d1-deploy-gate.json +4 -4
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1404-persistence-data-d1-recovery-runner.json +4 -4
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13101.json +2 -2
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13102.json +1 -1
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13107.json +2 -2
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +6 -6
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +4 -4
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +2 -2
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +4 -4
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +4 -4
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +2 -2
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-001.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-002.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-003.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-004.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-005.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-006.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-007.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-008.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-009.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-010.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-011.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-601-persistence-data-sqlite-store.json +6 -6
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-602-persistence-data-sqlite-migration-runner.json +2 -2
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-603-persistence-data-sqlite-migration-catalog.json +4 -4
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-604-persistence-data-sqlite-backup-runner.json +2 -2
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5101.json +2 -2
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5103.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5104.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5106.json +1 -1
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5110.json +2 -2
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5111.json +1 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-001.json +1 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-002.json +1 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-003.json +1 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-004.json +1 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json +6 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json +9 -2
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json +6 -1
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32101.json +6 -6
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32102.json +5 -5
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32103.json +3 -3
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32104.json +4 -4
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32105.json +4 -4
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32106.json +4 -4
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32107.json +3 -3
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-001.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-002.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-003.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-004.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-005.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-006.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-007.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-008.json +1 -1
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3401-platform-cloudflare-durable-objects-namespace-facade.json +6 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3402-platform-cloudflare-durable-objects-single-cell-shape.json +6 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3403-platform-cloudflare-durable-objects-alarm-handler.json +6 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3404-platform-cloudflare-durable-objects-websocket-hub.json +6 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3405-platform-cloudflare-durable-objects-event-sink.json +3 -2
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33101.json +5 -5
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33102.json +4 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33103.json +5 -5
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33104.json +5 -5
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33105.json +5 -5
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33106.json +4 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33107.json +3 -3
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33108.json +5 -5
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33109.json +3 -3
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33110.json +4 -4
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33111.json +3 -3
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33112.json +3 -3
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33113.json +5 -5
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-001.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-002.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-003.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-004.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-005.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-006.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-007.json +1 -1
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3201-platform-cloudflare-kv-facade.json +3 -2
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3202-platform-cloudflare-kv-cache-aside.json +3 -2
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3203-platform-cloudflare-kv-event-sink.json +3 -2
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31101.json +4 -4
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31102.json +3 -3
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31103.json +4 -4
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31104.json +4 -4
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31105.json +4 -4
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31106.json +3 -3
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31107.json +3 -3
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31108.json +3 -3
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31109.json +4 -4
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31110.json +5 -5
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31111.json +5 -5
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-007.json +1 -1
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +3 -2
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +3 -2
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +3 -2
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +3 -2
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +5 -5
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +4 -4
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +4 -4
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +4 -4
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +3 -3
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +3 -3
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +3 -3
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +3 -3
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +3 -3
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38110.json +3 -3
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-001.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-002.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-003.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-004.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-006.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-010.json +1 -1
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-011.json +1 -1
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1001-security-auth-clerk-middleware.json +6 -6
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1002-security-auth-clerk-authorisation-adapter.json +8 -3
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1003-security-auth-clerk-session-verifier.json +8 -8
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9102.json +1 -1
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9108.json +1 -1
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9112.json +6 -6
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9113.json +6 -6
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-002.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-003.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-004.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-005.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-006.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-011.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-013.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-014.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-015.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-016.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-017.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-018.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-019.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1201-security-auth-keycloak-discovery-client.json +10 -10
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1202-security-auth-keycloak-jwt-verifier.json +8 -8
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1203-security-auth-keycloak-introspection-client.json +8 -8
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1204-security-auth-keycloak-provider-router.json +6 -6
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1205-security-auth-keycloak-role-adapter.json +4 -4
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11102.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11103.json +2 -2
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11104.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11106.json +3 -3
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11111.json +2 -2
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11114.json +1 -1
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11115.json +5 -5
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11116.json +7 -7
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11117.json +7 -7
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11118.json +7 -7
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11119.json +7 -7
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11120.json +6 -6
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-002.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-003.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-004.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-005.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-008.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-009.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-010.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-011.json +1 -1
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-501-security-auth-magic-link-manager.json +6 -6
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-502-security-auth-magic-link-session-manager.json +6 -6
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-503-security-auth-magic-link-login-routes.json +10 -10
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-504-security-auth-magic-link-email-delivery-adapter.json +2 -2
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-505-security-auth-magic-link-principal-registry.json +2 -2
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3111.json +2 -2
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-002.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-003.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-005.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-006.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-008.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-009.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-011.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-012.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-013.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1101-security-auth-oauth2-flow-controller.json +24 -14
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1102-security-auth-oauth2-provider-adapter.json +4 -4
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1103-security-auth-oauth2-session-bridge.json +10 -10
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1104-security-auth-oauth2-provider-selector.json +8 -3
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10111.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10112.json +1 -1
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10114.json +5 -5
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-001.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-002.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-003.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-004.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-005.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-006.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-007.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-008.json +1 -1
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-009.json +1 -1
- package/blueprints/security-secrets-management/contributions/tacs/tac-901-security-secrets-management-manager-client.json +8 -8
- package/blueprints/security-secrets-management/contributions/tacs/tac-902-security-secrets-management-manifest.json +4 -4
- package/blueprints/security-secrets-management/contributions/tacs/tac-903-security-secrets-management-env-reflector.json +4 -4
- package/blueprints/security-secrets-management/contributions/tacs/tac-904-security-secrets-management-rotation-gate.json +8 -8
- package/blueprints/security-secrets-management/contributions/tacs/tac-905-security-secrets-management-agent-cli.json +4 -4
- package/fixtures/canary-manifest.json +6 -6
- package/guidance/define-litmus.md +102 -0
- package/guidance/manifest.json +2 -1
- package/package.json +1 -1
- package/rcf/adrs/adr-4131-gates-bite-ack-recorded-override.json +30 -0
- package/rcf/code-nodes/cn-753.json +19 -0
- package/rcf/code-nodes/cn-754.json +17 -0
- package/rcf/code-nodes/cn-755.json +14 -0
- package/rcf/code-nodes/cn-756.json +15 -0
- package/rcf/code-nodes/cn-757.json +21 -0
- package/rcf/code-nodes/cn-758.json +16 -0
- package/rcf/code-nodes/cn-759.json +21 -0
- package/rcf/code-nodes/cn-760.json +19 -0
- package/rcf/code-nodes/cn-761.json +16 -0
- package/rcf/code-nodes/cn-762.json +18 -0
- package/rcf/code-nodes/cn-763.json +18 -0
- package/rcf/code-nodes/cn-764.json +15 -0
- package/rcf/code-nodes/cn-765.json +23 -0
- package/rcf/code-nodes/cn-766.json +17 -0
- package/rcf/code-nodes/cn-767.json +17 -0
- package/rcf/code-nodes/cn-768.json +19 -0
- package/rcf/code-nodes/cn-769.json +17 -0
- package/rcf/code-nodes/cn-770.json +18 -0
- package/rcf/fbs/fbs-202.json +69 -9
- package/rcf/requirements/req-174.json +2 -2
- package/rcf/requirements/req-175.json +2 -2
- package/rcf/requirements/req-177.json +31 -0
- package/rcf/requirements/req-178.json +31 -0
- package/rcf/requirements/req-179.json +31 -0
- package/rcf/tacs/tac-001.json +7 -7
- package/rcf/tacs/tac-002.json +23 -23
- package/rcf/tacs/tac-003.json +5 -5
- package/rcf/tacs/tac-004.json +9 -9
- package/rcf/tacs/tac-005.json +7 -7
- package/rcf/tacs/tac-006.json +21 -21
- package/rcf/tacs/tac-007.json +7 -7
- package/rcf/tacs/tac-008.json +7 -7
- package/rcf/tacs/tac-4101-feedback-cli.json +5 -5
- package/rcf/tacs/tac-4102-feedback-store.json +9 -9
- package/rcf/tacs/tac-4103-feedback-redact.json +5 -5
- package/rcf/tacs/tac-4104-feedback-fingerprint.json +3 -3
- package/rcf/tacs/tac-4105-feedback-render.json +7 -7
- package/rcf/tacs/tac-4106-feedback-destination.json +5 -5
- package/rcf/tacs/tac-4107-feedback-gh.json +7 -7
- package/rcf/tacs/tac-4108-feedback-hook.json +7 -7
- package/rcf/tacs/tac-4121-define-ledgers.json +3 -2
- package/rcf/tacs/tac-4122-define-gates.json +31 -3
- package/rcf/tacs/tac-4123-define-readiness.json +29 -3
- package/rcf/tacs/tac-4125-build-bundle-refuse-override-skip.json +43 -0
- package/rcf/tacs/tac-4126-define-validate-findings.json +32 -0
- package/rcf/tacs/tac-4128-define-guidance.json +8 -2
- package/rcf/tacs/tac-4129-define-questions.json +3 -3
- package/rcf/tacs/tac-4134-wespa-host-fixture.json +9 -9
- package/rcf/test-suites/ts-222.json +4 -4
- package/rcf/test-suites/ts-228.json +4 -4
- package/rcf/test-suites/ts-230.json +76 -0
- package/rcf/test-suites/ts-231.json +104 -0
- package/rcf/test-suites/ts-232.json +109 -0
- package/rcf/test-suites/ts-233.json +61 -0
- package/rcf/test-suites/ts-234.json +53 -0
- package/rcf/test-suites/ts-235.json +53 -0
- package/rcf/user-stories/us-17404.json +51 -0
- package/rcf/user-stories/us-17405.json +61 -0
- package/rcf/user-stories/us-17406.json +51 -0
- package/rcf/user-stories/us-17503.json +2 -2
- package/rcf/user-stories/us-17504.json +46 -0
- package/rcf/user-stories/us-17702.json +51 -0
- package/rcf/user-stories/us-17802.json +40 -0
- package/rcf/user-stories/us-17902.json +46 -0
- package/releases/releases.yaml +11 -1
- package/src/blueprint/consistency-lint.js +72 -3
- package/src/cli/build.js +206 -3
- package/src/cli/freeze.js +68 -18
- package/src/cli/readiness.js +136 -35
- package/src/cli/validate.js +8 -0
- package/src/define/concern-catalogue.js +130 -0
- package/src/define/freeze-record.js +74 -0
- package/src/define/probe-runner.js +55 -0
- package/src/define/validate-findings.js +256 -0
- package/src/query/gates.js +947 -12
- package/src/query/index.js +6 -1
- package/src/query/readiness.js +179 -2
- package/src/query/refuse-on-admissibility.js +137 -4
- package/src/ruleset/ruleset.json +35 -0
package/src/query/gates.js
CHANGED
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
import { computeQueue } from '../build/queue.js';
|
|
47
47
|
import { isOptedOut } from '../req-baseline/opt-out.js';
|
|
48
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']);
|
|
@@ -113,26 +114,37 @@ export const CHECK_PERSONA = /** @type {const} */ ({
|
|
|
113
114
|
'brief:kinds': 'productOwner',
|
|
114
115
|
'brief:openQuestions': 'productOwner',
|
|
115
116
|
'brief:profile': 'productOwner',
|
|
116
|
-
// D2 Skeleton: resolvedBy + reqIntent are PO; reqShape, tadPersistence, deployAdr are engineer.
|
|
117
|
+
// D2 Skeleton: resolvedBy + reqIntent are PO; reqShape, tadPersistence, deployAdr, standardsCited are engineer.
|
|
117
118
|
'skeleton:resolvedBy': 'productOwner',
|
|
118
119
|
'skeleton:reqIntent': 'productOwner',
|
|
119
120
|
'skeleton:reqShape': 'engineer',
|
|
120
121
|
'skeleton:tadPersistence': 'engineer',
|
|
121
122
|
'skeleton:deployAdr': 'engineer',
|
|
123
|
+
'skeleton:standardsCited': 'engineer',
|
|
122
124
|
// D3 Shapes: every check is engineer (shapes are the engineer's first act after hand-over).
|
|
123
125
|
'shapes:tacHasInterface': 'engineer',
|
|
124
126
|
'shapes:kindVocabulary': 'engineer',
|
|
125
127
|
'shapes:draftSettled': 'engineer',
|
|
126
|
-
|
|
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.
|
|
127
132
|
'stories:reqHasUs': 'productOwner',
|
|
128
133
|
'stories:usFloors': 'engineer',
|
|
129
|
-
|
|
134
|
+
'stories:closedSets': 'engineer',
|
|
135
|
+
'stories:ownerRefResolves': 'engineer',
|
|
136
|
+
// D5 Crosscut: TAD + concern-ledger content and the catalogue walk are engineering.
|
|
130
137
|
'crosscut:securityArchitecture': 'engineer',
|
|
131
138
|
'crosscut:operationalConcerns': 'engineer',
|
|
132
139
|
'crosscut:concernsResolved': 'engineer',
|
|
133
|
-
|
|
140
|
+
'crosscut:catalogue': 'engineer',
|
|
141
|
+
// D6 Consistency: schema validity, probes and the four scans are engineer.
|
|
134
142
|
'consistency:validateClean': 'engineer',
|
|
135
143
|
'consistency:probeCount': 'engineer',
|
|
144
|
+
'consistency:contradictions': 'engineer',
|
|
145
|
+
'consistency:unsatisfiable': 'engineer',
|
|
146
|
+
'consistency:duplicates': 'engineer',
|
|
147
|
+
'consistency:orphanInterfaces': 'engineer',
|
|
136
148
|
// D7 Decisions: enumeration is PO (the PO answers or lets the default stand);
|
|
137
149
|
// zero-open is the engineer's hand-over condition.
|
|
138
150
|
'decisions:wellFormed': 'productOwner',
|
|
@@ -161,16 +173,27 @@ export const CHECK_QUESTION = /** @type {const} */ ({
|
|
|
161
173
|
'skeleton:reqShape': 'Every requirement in scope carries a shape classification.',
|
|
162
174
|
'skeleton:tadPersistence': 'TAD data architecture lists dataStores and coreEntities for persistence REQs.',
|
|
163
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.',
|
|
164
177
|
'shapes:tacHasInterface': 'Every TAC in scope has at least one interface.',
|
|
165
178
|
'shapes:kindVocabulary': 'Every interface kind is in the closed vocabulary.',
|
|
166
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.',
|
|
167
183
|
'stories:reqHasUs': 'What does someone do with this requirement?',
|
|
168
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.',
|
|
169
187
|
'crosscut:securityArchitecture': 'TAD.securityArchitecture is present when an auth or httpApi REQ exists.',
|
|
170
188
|
'crosscut:operationalConcerns': 'TAD.operationalConcerns is present when a deployed-scope AC exists.',
|
|
171
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.',
|
|
172
191
|
'consistency:validateClean': 'Validate is clean tree-wide.',
|
|
173
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.',
|
|
174
197
|
'decisions:wellFormed': 'Every decision is enumerated (question, two or more options, a default).',
|
|
175
198
|
'decisions:allAnswered': 'Zero decisions are open.',
|
|
176
199
|
'freeze:priorGates': 'Every prior stage passed or is acknowledged at the current hash.',
|
|
@@ -280,6 +303,118 @@ export function parseCoreEntityDraft(entity) {
|
|
|
280
303
|
return hasDraftMarker(/** @type {any} */ (entity).description);
|
|
281
304
|
}
|
|
282
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
|
+
|
|
283
418
|
/** Warn-with-ack stages in 0.29.0 (ADR-4122). */
|
|
284
419
|
const WARN_WITH_ACK = new Set(['D3', 'D5', 'D6']);
|
|
285
420
|
|
|
@@ -297,6 +432,21 @@ export function stagePolicy(stage) {
|
|
|
297
432
|
return WARN_WITH_ACK.has(stage) ? 'warnWithAck' : 'blocking';
|
|
298
433
|
}
|
|
299
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
|
+
|
|
300
450
|
/**
|
|
301
451
|
* Scaffold TODO placeholder marker: uppercase "TODO" followed by a
|
|
302
452
|
* colon, matching every scaffold string `rcf init` and `rcf define
|
|
@@ -313,6 +463,192 @@ const TODO_RE = /\bTODO:/;
|
|
|
313
463
|
/** Bracketed AC-class prefix (Baz decision 6, proposal §3.2 D4). */
|
|
314
464
|
const AC_CLASS_RE = /^\[(happy|edge|failure|must-not|non-functional)\]/;
|
|
315
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
|
+
|
|
316
652
|
/**
|
|
317
653
|
* Parse the leading bracketed class marker on `ac.description`.
|
|
318
654
|
* Returns the class token, or null when no marker is present.
|
|
@@ -435,6 +771,11 @@ function asSet(scope) {
|
|
|
435
771
|
* @property {{ skipReviewFor?: string } | undefined} profile parsed profile switches (light shape)
|
|
436
772
|
* @property {string | null | undefined} currentTreeHash for warn-with-ack acknowledgement match
|
|
437
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`.
|
|
438
779
|
*/
|
|
439
780
|
|
|
440
781
|
/**
|
|
@@ -621,6 +962,50 @@ export function checkD2Skeleton(ctx) {
|
|
|
621
962
|
else if (deployAdrs.length > 1) deployFail.push({ id: 'ADR:deploy', why: `${deployAdrs.length} Deploy ADRs found; expected exactly one` });
|
|
622
963
|
checks.push(makeCheck('skeleton:deployAdr', 'tree', 1, deployFail));
|
|
623
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
|
+
|
|
624
1009
|
return foldState('D2', gate, checks, {
|
|
625
1010
|
currentTreeHash: ctx.currentTreeHash ?? null,
|
|
626
1011
|
freezeGates: /** @type {any} */ (ctx.freeze?.gates),
|
|
@@ -722,6 +1107,106 @@ export function checkD3Shapes(ctx) {
|
|
|
722
1107
|
checks.push(makeCheck('shapes:kindVocabulary', 'delta', totalInterfaces, badKinds));
|
|
723
1108
|
checks.push(makeCheck('shapes:draftSettled', 'delta', totalDraftHomes, draftFindings));
|
|
724
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));
|
|
1209
|
+
|
|
725
1210
|
return foldState('D3', gate, checks, {
|
|
726
1211
|
currentTreeHash: ctx.currentTreeHash ?? null,
|
|
727
1212
|
freezeGates: /** @type {any} */ (ctx.freeze?.gates),
|
|
@@ -801,6 +1286,72 @@ export function checkD4Stories(ctx) {
|
|
|
801
1286
|
}
|
|
802
1287
|
checks.push(makeCheck('stories:usFloors', 'delta', usInScope.length, usFail));
|
|
803
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
|
+
|
|
804
1355
|
return foldState('D4', gate, checks, {
|
|
805
1356
|
currentTreeHash: ctx.currentTreeHash ?? null,
|
|
806
1357
|
freezeGates: /** @type {any} */ (ctx.freeze?.gates),
|
|
@@ -871,6 +1422,52 @@ export function checkD5Crosscut(ctx) {
|
|
|
871
1422
|
openInScope.map((c) => ({ id: `concern:${c.id}`, why: `open concern on ${c.reqId}: ${c.concern}` })),
|
|
872
1423
|
));
|
|
873
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
|
+
|
|
874
1471
|
return foldState('D5', gate, checks, {
|
|
875
1472
|
currentTreeHash: ctx.currentTreeHash ?? null,
|
|
876
1473
|
freezeGates: /** @type {any} */ (ctx.freeze?.gates),
|
|
@@ -882,14 +1479,14 @@ export function checkD5Crosscut(ctx) {
|
|
|
882
1479
|
// ---------------------------------------------------------------------------
|
|
883
1480
|
|
|
884
1481
|
/**
|
|
885
|
-
* D6 -- Consistency and satisfiability probe. 0.29.0
|
|
886
|
-
* validate-clean tree-wide check and the probe-ledger open count
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
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.
|
|
893
1490
|
*
|
|
894
1491
|
* @param {StageContext} ctx
|
|
895
1492
|
*/
|
|
@@ -933,12 +1530,350 @@ export function checkD6Consistency(ctx) {
|
|
|
933
1530
|
// uses a single representative entry regardless.
|
|
934
1531
|
checks.push(makeCheck('consistency:probeCount', 'tree', Math.max(effectiveOpen, 1), failing, effectiveOpen));
|
|
935
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
|
+
|
|
936
1682
|
return foldState('D6', gate, checks, {
|
|
937
1683
|
currentTreeHash: ctx.currentTreeHash ?? null,
|
|
938
1684
|
freezeGates: /** @type {any} */ (ctx.freeze?.gates),
|
|
939
1685
|
});
|
|
940
1686
|
}
|
|
941
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
|
+
|
|
942
1877
|
// ---------------------------------------------------------------------------
|
|
943
1878
|
// D7 -- Decisions and review (blocking in 0.29.0).
|
|
944
1879
|
// ---------------------------------------------------------------------------
|