rcf-lite 0.27.0 → 0.28.1
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 +39 -0
- package/README.md +19 -0
- package/bin/rcf.js +2 -0
- package/blueprints/application-account-settings/CHANGELOG.md +35 -6
- package/blueprints/application-account-settings/README.md +1 -1
- package/blueprints/application-account-settings/blueprint.json +4 -2
- package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +1 -1
- package/blueprints/application-account-settings/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-account-settings/contributions/probes/profile-form-autocomplete.mjs +67 -0
- package/blueprints/application-account-settings/contributions/probes/run-profile-form-autocomplete.mjs +5 -0
- package/blueprints/application-account-settings/contributions/probes/run-sessions-adapter-uniform.mjs +5 -0
- package/blueprints/application-account-settings/contributions/probes/run-sessions-surface-shape.mjs +5 -0
- package/blueprints/application-account-settings/contributions/probes/run-shell-tablist-per-capability.mjs +5 -0
- package/blueprints/application-account-settings/contributions/probes/run-theme-radiogroup.mjs +5 -0
- package/blueprints/application-account-settings/contributions/probes/sessions-adapter-uniform.mjs +130 -0
- package/blueprints/application-account-settings/contributions/probes/sessions-surface-shape.mjs +70 -0
- package/blueprints/application-account-settings/contributions/probes/shell-tablist-per-capability.mjs +60 -0
- package/blueprints/application-account-settings/contributions/probes/theme-radiogroup.mjs +126 -0
- package/blueprints/application-admin-console/CHANGELOG.md +32 -6
- package/blueprints/application-admin-console/README.md +1 -1
- package/blueprints/application-admin-console/blueprint.json +4 -2
- package/blueprints/application-admin-console/contributions/adrs/adr-2201-application-admin-console-capability-vocabulary.json +1 -1
- package/blueprints/application-admin-console/contributions/probes/audit-log-surface.mjs +79 -0
- package/blueprints/application-admin-console/contributions/probes/org-switcher-surface.mjs +83 -0
- package/blueprints/application-admin-console/contributions/probes/permission-matrix-grid.mjs +67 -0
- package/blueprints/application-admin-console/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-admin-console/contributions/probes/run-audit-log-surface.mjs +5 -0
- package/blueprints/application-admin-console/contributions/probes/run-org-switcher-surface.mjs +5 -0
- package/blueprints/application-admin-console/contributions/probes/run-permission-matrix-grid.mjs +5 -0
- package/blueprints/application-admin-console/contributions/probes/run-sign-in-access-gated-surface.mjs +5 -0
- package/blueprints/application-admin-console/contributions/probes/run-users-directory-surface.mjs +5 -0
- package/blueprints/application-admin-console/contributions/probes/sign-in-access-gated-surface.mjs +117 -0
- package/blueprints/application-admin-console/contributions/probes/users-directory-surface.mjs +145 -0
- package/blueprints/application-api-rest/CHANGELOG.md +16 -8
- package/blueprints/application-api-rest/README.md +3 -3
- package/blueprints/application-api-rest/blueprint.json +3 -2
- package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +1 -1
- package/blueprints/application-api-rest/contributions/probes/cursor-pagination-round-trip.mjs +154 -0
- package/blueprints/application-api-rest/contributions/probes/health-probes-distinct.mjs +124 -0
- package/blueprints/application-api-rest/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-api-rest/contributions/probes/problem-details-on-error.mjs +77 -0
- package/blueprints/application-api-rest/contributions/probes/request-id-echoed.mjs +76 -0
- package/blueprints/application-api-rest/contributions/probes/run-cursor-pagination-round-trip.mjs +5 -0
- package/blueprints/application-api-rest/contributions/probes/run-health-probes-distinct.mjs +5 -0
- package/blueprints/application-api-rest/contributions/probes/run-problem-details-on-error.mjs +5 -0
- package/blueprints/application-api-rest/contributions/probes/run-request-id-echoed.mjs +5 -0
- package/blueprints/application-api-rest/docs/topics.md +1 -1
- package/blueprints/application-charts/CHANGELOG.md +35 -9
- package/blueprints/application-charts/README.md +6 -6
- package/blueprints/application-charts/blueprint.json +5 -3
- package/blueprints/application-charts/contributions/adrs/adr-1901-application-charts-engine-choice.json +1 -1
- package/blueprints/application-charts/contributions/probes/keyboard-traversal.mjs +151 -0
- package/blueprints/application-charts/contributions/probes/non-colour-distinction.mjs +67 -0
- package/blueprints/application-charts/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-charts/contributions/probes/run-keyboard-traversal.mjs +5 -0
- package/blueprints/application-charts/contributions/probes/run-non-colour-distinction.mjs +5 -0
- package/blueprints/application-charts/contributions/probes/run-text-alternative-table.mjs +5 -0
- package/blueprints/application-charts/contributions/probes/text-alternative-table.mjs +139 -0
- package/blueprints/application-charts/contributions/requirements/application-charts-req-001.json +1 -1
- package/blueprints/application-charts/contributions/requirements/application-charts-req-002.json +1 -1
- package/blueprints/application-charts/contributions/user-stories/application-charts-us-18101.json +5 -5
- package/blueprints/application-charts/contributions/user-stories/application-charts-us-18106.json +1 -1
- package/blueprints/application-charts/guide/application-charts.md +1 -1
- package/blueprints/application-dashboard/CHANGELOG.md +20 -10
- package/blueprints/application-dashboard/README.md +6 -6
- package/blueprints/application-dashboard/assets/guidance/dashboard-design.md +2 -2
- package/blueprints/application-dashboard/blueprint.json +3 -2
- package/blueprints/application-dashboard/contributions/adrs/adr-2001-application-dashboard-primary-kpi-enum.json +1 -1
- package/blueprints/application-dashboard/contributions/adrs/adr-2002-application-dashboard-timeframe-presets.json +1 -1
- package/blueprints/application-dashboard/contributions/probes/export-handle-formats.mjs +75 -0
- package/blueprints/application-dashboard/contributions/probes/four-tile-states.mjs +75 -0
- package/blueprints/application-dashboard/contributions/probes/primary-kpi-top-left.mjs +58 -0
- package/blueprints/application-dashboard/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-dashboard/contributions/probes/run-export-handle-formats.mjs +4 -0
- package/blueprints/application-dashboard/contributions/probes/run-four-tile-states.mjs +4 -0
- package/blueprints/application-dashboard/contributions/probes/run-primary-kpi-top-left.mjs +4 -0
- package/blueprints/application-dashboard/contributions/probes/run-shell-five-regions.mjs +4 -0
- package/blueprints/application-dashboard/contributions/probes/shell-five-regions.mjs +93 -0
- package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-002.json +1 -1
- package/blueprints/application-dashboard/contributions/requirements/application-dashboard-req-003.json +1 -1
- package/blueprints/application-dashboard/contributions/tacs/tac-2002-application-dashboard-filter-chrome.json +1 -1
- 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-19101.json +2 -2
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19102.json +2 -2
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19103.json +1 -1
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19104.json +1 -1
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19105.json +1 -1
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19106.json +2 -2
- package/blueprints/application-dashboard/contributions/user-stories/application-dashboard-us-19107.json +5 -5
- package/blueprints/application-dashboard/docs/topics.md +2 -2
- package/blueprints/application-dashboard/guide/application-dashboard.md +2 -2
- package/blueprints/application-datatable/CHANGELOG.md +19 -9
- package/blueprints/application-datatable/README.md +2 -2
- package/blueprints/application-datatable/blueprint.json +3 -2
- package/blueprints/application-datatable/contributions/probes/apg-table-shape.mjs +57 -0
- package/blueprints/application-datatable/contributions/probes/four-states-regions.mjs +80 -0
- package/blueprints/application-datatable/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-datatable/contributions/probes/run-apg-table-shape.mjs +4 -0
- package/blueprints/application-datatable/contributions/probes/run-four-states-regions.mjs +4 -0
- package/blueprints/application-datatable/contributions/probes/run-search-adapter-round-trip.mjs +4 -0
- package/blueprints/application-datatable/contributions/probes/run-sort-adapter-round-trip.mjs +4 -0
- package/blueprints/application-datatable/contributions/probes/search-adapter-round-trip.mjs +58 -0
- package/blueprints/application-datatable/contributions/probes/sort-adapter-round-trip.mjs +60 -0
- package/blueprints/application-datatable/contributions/requirements/application-datatable-req-006.json +1 -1
- package/blueprints/application-datatable/docs/topics.md +1 -1
- package/blueprints/application-empty-error-states/CHANGELOG.md +33 -3
- package/blueprints/application-empty-error-states/blueprint.json +4 -2
- package/blueprints/application-empty-error-states/contributions/probes/empty-list-and-no-search.mjs +66 -0
- package/blueprints/application-empty-error-states/contributions/probes/error-boundary-alert.mjs +65 -0
- package/blueprints/application-empty-error-states/contributions/probes/forbidden-and-server-error.mjs +167 -0
- package/blueprints/application-empty-error-states/contributions/probes/not-found-and-recovery.mjs +61 -0
- package/blueprints/application-empty-error-states/contributions/probes/permission-denied-and-offline.mjs +155 -0
- package/blueprints/application-empty-error-states/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-empty-error-states/contributions/probes/run-empty-list-and-no-search.mjs +5 -0
- package/blueprints/application-empty-error-states/contributions/probes/run-error-boundary-alert.mjs +5 -0
- package/blueprints/application-empty-error-states/contributions/probes/run-forbidden-and-server-error.mjs +5 -0
- package/blueprints/application-empty-error-states/contributions/probes/run-not-found-and-recovery.mjs +5 -0
- package/blueprints/application-empty-error-states/contributions/probes/run-permission-denied-and-offline.mjs +5 -0
- package/blueprints/application-error-handling/CHANGELOG.md +45 -6
- package/blueprints/application-error-handling/blueprint.json +3 -2
- package/blueprints/application-error-handling/contributions/probes/category-vocabulary.mjs +90 -0
- package/blueprints/application-error-handling/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-error-handling/contributions/probes/record-shape-adr-1701.mjs +78 -0
- package/blueprints/application-error-handling/contributions/probes/run-category-vocabulary.mjs +5 -0
- package/blueprints/application-error-handling/contributions/probes/run-record-shape-adr-1701.mjs +5 -0
- package/blueprints/application-error-handling/contributions/probes/run-two-boundaries-registered.mjs +5 -0
- package/blueprints/application-error-handling/contributions/probes/two-boundaries-registered.mjs +343 -0
- package/blueprints/application-file-upload/CHANGELOG.md +28 -6
- package/blueprints/application-file-upload/README.md +1 -1
- package/blueprints/application-file-upload/blueprint.json +3 -2
- package/blueprints/application-file-upload/contributions/probes/assertive-completion-slot.mjs +78 -0
- package/blueprints/application-file-upload/contributions/probes/chunked-transport-endpoints.mjs +173 -0
- package/blueprints/application-file-upload/contributions/probes/per-file-progressbar.mjs +124 -0
- package/blueprints/application-file-upload/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-file-upload/contributions/probes/run-assertive-completion-slot.mjs +4 -0
- package/blueprints/application-file-upload/contributions/probes/run-chunked-transport-endpoints.mjs +4 -0
- package/blueprints/application-file-upload/contributions/probes/run-per-file-progressbar.mjs +4 -0
- package/blueprints/application-file-upload/contributions/probes/run-upload-surface-shape.mjs +4 -0
- package/blueprints/application-file-upload/contributions/probes/upload-surface-shape.mjs +55 -0
- 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/probe-packs/application-file-upload.pack.mjs +1 -1
- package/blueprints/application-forms-wizard/CHANGELOG.md +20 -6
- package/blueprints/application-forms-wizard/README.md +2 -2
- package/blueprints/application-forms-wizard/blueprint.json +3 -2
- package/blueprints/application-forms-wizard/contributions/probes/draft-persistence-round-trip.mjs +110 -0
- package/blueprints/application-forms-wizard/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-forms-wizard/contributions/probes/run-draft-persistence-round-trip.mjs +4 -0
- package/blueprints/application-forms-wizard/contributions/probes/run-step-page-shape.mjs +4 -0
- package/blueprints/application-forms-wizard/contributions/probes/run-task-list-surface.mjs +4 -0
- package/blueprints/application-forms-wizard/contributions/probes/step-page-shape.mjs +61 -0
- package/blueprints/application-forms-wizard/contributions/probes/task-list-surface.mjs +109 -0
- 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/probe-packs/application-forms-wizard.pack.mjs +1 -1
- package/blueprints/application-notifications-in-app/CHANGELOG.md +38 -5
- package/blueprints/application-notifications-in-app/README.md +4 -4
- package/blueprints/application-notifications-in-app/blueprint.json +4 -2
- package/blueprints/application-notifications-in-app/contributions/adrs/adr-2101-application-notifications-in-app-live-region-role-mapping.json +1 -1
- package/blueprints/application-notifications-in-app/contributions/probes/centre-acknowledge-round-trip.mjs +210 -0
- package/blueprints/application-notifications-in-app/contributions/probes/live-region-preseeding.mjs +93 -0
- package/blueprints/application-notifications-in-app/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-notifications-in-app/contributions/probes/run-centre-acknowledge-round-trip.mjs +5 -0
- package/blueprints/application-notifications-in-app/contributions/probes/run-live-region-preseeding.mjs +5 -0
- package/blueprints/application-notifications-in-app/contributions/probes/run-toast-contract.mjs +5 -0
- package/blueprints/application-notifications-in-app/contributions/probes/toast-contract.mjs +92 -0
- package/blueprints/application-notifications-in-app/contributions/tacs/tac-2101-application-notifications-in-app-live-region.json +3 -3
- package/blueprints/application-notifications-in-app/contributions/tacs/tac-2102-application-notifications-in-app-centre.json +1 -1
- 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 +1 -1
- package/blueprints/application-notifications-in-app/contributions/user-stories/application-notifications-in-app-us-20105.json +1 -1
- package/blueprints/application-notifications-in-app/guide/application-notifications-in-app.md +3 -3
- package/blueprints/application-onboarding-tour/CHANGELOG.md +31 -5
- package/blueprints/application-onboarding-tour/README.md +1 -1
- package/blueprints/application-onboarding-tour/blueprint.json +5 -3
- package/blueprints/application-onboarding-tour/contributions/probes/checklist-anchor-open.mjs +81 -0
- package/blueprints/application-onboarding-tour/contributions/probes/completion-persistence.mjs +159 -0
- package/blueprints/application-onboarding-tour/contributions/probes/first-run-detection.mjs +67 -0
- package/blueprints/application-onboarding-tour/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-onboarding-tour/contributions/probes/run-checklist-anchor-open.mjs +5 -0
- package/blueprints/application-onboarding-tour/contributions/probes/run-completion-persistence.mjs +5 -0
- package/blueprints/application-onboarding-tour/contributions/probes/run-first-run-detection.mjs +5 -0
- package/blueprints/application-onboarding-tour/contributions/probes/run-stepper-role-dialog.mjs +5 -0
- package/blueprints/application-onboarding-tour/contributions/probes/stepper-role-dialog.mjs +45 -0
- package/blueprints/application-spa/CHANGELOG.md +20 -11
- package/blueprints/application-spa/README.md +9 -10
- package/blueprints/application-spa/blueprint.json +3 -2
- package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +1 -1
- package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +1 -1
- package/blueprints/application-spa/contributions/probes/designed-empty-state.mjs +72 -0
- package/blueprints/application-spa/contributions/probes/probe-utils.mjs +177 -0
- package/blueprints/application-spa/contributions/probes/route-inventory-published.mjs +185 -0
- package/blueprints/application-spa/contributions/probes/run-designed-empty-state.mjs +5 -0
- package/blueprints/application-spa/contributions/probes/run-route-inventory-published.mjs +5 -0
- package/blueprints/application-spa/contributions/probes/run-shell-nav-present.mjs +5 -0
- package/blueprints/application-spa/contributions/probes/shell-nav-present.mjs +69 -0
- package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +1 -1
- package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +2 -2
- package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +3 -3
- package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +2 -2
- package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +2 -2
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +1 -1
- package/blueprints/application-spa/docs/topics.md +1 -1
- package/blueprints/delivery-ci-workflows/CHANGELOG.md +31 -11
- package/blueprints/delivery-ci-workflows/README.md +3 -3
- package/blueprints/delivery-ci-workflows/blueprint.json +3 -2
- package/blueprints/delivery-ci-workflows/contributions/adrs/adr-702-delivery-ci-workflows-strict-coverage-gate.json +2 -2
- package/blueprints/delivery-ci-workflows/contributions/probes/node-gate-entrypoint.mjs +76 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/probe-utils.mjs +56 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/real-account-github-actions-run-record.mjs +139 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/run-node-gate-entrypoint.mjs +3 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/run-real-account-github-actions-run-record.mjs +3 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/run-workflow-template-shape.mjs +3 -0
- package/blueprints/delivery-ci-workflows/contributions/probes/workflow-template-shape.mjs +94 -0
- package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +1 -1
- package/blueprints/delivery-ci-workflows/docs/topics.md +2 -3
- package/blueprints/deploy-cloudflare-workers/CHANGELOG.md +4 -4
- package/blueprints/deploy-cloudflare-workers/README.md +3 -3
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1306-deploy-cloudflare-workers-spa-shape.json +2 -2
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
- package/blueprints/deploy-hetzner-server/CHANGELOG.md +98 -7
- package/blueprints/deploy-hetzner-server/blueprint.json +7 -6
- package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +46 -21
- package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +344 -83
- package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +211 -42
- package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +140 -22
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +111 -30
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +158 -30
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +154 -32
- package/blueprints/edge-cloudflare-access/CHANGELOG.md +6 -5
- package/blueprints/edge-cloudflare-access/blueprint.json +1 -1
- package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +9 -1
- package/blueprints/edge-cloudflare-access/docs/topics.md +1 -1
- package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +4 -7
- package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +1 -1
- package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +4 -6
- package/blueprints/edge-cloudflare-tunnel/README.md +1 -2
- package/blueprints/edge-cloudflare-tunnel/docs/topics.md +1 -1
- package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +2 -3
- package/blueprints/edge-cloudflare-turnstile/docs/topics.md +1 -1
- package/blueprints/email-smtp-resend/CHANGELOG.md +24 -8
- package/blueprints/email-smtp-resend/README.md +2 -2
- package/blueprints/email-smtp-resend/blueprint.json +3 -2
- package/blueprints/email-smtp-resend/contributions/probes/probe-utils.mjs +50 -0
- package/blueprints/email-smtp-resend/contributions/probes/real-account-resend-send.mjs +50 -0
- package/blueprints/email-smtp-resend/contributions/probes/run-real-account-resend-send.mjs +3 -0
- package/blueprints/email-smtp-resend/contributions/probes/run-smtp-round-trip.mjs +3 -0
- package/blueprints/email-smtp-resend/contributions/probes/run-unverified-sender-refusal.mjs +3 -0
- package/blueprints/email-smtp-resend/contributions/probes/smtp-round-trip.mjs +43 -0
- package/blueprints/email-smtp-resend/contributions/probes/unverified-sender-refusal.mjs +99 -0
- package/blueprints/email-smtp-resend/docs/topics.md +2 -3
- package/blueprints/jobs-background/CHANGELOG.md +66 -5
- package/blueprints/jobs-background/README.md +2 -2
- package/blueprints/jobs-background/blueprint.json +3 -2
- package/blueprints/jobs-background/contributions/probes/apply-time-override.mjs +38 -10
- package/blueprints/jobs-background/contributions/probes/apply-time-refusal.mjs +28 -6
- package/blueprints/jobs-background/contributions/probes/event-secrecy.mjs +16 -2
- package/blueprints/jobs-background/contributions/probes/fake-clock-cron.mjs +102 -21
- package/blueprints/jobs-background/contributions/probes/probe-utils.mjs +10 -2
- package/blueprints/jobs-background/contributions/probes/retry-and-fail-real-account.mjs +355 -0
- package/blueprints/jobs-background/contributions/probes/retry-and-fail.mjs +33 -2
- package/blueprints/jobs-background/contributions/probes/run-retry-and-fail-real-account.mjs +12 -0
- package/blueprints/jobs-background/docs/topics.md +1 -1
- package/blueprints/jobs-background/guide/jobs-background.md +1 -1
- package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +25 -19
- package/blueprints/messaging-queue-cloudflare/README.md +12 -12
- package/blueprints/messaging-queue-cloudflare/blueprint.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3001-messaging-queue-cloudflare-adapter.json +2 -2
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3002-messaging-queue-cloudflare-delivery-semantics.json +1 -1
- package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +180 -12
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +1 -1
- package/blueprints/messaging-queue-cloudflare/docs/topics.md +2 -2
- package/blueprints/messaging-queue-cloudflare/guide/messaging-queue-cloudflare.md +2 -2
- package/blueprints/object-storage-s3/CHANGELOG.md +75 -4
- package/blueprints/object-storage-s3/blueprint.json +3 -2
- package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +73 -12
- package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +55 -7
- package/blueprints/object-storage-s3/contributions/probes/hetzner-object-storage-round-trip.mjs +102 -18
- package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +105 -36
- package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +104 -55
- package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +129 -7
- package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +80 -18
- package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +291 -37
- package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +8 -2
- package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +5 -5
- package/blueprints/object-storage-s3/contributions/probes/run-hetzner-object-storage-round-trip.mjs +8 -5
- package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +8 -2
- package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +8 -2
- package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +6 -3
- package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +10 -2
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +1 -1
- package/blueprints/object-storage-s3/docs/topics.md +1 -1
- package/blueprints/object-storage-s3/guide/object-storage-s3.md +1 -1
- package/blueprints/observability-essentials/CHANGELOG.md +23 -7
- package/blueprints/observability-essentials/README.md +2 -2
- package/blueprints/observability-essentials/assets/probe-samples/probe-response-baseline.v2.json +1 -1
- package/blueprints/observability-essentials/blueprint.json +3 -2
- package/blueprints/observability-essentials/contributions/probes/liveness-probe.mjs +84 -0
- package/blueprints/observability-essentials/contributions/probes/metrics-endpoint.mjs +96 -0
- package/blueprints/observability-essentials/contributions/probes/probe-utils.mjs +52 -0
- package/blueprints/observability-essentials/contributions/probes/readiness-probe.mjs +171 -0
- package/blueprints/observability-essentials/contributions/probes/run-liveness-probe.mjs +3 -0
- package/blueprints/observability-essentials/contributions/probes/run-metrics-endpoint.mjs +3 -0
- package/blueprints/observability-essentials/contributions/probes/run-readiness-probe.mjs +3 -0
- package/blueprints/observability-essentials/docs/topics.md +2 -3
- package/blueprints/observability-logging/CHANGELOG.md +29 -4
- package/blueprints/observability-logging/README.md +2 -2
- package/blueprints/observability-logging/blueprint.json +3 -2
- package/blueprints/observability-logging/contributions/probes/correlation-id-flow.mjs +173 -0
- package/blueprints/observability-logging/contributions/probes/line-shape-and-fields.mjs +82 -0
- package/blueprints/observability-logging/contributions/probes/probe-utils.mjs +47 -0
- package/blueprints/observability-logging/contributions/probes/redaction-boundary.mjs +130 -0
- package/blueprints/observability-logging/contributions/probes/run-correlation-id-flow.mjs +3 -0
- package/blueprints/observability-logging/contributions/probes/run-line-shape-and-fields.mjs +3 -0
- package/blueprints/observability-logging/contributions/probes/run-redaction-boundary.mjs +3 -0
- package/blueprints/observability-probe-endpoints/CHANGELOG.md +23 -8
- package/blueprints/observability-probe-endpoints/README.md +3 -3
- package/blueprints/observability-probe-endpoints/blueprint.json +3 -2
- package/blueprints/observability-probe-endpoints/contributions/probes/kubernetes-startup-enabled.mjs +80 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/partial-profile-refusal.mjs +101 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/probe-utils.mjs +49 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/profile-boot-materialisation.mjs +69 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/run-kubernetes-startup-enabled.mjs +3 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/run-partial-profile-refusal.mjs +3 -0
- package/blueprints/observability-probe-endpoints/contributions/probes/run-profile-boot-materialisation.mjs +3 -0
- package/blueprints/observability-probe-endpoints/docs/topics.md +2 -2
- package/blueprints/persistence-data-d1/CHANGELOG.md +16 -3
- package/blueprints/persistence-data-d1/README.md +2 -2
- package/blueprints/persistence-data-d1/blueprint.json +3 -2
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +1 -1
- package/blueprints/persistence-data-d1/contributions/probes/facade-round-trip.mjs +140 -0
- package/blueprints/persistence-data-d1/contributions/probes/migrations-forward-only.mjs +66 -0
- package/blueprints/persistence-data-d1/contributions/probes/probe-utils.mjs +51 -0
- package/blueprints/persistence-data-d1/contributions/probes/real-account-d1-round-trip.mjs +133 -0
- package/blueprints/persistence-data-d1/contributions/probes/run-facade-round-trip.mjs +3 -0
- package/blueprints/persistence-data-d1/contributions/probes/run-migrations-forward-only.mjs +3 -0
- package/blueprints/persistence-data-d1/contributions/probes/run-real-account-d1-round-trip.mjs +3 -0
- package/blueprints/persistence-data-d1/docs/topics.md +2 -3
- package/blueprints/persistence-data-postgres/CHANGELOG.md +84 -4
- package/blueprints/persistence-data-postgres/README.md +2 -2
- package/blueprints/persistence-data-postgres/blueprint.json +3 -2
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +1 -1
- package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +87 -12
- package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +245 -19
- package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +109 -26
- package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +151 -38
- package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +24 -6
- package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +261 -48
- package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +76 -20
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +1 -1
- package/blueprints/persistence-data-postgres/docs/topics.md +1 -1
- package/blueprints/persistence-data-sqlite/CHANGELOG.md +16 -2
- package/blueprints/persistence-data-sqlite/README.md +2 -2
- package/blueprints/persistence-data-sqlite/blueprint.json +3 -2
- package/blueprints/persistence-data-sqlite/contributions/probes/boot-open-migrate.mjs +90 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/facade-round-trip.mjs +82 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/probe-utils.mjs +83 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/run-boot-open-migrate.mjs +5 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/run-facade-round-trip.mjs +5 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/run-wal-checkpoint.mjs +5 -0
- package/blueprints/persistence-data-sqlite/contributions/probes/wal-checkpoint.mjs +137 -0
- package/blueprints/persistence-data-sqlite/docs/topics.md +2 -3
- package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +5 -5
- package/blueprints/platform-cloudflare-cron-triggers/README.md +2 -3
- package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +1 -1
- package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +6 -10
- package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +1 -1
- package/blueprints/platform-cloudflare-kv/CHANGELOG.md +16 -12
- package/blueprints/platform-cloudflare-kv/README.md +2 -4
- package/blueprints/platform-cloudflare-kv/blueprint.json +2 -2
- package/blueprints/platform-cloudflare-kv/docs/topics.md +1 -1
- package/blueprints/platform-docker-compose-host/CHANGELOG.md +92 -5
- package/blueprints/platform-docker-compose-host/blueprint.json +2 -2
- package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +116 -29
- package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +181 -109
- package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +146 -26
- package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +238 -24
- package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +207 -21
- package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +246 -42
- package/blueprints/platform-docker-compose-host/docs/topics.md +1 -1
- package/blueprints/security-auth-clerk/CHANGELOG.md +18 -6
- package/blueprints/security-auth-clerk/README.md +3 -3
- package/blueprints/security-auth-clerk/assets/wiring/workers-wrangler-toml-shape.md +1 -1
- package/blueprints/security-auth-clerk/blueprint.json +3 -2
- package/blueprints/security-auth-clerk/contributions/probes/hosted-identity-ui-config.mjs +61 -0
- package/blueprints/security-auth-clerk/contributions/probes/probe-utils.mjs +188 -0
- package/blueprints/security-auth-clerk/contributions/probes/real-account-principal-directory-round-trip.mjs +216 -0
- package/blueprints/security-auth-clerk/contributions/probes/real-account-session-inventory.mjs +260 -0
- package/blueprints/security-auth-clerk/contributions/probes/role-model-adapter.mjs +53 -0
- package/blueprints/security-auth-clerk/contributions/probes/run-hosted-identity-ui-config.mjs +4 -0
- package/blueprints/security-auth-clerk/contributions/probes/run-real-account-principal-directory-round-trip.mjs +4 -0
- package/blueprints/security-auth-clerk/contributions/probes/run-real-account-session-inventory.mjs +4 -0
- package/blueprints/security-auth-clerk/contributions/probes/run-role-model-adapter.mjs +4 -0
- package/blueprints/security-auth-clerk/docs/topics.md +2 -3
- package/blueprints/security-auth-keycloak/CHANGELOG.md +18 -7
- package/blueprints/security-auth-keycloak/README.md +2 -2
- package/blueprints/security-auth-keycloak/blueprint.json +3 -2
- package/blueprints/security-auth-keycloak/contributions/probes/discovery-shape.mjs +68 -0
- package/blueprints/security-auth-keycloak/contributions/probes/introspection-shape.mjs +88 -0
- package/blueprints/security-auth-keycloak/contributions/probes/jwt-verifier-shape.mjs +86 -0
- package/blueprints/security-auth-keycloak/contributions/probes/probe-utils.mjs +180 -0
- package/blueprints/security-auth-keycloak/contributions/probes/real-account-realm-round-trip.mjs +91 -0
- package/blueprints/security-auth-keycloak/contributions/probes/role-adapter-shape.mjs +69 -0
- package/blueprints/security-auth-keycloak/contributions/probes/run-discovery-shape.mjs +4 -0
- package/blueprints/security-auth-keycloak/contributions/probes/run-introspection-shape.mjs +4 -0
- package/blueprints/security-auth-keycloak/contributions/probes/run-jwt-verifier-shape.mjs +4 -0
- package/blueprints/security-auth-keycloak/contributions/probes/run-real-account-realm-round-trip.mjs +4 -0
- package/blueprints/security-auth-keycloak/contributions/probes/run-role-adapter-shape.mjs +4 -0
- package/blueprints/security-auth-keycloak/docs/topics.md +1 -2
- package/blueprints/security-auth-magic-link/CHANGELOG.md +15 -4
- package/blueprints/security-auth-magic-link/README.md +2 -2
- package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +1 -1
- package/blueprints/security-auth-magic-link/blueprint.json +3 -2
- package/blueprints/security-auth-magic-link/contributions/probes/probe-utils.mjs +174 -0
- package/blueprints/security-auth-magic-link/contributions/probes/real-account-magic-link-send.mjs +139 -0
- package/blueprints/security-auth-magic-link/contributions/probes/run-real-account-magic-link-send.mjs +4 -0
- package/blueprints/security-auth-magic-link/contributions/probes/run-token-entropy-shape.mjs +4 -0
- package/blueprints/security-auth-magic-link/contributions/probes/run-token-issue-verify.mjs +4 -0
- package/blueprints/security-auth-magic-link/contributions/probes/token-entropy-shape.mjs +60 -0
- package/blueprints/security-auth-magic-link/contributions/probes/token-issue-verify.mjs +90 -0
- package/blueprints/security-auth-magic-link/docs/topics.md +1 -1
- package/blueprints/security-auth-oauth2/CHANGELOG.md +16 -5
- package/blueprints/security-auth-oauth2/README.md +2 -2
- package/blueprints/security-auth-oauth2/blueprint.json +3 -2
- package/blueprints/security-auth-oauth2/contributions/probes/authorisation-code-flow-shape.mjs +259 -0
- package/blueprints/security-auth-oauth2/contributions/probes/pkce-challenge-shape.mjs +58 -0
- package/blueprints/security-auth-oauth2/contributions/probes/probe-utils.mjs +190 -0
- package/blueprints/security-auth-oauth2/contributions/probes/provider-adapter-shape.mjs +64 -0
- package/blueprints/security-auth-oauth2/contributions/probes/real-account-authorisation-code-flow.mjs +93 -0
- package/blueprints/security-auth-oauth2/contributions/probes/run-authorisation-code-flow-shape.mjs +4 -0
- package/blueprints/security-auth-oauth2/contributions/probes/run-pkce-challenge-shape.mjs +4 -0
- package/blueprints/security-auth-oauth2/contributions/probes/run-provider-adapter-shape.mjs +4 -0
- package/blueprints/security-auth-oauth2/contributions/probes/run-real-account-authorisation-code-flow.mjs +4 -0
- package/blueprints/security-auth-oauth2/contributions/probes/run-session-bridge-shape.mjs +4 -0
- package/blueprints/security-auth-oauth2/contributions/probes/session-bridge-shape.mjs +78 -0
- package/blueprints/security-auth-oauth2/docs/topics.md +1 -2
- package/blueprints/security-secrets-management/CHANGELOG.md +15 -4
- package/blueprints/security-secrets-management/README.md +2 -2
- package/blueprints/security-secrets-management/blueprint.json +3 -2
- package/blueprints/security-secrets-management/contributions/probes/add-recipient-rotation.mjs +107 -0
- package/blueprints/security-secrets-management/contributions/probes/encrypt-decrypt-round-trip.mjs +122 -0
- package/blueprints/security-secrets-management/contributions/probes/key-rotation.mjs +93 -0
- package/blueprints/security-secrets-management/contributions/probes/mismatched-key-refusal.mjs +74 -0
- package/blueprints/security-secrets-management/contributions/probes/probe-utils.mjs +214 -0
- package/blueprints/security-secrets-management/contributions/probes/run-add-recipient-rotation.mjs +4 -0
- package/blueprints/security-secrets-management/contributions/probes/run-encrypt-decrypt-round-trip.mjs +4 -0
- package/blueprints/security-secrets-management/contributions/probes/run-key-rotation.mjs +4 -0
- package/blueprints/security-secrets-management/contributions/probes/run-mismatched-key-refusal.mjs +4 -0
- package/blueprints/security-secrets-management/docs/topics.md +2 -3
- package/fixtures/canary-manifest.json +9 -9
- package/guidance/harness-template.md +25 -0
- package/guidance/managed/agent-instructions-block.hash +1 -1
- package/guidance/managed/agent-instructions-block.md +25 -0
- package/package.json +2 -2
- package/rcf/adrs/adr-4101-feedback-store-gitignored.json +20 -0
- package/rcf/adrs/adr-4102-fingerprint-and-labels.json +25 -0
- package/rcf/adrs/adr-4103-redaction-rule-based.json +20 -0
- package/rcf/adrs/adr-4104-destination-on-library.json +25 -0
- package/rcf/adrs/adr-4105-gh-ambient-auth.json +20 -0
- package/rcf/adrs/adr-4106-bundled-entries-terminal.json +20 -0
- package/rcf/adrs/adr-4107-stop-is-ask-event.json +30 -0
- package/rcf/adrs/adr-4108-hooks-in-committed-config.json +25 -0
- package/rcf/adrs/adr-4109-referee-validate-adr-crosslinks.json +25 -0
- package/rcf/adrs/adr-4110-referee-coverage-strict-by-default.json +25 -0
- package/rcf/adrs/adr-4111-referee-finalise-refusals.json +20 -0
- package/rcf/adrs/adr-4112-referee-finalise-verified-invariant.json +30 -0
- package/rcf/code-nodes/cn-600.json +46 -0
- package/rcf/code-nodes/cn-601.json +18 -0
- package/rcf/code-nodes/cn-602.json +16 -0
- package/rcf/code-nodes/cn-603.json +12 -0
- package/rcf/code-nodes/cn-604.json +14 -0
- package/rcf/code-nodes/cn-605.json +18 -0
- package/rcf/code-nodes/cn-606.json +12 -0
- package/rcf/code-nodes/cn-607.json +12 -0
- package/rcf/code-nodes/cn-608.json +14 -0
- package/rcf/code-nodes/cn-609.json +17 -0
- package/rcf/code-nodes/cn-620.json +18 -0
- package/rcf/code-nodes/cn-621.json +14 -0
- package/rcf/code-nodes/cn-622.json +15 -0
- package/rcf/code-nodes/cn-623.json +16 -0
- package/rcf/code-nodes/cn-624.json +14 -0
- package/rcf/code-nodes/cn-625.json +15 -0
- package/rcf/code-nodes/cn-626.json +13 -0
- package/rcf/code-nodes/cn-627.json +13 -0
- package/rcf/code-nodes/cn-628.json +14 -0
- package/rcf/code-nodes/cn-629.json +12 -0
- package/rcf/code-nodes/cn-630.json +12 -0
- package/rcf/code-nodes/cn-631.json +13 -0
- package/rcf/code-nodes/cn-632.json +13 -0
- package/rcf/fbs/fbs-180.json +45 -0
- package/rcf/fbs/fbs-181.json +46 -0
- package/rcf/fbs/fbs-182.json +43 -0
- package/rcf/fbs/fbs-183.json +50 -0
- package/rcf/fbs/fbs-184.json +49 -0
- package/rcf/fbs/fbs-185.json +34 -0
- package/rcf/fbs/fbs-186.json +16 -0
- package/rcf/fbs/fbs-187.json +17 -0
- package/rcf/fbs/fbs-188.json +17 -0
- package/rcf/fbs/fbs-189.json +17 -0
- package/rcf/requirements/req-155.json +13 -0
- package/rcf/requirements/req-156.json +13 -0
- package/rcf/requirements/req-157.json +13 -0
- package/rcf/requirements/req-158.json +13 -0
- package/rcf/requirements/req-159.json +13 -0
- package/rcf/requirements/req-160.json +13 -0
- package/rcf/requirements/req-161.json +13 -0
- package/rcf/requirements/req-162.json +13 -0
- package/rcf/requirements/req-163.json +13 -0
- package/rcf/requirements/req-164.json +13 -0
- package/rcf/requirements/req-165.json +13 -0
- package/rcf/tacs/tac-4101-feedback-cli.json +77 -0
- package/rcf/tacs/tac-4102-feedback-store.json +50 -0
- package/rcf/tacs/tac-4103-feedback-redact.json +40 -0
- package/rcf/tacs/tac-4104-feedback-fingerprint.json +33 -0
- package/rcf/tacs/tac-4105-feedback-render.json +45 -0
- package/rcf/tacs/tac-4106-feedback-destination.json +40 -0
- package/rcf/tacs/tac-4107-feedback-gh.json +43 -0
- package/rcf/tacs/tac-4108-feedback-hook.json +46 -0
- package/rcf/tacs/tac-4109-referee-validate-adr-crosslinks.json +20 -0
- package/rcf/tacs/tac-4110-referee-coverage-mode-selector.json +21 -0
- package/rcf/tacs/tac-4111-referee-finalise-per-ac-refusals.json +21 -0
- package/rcf/tacs/tac-4112-referee-finalise-verified-invariant.json +22 -0
- package/rcf/test-suites/ts-140.json +9 -9
- package/rcf/test-suites/ts-150.json +9 -9
- package/rcf/test-suites/ts-185.json +54 -0
- package/rcf/test-suites/ts-186.json +58 -0
- package/rcf/test-suites/ts-187.json +44 -0
- package/rcf/test-suites/ts-188.json +174 -0
- package/rcf/test-suites/ts-189.json +60 -0
- package/rcf/test-suites/ts-190.json +30 -0
- package/rcf/test-suites/ts-191.json +51 -0
- package/rcf/test-suites/ts-192.json +37 -0
- package/rcf/test-suites/ts-193.json +60 -0
- package/rcf/test-suites/ts-194.json +67 -0
- package/rcf/test-suites/ts-195.json +52 -0
- package/rcf/test-suites/ts-196.json +58 -0
- package/rcf/test-suites/ts-197.json +66 -0
- package/rcf/test-suites/ts-198.json +87 -0
- package/rcf/test-suites/ts-199.json +51 -0
- package/rcf/test-suites/ts-200.json +30 -0
- package/rcf/test-suites/ts-201.json +38 -0
- package/rcf/test-suites/ts-202.json +38 -0
- package/rcf/test-suites/ts-203.json +38 -0
- package/rcf/user-stories/us-15501.json +60 -0
- package/rcf/user-stories/us-15502.json +33 -0
- package/rcf/user-stories/us-15503.json +33 -0
- package/rcf/user-stories/us-15601.json +60 -0
- package/rcf/user-stories/us-15701.json +42 -0
- package/rcf/user-stories/us-15801.json +51 -0
- package/rcf/user-stories/us-15802.json +33 -0
- package/rcf/user-stories/us-15901.json +33 -0
- package/rcf/user-stories/us-15902.json +51 -0
- package/rcf/user-stories/us-16001.json +51 -0
- package/rcf/user-stories/us-16101.json +42 -0
- package/rcf/user-stories/us-16102.json +33 -0
- package/rcf/user-stories/us-16103.json +42 -0
- package/rcf/user-stories/us-16104.json +42 -0
- package/rcf/user-stories/us-16201.json +33 -0
- package/rcf/user-stories/us-16301.json +36 -0
- package/rcf/user-stories/us-16401.json +45 -0
- package/rcf/user-stories/us-16501.json +45 -0
- package/rcf/user-stories/us-16502.json +45 -0
- package/releases/releases.yaml +21 -1
- package/src/blueprint/library-loader.js +48 -0
- package/src/blueprint/library-registry.js +13 -0
- package/src/browser-verify/pack-runner.js +7 -12
- package/src/build/mark.js +1 -1
- package/src/cli/blueprint-library.js +149 -0
- package/src/cli/coverage.js +49 -24
- package/src/cli/doctor.js +195 -7
- package/src/cli/feedback.js +2213 -0
- package/src/cli/finalise.js +158 -1
- package/src/cli/help.js +6 -0
- package/src/cli/init.js +63 -0
- package/src/cli/update.js +21 -1
- package/src/core/store/walker.js +33 -0
- package/src/core/store/writer.js +23 -0
- package/src/feedback/destination.js +455 -0
- package/src/feedback/fingerprint.js +132 -0
- package/src/feedback/gh.js +376 -0
- package/src/feedback/hook.js +183 -0
- package/src/feedback/labels.js +87 -0
- package/src/feedback/redact-allowlist.json +14 -0
- package/src/feedback/redact.js +1148 -0
- package/src/feedback/render.js +267 -0
- package/src/feedback/store.js +604 -0
- package/src/finalise/index.js +4 -0
- package/src/finalise/ingest.js +61 -0
- package/src/finalise/ship-without-eval.js +19 -7
- package/src/mcp/tools.js +8 -2
- package/src/setup/feedback-hooks.js +397 -0
- package/src/setup/managed-gitignore.js +3 -0
- package/src/view/html-page.js +5 -5
- package/src/view/style.css +2 -2
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
// Feedback destination resolver (TAC-4106-feedback-destination,
|
|
2
|
+
// ADR-4104-destination-on-library). Slice 3 (FBS-182): given a pending
|
|
3
|
+
// entry plus the project's manifest and library registry, work out
|
|
4
|
+
// which GitHub repo the finding should be filed against and whether it
|
|
5
|
+
// is public or private. The resolver is pure: no i/o, no network,
|
|
6
|
+
// nothing that would slow preview or submit down to disk speed.
|
|
7
|
+
//
|
|
8
|
+
// Resolution order (design section 3.3):
|
|
9
|
+
// 1. --kind core -> CORE_REPO (public)
|
|
10
|
+
// 2. --kind blueprint, no libraryPrefix -> library-slug inference
|
|
11
|
+
// (AC-15801-4 / design amendment R5a): if the applied slug is
|
|
12
|
+
// owned by exactly one registered library that resolves to a
|
|
13
|
+
// destination (issuesRepo or derivable sourceRef), route there
|
|
14
|
+
// with source: 'library-slug-inference'; if two or more libraries
|
|
15
|
+
// own the slug and resolve, return unresolved with reason
|
|
16
|
+
// 'ambiguous-library-slug' and a candidates[] array of prefixes;
|
|
17
|
+
// otherwise fall through to CORE_REPO (shelf; public).
|
|
18
|
+
// 3. --kind blueprint, libraryPrefix -> registry entry issuesRepo
|
|
19
|
+
// (declared destination wins;
|
|
20
|
+
// visibility from the entry)
|
|
21
|
+
// 4. registry entry with no issuesRepo -> derive from sourceRef when
|
|
22
|
+
// it parses as
|
|
23
|
+
// git+https://github.com/OWNER/REPO(.git)#ref
|
|
24
|
+
// (marked derived: true;
|
|
25
|
+
// visibility defaults to
|
|
26
|
+
// public unless the entry
|
|
27
|
+
// already asserted private)
|
|
28
|
+
// 5. anything else -> unresolved (reason names
|
|
29
|
+
// the why, publisherContact
|
|
30
|
+
// carries the registry
|
|
31
|
+
// contact when known)
|
|
32
|
+
//
|
|
33
|
+
// The CORE_REPO constant is derived from packages/rcf-lite/package.json
|
|
34
|
+
// bugs.url. Because a resolver call is on the hot path of preview and
|
|
35
|
+
// submit, and because reading package.json every call is wasteful and
|
|
36
|
+
// hard to test in isolation, the value is cached at module load time.
|
|
37
|
+
// A dedicated `resolveCoreRepo()` helper (also exported) does the
|
|
38
|
+
// parse; consumers with their own package.json can call it directly
|
|
39
|
+
// and the resolver's CORE_REPO getter reads through it.
|
|
40
|
+
|
|
41
|
+
import { readFile } from 'node:fs/promises';
|
|
42
|
+
import { dirname, resolve as resolvePath } from 'node:path';
|
|
43
|
+
import { fileURLToPath } from 'node:url';
|
|
44
|
+
|
|
45
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
46
|
+
// packages/rcf-lite/src/feedback -> packages/rcf-lite/package.json.
|
|
47
|
+
const PACKAGE_JSON_PATH = resolvePath(here, '..', '..', 'package.json');
|
|
48
|
+
const CORE_REPO_FALLBACK = 'Stravica/rcf-lite';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The Stravica/rcf-lite constant that every core-kind entry and every
|
|
52
|
+
* shelf-blueprint entry routes to. Sourced from
|
|
53
|
+
* `packages/rcf-lite/package.json:bugs.url` at module load so a rename
|
|
54
|
+
* only ripples through one file; a matching unit test pins the constant
|
|
55
|
+
* to the package.json value at test time so a drift is caught in CI.
|
|
56
|
+
*
|
|
57
|
+
* @type {string}
|
|
58
|
+
*/
|
|
59
|
+
export let CORE_REPO = CORE_REPO_FALLBACK;
|
|
60
|
+
|
|
61
|
+
/** Guard against double-init during test loops. */
|
|
62
|
+
let coreRepoInitialised = false;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse `bugs.url` from a package.json object and return `OWNER/REPO`.
|
|
66
|
+
* Accepts the trailing `/issues`, an `.git` suffix and either the
|
|
67
|
+
* string or the object shape npm allows on `bugs`.
|
|
68
|
+
*
|
|
69
|
+
* @param {object | undefined | null} pkg
|
|
70
|
+
* @returns {string | null}
|
|
71
|
+
*/
|
|
72
|
+
export function parseBugsRepo(pkg) {
|
|
73
|
+
if (pkg == null) return null;
|
|
74
|
+
const bugs = typeof pkg.bugs === 'string' ? pkg.bugs : pkg?.bugs?.url;
|
|
75
|
+
if (typeof bugs !== 'string' || bugs.length === 0) return null;
|
|
76
|
+
const withIssues = bugs.match(/github\.com\/([^/]+)\/([^/#?]+?)(?:\.git)?\/issues\/?(?:[/?#].*)?$/i);
|
|
77
|
+
if (withIssues) return `${withIssues[1]}/${withIssues[2]}`;
|
|
78
|
+
const bare = bugs.match(/github\.com\/([^/]+)\/([^/#?]+?)(?:\.git)?\/?$/i);
|
|
79
|
+
if (bare) return `${bare[1]}/${bare[2]}`;
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Read `packages/rcf-lite/package.json` and populate `CORE_REPO`. Safe
|
|
85
|
+
* to call more than once; a failed read leaves the fallback in place.
|
|
86
|
+
* The resolver auto-inits on first `resolve()` call, so most callers
|
|
87
|
+
* never touch this directly; tests call it to force a fresh read.
|
|
88
|
+
*
|
|
89
|
+
* @returns {Promise<string>}
|
|
90
|
+
*/
|
|
91
|
+
export async function initCoreRepo() {
|
|
92
|
+
try {
|
|
93
|
+
const text = await readFile(PACKAGE_JSON_PATH, 'utf8');
|
|
94
|
+
const pkg = JSON.parse(text);
|
|
95
|
+
const parsed = parseBugsRepo(pkg);
|
|
96
|
+
if (parsed) CORE_REPO = parsed;
|
|
97
|
+
} catch {
|
|
98
|
+
// Missing or unreadable package.json leaves the fallback active.
|
|
99
|
+
// A dedicated test pins the value in CI so this branch never ships.
|
|
100
|
+
}
|
|
101
|
+
coreRepoInitialised = true;
|
|
102
|
+
return CORE_REPO;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parse a git sourceRef of the shape `git+https://github.com/OWNER/REPO(.git)#ref`
|
|
107
|
+
* (or `git+ssh://git@github.com:OWNER/REPO.git#ref`, the two shapes
|
|
108
|
+
* `library add` accepts) into `OWNER/REPO`. Anything else returns null;
|
|
109
|
+
* the resolver treats that as "cannot derive", not as an error.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} sourceRef
|
|
112
|
+
* @returns {string | null}
|
|
113
|
+
*/
|
|
114
|
+
export function parseGithubSource(sourceRef) {
|
|
115
|
+
if (typeof sourceRef !== 'string' || sourceRef.length === 0) return null;
|
|
116
|
+
// git+https://github.com/OWNER/REPO(.git)(#ref)
|
|
117
|
+
const https = sourceRef.match(/^git\+https?:\/\/github\.com\/([^/]+)\/([^/#?]+?)(?:\.git)?(?:#.*)?$/i);
|
|
118
|
+
if (https) return `${https[1]}/${https[2]}`;
|
|
119
|
+
// git+ssh://git@github.com:OWNER/REPO.git(#ref) or git+ssh://git@github.com/OWNER/REPO.git(#ref)
|
|
120
|
+
const ssh = sourceRef.match(/^git\+ssh:\/\/git@github\.com[:\/]([^/]+)\/([^/#?]+?)(?:\.git)?(?:#.*)?$/i);
|
|
121
|
+
if (ssh) return `${ssh[1]}/${ssh[2]}`;
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Look up a blueprint record on `manifest.blueprints[]` by ref. Accepts
|
|
127
|
+
* the shelf slug (`security-auth-magic-link`), the prefix:slug form
|
|
128
|
+
* (`wsd:std-error-envelope`) and the effective slug already stamped
|
|
129
|
+
* onto the record (`wsd-std-error-envelope`).
|
|
130
|
+
*
|
|
131
|
+
* F-slice-3-01: a QUALIFIED ref (`prefix:slug`) must resolve to a
|
|
132
|
+
* record whose libraryPrefix matches the qualifier. Falling back to
|
|
133
|
+
* an unqualified shelf record on slug collision would route a
|
|
134
|
+
* private WSD finding to the public Stravica/rcf-lite repo. The
|
|
135
|
+
* matcher therefore has two passes: first, any record whose stamped
|
|
136
|
+
* effectiveSlug OR (slug + libraryPrefix) matches the qualifier
|
|
137
|
+
* wins; only when the ref is unqualified do bare-slug matches apply.
|
|
138
|
+
*
|
|
139
|
+
* @param {object | null | undefined} manifest
|
|
140
|
+
* @param {string} ref
|
|
141
|
+
* @returns {object | null}
|
|
142
|
+
*/
|
|
143
|
+
export function findBlueprintRecord(manifest, ref) {
|
|
144
|
+
const list = Array.isArray(manifest?.blueprints) ? manifest.blueprints : [];
|
|
145
|
+
if (typeof ref !== 'string' || ref.length === 0) return null;
|
|
146
|
+
|
|
147
|
+
// Qualified `prefix:slug` (and the equivalent `prefix-slug`
|
|
148
|
+
// effective-slug shape) must NEVER match a shelf record whose
|
|
149
|
+
// libraryPrefix does not equal the qualifier. F-slice-3-01: a
|
|
150
|
+
// qualified WSD ref must not fall back to a public shelf record
|
|
151
|
+
// on slug collision.
|
|
152
|
+
if (ref.includes(':')) {
|
|
153
|
+
const [pre, slug] = ref.split(':');
|
|
154
|
+
if (pre && slug) {
|
|
155
|
+
const effective = `${pre}-${slug}`;
|
|
156
|
+
for (const r of list) {
|
|
157
|
+
if (!r || typeof r !== 'object') continue;
|
|
158
|
+
if (r.libraryPrefix !== pre) continue;
|
|
159
|
+
const candidates = recordCandidates(r);
|
|
160
|
+
if (candidates.includes(ref) || candidates.includes(effective) || candidates.includes(slug)) return r;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Unqualified ref: match by any candidate. A record with a
|
|
167
|
+
// libraryPrefix still matches, but only through its stamped
|
|
168
|
+
// canonical effective slug (`libraryPrefix-slug`) - never through
|
|
169
|
+
// a bare, unqualified slug that could collide with a shelf record.
|
|
170
|
+
for (const r of list) {
|
|
171
|
+
if (!r || typeof r !== 'object') continue;
|
|
172
|
+
const isQualifiedRecord = typeof r.libraryPrefix === 'string' && r.libraryPrefix.length > 0;
|
|
173
|
+
if (isQualifiedRecord) {
|
|
174
|
+
const canonical = recordEffectiveSlug(r);
|
|
175
|
+
if (canonical && ref === canonical) return r;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const candidates = recordCandidates(r);
|
|
179
|
+
if (candidates.includes(ref)) return r;
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The candidate name set stamped on a manifest record: any of
|
|
186
|
+
* effectiveSlug, slug, name that are non-empty strings.
|
|
187
|
+
*
|
|
188
|
+
* @param {object} record
|
|
189
|
+
* @returns {string[]}
|
|
190
|
+
*/
|
|
191
|
+
function recordCandidates(record) {
|
|
192
|
+
return [record.effectiveSlug, record.slug, record.name].filter(
|
|
193
|
+
(s) => typeof s === 'string' && s.length > 0,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The canonical effective slug for a qualified manifest record. If
|
|
199
|
+
* the record already carries `effectiveSlug`, that wins; otherwise
|
|
200
|
+
* synthesise it from `libraryPrefix` + `slug` (either the slug is
|
|
201
|
+
* already prefixed, or we prepend the prefix).
|
|
202
|
+
*
|
|
203
|
+
* @param {object} record
|
|
204
|
+
* @returns {string | null}
|
|
205
|
+
*/
|
|
206
|
+
function recordEffectiveSlug(record) {
|
|
207
|
+
if (typeof record.effectiveSlug === 'string' && record.effectiveSlug.length > 0) return record.effectiveSlug;
|
|
208
|
+
const pre = typeof record.libraryPrefix === 'string' ? record.libraryPrefix : '';
|
|
209
|
+
const slug = typeof record.slug === 'string' ? record.slug : '';
|
|
210
|
+
if (!pre || !slug) return null;
|
|
211
|
+
return slug.startsWith(`${pre}-`) ? slug : `${pre}-${slug}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @typedef {object} Destination
|
|
216
|
+
* @property {string | null} repo OWNER/REPO or null when unresolved
|
|
217
|
+
* @property {'public' | 'private' | 'unresolved'} visibility
|
|
218
|
+
* @property {'core' | 'shelf' | 'library'} kind
|
|
219
|
+
* @property {boolean} derived true when repo came from sourceRef derivation
|
|
220
|
+
* @property {string} [reason] filled on unresolved: 'no-issues-field' | 'no-github-source' | 'no-libraryprefix-record' | 'unknown-target' | 'ambiguous-library-slug'
|
|
221
|
+
* @property {string[]} [candidates] filled on unresolved with reason 'ambiguous-library-slug': sorted library prefixes owning the slug
|
|
222
|
+
* @property {string} [publisherContact] registry entry's publisher.contact (bundle uses it)
|
|
223
|
+
* @property {string} [source] 'library-manifest' | 'sourceRef-derivation' | 'package-bugs-url' | 'shelf-constant' | 'library-slug-inference'
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Resolve one entry to its destination shape. Pure over the inputs.
|
|
228
|
+
*
|
|
229
|
+
* @param {object} entry a feedback entry (design §4.1)
|
|
230
|
+
* @param {object} [context]
|
|
231
|
+
* @param {object} [context.manifest] parsed rcf/manifest.json
|
|
232
|
+
* @param {object} [context.registry] parsed rcf/blueprint-libraries.json
|
|
233
|
+
* @returns {Promise<Destination>}
|
|
234
|
+
*/
|
|
235
|
+
export async function resolve(entry, context = {}) {
|
|
236
|
+
if (!coreRepoInitialised) await initCoreRepo();
|
|
237
|
+
const manifest = context.manifest ?? null;
|
|
238
|
+
const registry = context.registry ?? { libraries: [] };
|
|
239
|
+
const kind = entry?.kind;
|
|
240
|
+
|
|
241
|
+
if (kind === 'core') {
|
|
242
|
+
return {
|
|
243
|
+
repo: CORE_REPO,
|
|
244
|
+
visibility: 'public',
|
|
245
|
+
kind: 'core',
|
|
246
|
+
derived: false,
|
|
247
|
+
source: 'package-bugs-url',
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (kind !== 'blueprint') {
|
|
251
|
+
return {
|
|
252
|
+
repo: null,
|
|
253
|
+
visibility: 'unresolved',
|
|
254
|
+
kind: 'library',
|
|
255
|
+
derived: false,
|
|
256
|
+
reason: 'unknown-target',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const ref = entry?.target?.ref;
|
|
261
|
+
const record = findBlueprintRecord(manifest, ref);
|
|
262
|
+
if (!record) {
|
|
263
|
+
return {
|
|
264
|
+
repo: null,
|
|
265
|
+
visibility: 'unresolved',
|
|
266
|
+
kind: 'library',
|
|
267
|
+
derived: false,
|
|
268
|
+
reason: 'unknown-target',
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const libraryPrefix = record.libraryPrefix ?? entry?.target?.libraryPrefix ?? null;
|
|
273
|
+
|
|
274
|
+
// Shelf blueprint (no libraryPrefix on the manifest record). Before
|
|
275
|
+
// falling through to the shelf constant, cross-check the registry:
|
|
276
|
+
// if exactly one registered library owns a blueprint with the applied
|
|
277
|
+
// slug AND that library resolves to a destination, route to that
|
|
278
|
+
// library so a bare-slug apply of a library-shared name still lands
|
|
279
|
+
// on the library owner's repo (design amendment R5, AC-15801-4).
|
|
280
|
+
if (!libraryPrefix) {
|
|
281
|
+
const inferred = inferLibraryFromSlug(record, registry);
|
|
282
|
+
if (inferred.kind === 'single') {
|
|
283
|
+
return inferred.destination;
|
|
284
|
+
}
|
|
285
|
+
if (inferred.kind === 'ambiguous') {
|
|
286
|
+
return {
|
|
287
|
+
repo: null,
|
|
288
|
+
visibility: 'unresolved',
|
|
289
|
+
kind: 'library',
|
|
290
|
+
derived: false,
|
|
291
|
+
reason: 'ambiguous-library-slug',
|
|
292
|
+
candidates: inferred.candidates,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
repo: CORE_REPO,
|
|
297
|
+
visibility: 'public',
|
|
298
|
+
kind: 'shelf',
|
|
299
|
+
derived: false,
|
|
300
|
+
source: 'package-bugs-url',
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const libEntry = findLibraryEntry(registry, libraryPrefix);
|
|
305
|
+
if (!libEntry) {
|
|
306
|
+
return {
|
|
307
|
+
repo: null,
|
|
308
|
+
visibility: 'unresolved',
|
|
309
|
+
kind: 'library',
|
|
310
|
+
derived: false,
|
|
311
|
+
reason: 'no-libraryprefix-record',
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const contact = typeof libEntry?.publisher?.contact === 'string'
|
|
316
|
+
? libEntry.publisher.contact
|
|
317
|
+
: undefined;
|
|
318
|
+
|
|
319
|
+
// Declared destination wins.
|
|
320
|
+
if (typeof libEntry.issuesRepo === 'string' && libEntry.issuesRepo.length > 0) {
|
|
321
|
+
const declaredVisibility = libEntry.issuesVisibility === 'private' ? 'private'
|
|
322
|
+
: libEntry.issuesVisibility === 'public' ? 'public'
|
|
323
|
+
: 'public';
|
|
324
|
+
return {
|
|
325
|
+
repo: libEntry.issuesRepo,
|
|
326
|
+
visibility: declaredVisibility,
|
|
327
|
+
kind: 'library',
|
|
328
|
+
derived: false,
|
|
329
|
+
source: 'library-manifest',
|
|
330
|
+
...(contact ? { publisherContact: contact } : {}),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Fallback: derive from sourceRef when it parses as a github URL.
|
|
335
|
+
const derived = parseGithubSource(libEntry.sourceRef ?? '');
|
|
336
|
+
if (derived) {
|
|
337
|
+
return {
|
|
338
|
+
repo: derived,
|
|
339
|
+
visibility: 'public',
|
|
340
|
+
kind: 'library',
|
|
341
|
+
derived: true,
|
|
342
|
+
source: 'sourceRef-derivation',
|
|
343
|
+
...(contact ? { publisherContact: contact } : {}),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Neither declared nor derivable: unresolved.
|
|
348
|
+
return {
|
|
349
|
+
repo: null,
|
|
350
|
+
visibility: 'unresolved',
|
|
351
|
+
kind: 'library',
|
|
352
|
+
derived: false,
|
|
353
|
+
reason: libEntry.sourceRef ? 'no-github-source' : 'no-issues-field',
|
|
354
|
+
...(contact ? { publisherContact: contact } : {}),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Enumerate every registered library and flag the ones the resolver
|
|
360
|
+
* cannot produce a destination for (no issues field and no derivable
|
|
361
|
+
* github source). Doctor's `feedback-destinations` check consumes this;
|
|
362
|
+
* the shape is `{ libraryPrefix, reason, publisherContact? }`.
|
|
363
|
+
*
|
|
364
|
+
* @param {object} registry
|
|
365
|
+
* @returns {Array<{ libraryPrefix: string, reason: 'no-issues-field' | 'no-github-source', publisherContact?: string }>}
|
|
366
|
+
*/
|
|
367
|
+
export function listUnresolvedLibraries(registry) {
|
|
368
|
+
const out = [];
|
|
369
|
+
const libs = Array.isArray(registry?.libraries) ? registry.libraries : [];
|
|
370
|
+
for (const lib of libs) {
|
|
371
|
+
if (typeof lib?.libraryPrefix !== 'string') continue;
|
|
372
|
+
if (typeof lib.issuesRepo === 'string' && lib.issuesRepo.length > 0) continue;
|
|
373
|
+
const derived = parseGithubSource(lib.sourceRef ?? '');
|
|
374
|
+
if (derived) continue;
|
|
375
|
+
const contact = typeof lib?.publisher?.contact === 'string' ? lib.publisher.contact : undefined;
|
|
376
|
+
out.push({
|
|
377
|
+
libraryPrefix: lib.libraryPrefix,
|
|
378
|
+
reason: lib.sourceRef ? 'no-github-source' : 'no-issues-field',
|
|
379
|
+
...(contact ? { publisherContact: contact } : {}),
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
return out;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function findLibraryEntry(registry, libraryPrefix) {
|
|
386
|
+
const libs = Array.isArray(registry?.libraries) ? registry.libraries : [];
|
|
387
|
+
return libs.find((l) => l?.libraryPrefix === libraryPrefix) ?? null;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* AC-15801-4 / design amendment R5a: given a manifest record with no
|
|
392
|
+
* libraryPrefix, cross-check the registry to see whether the applied
|
|
393
|
+
* slug is owned by exactly one registered library that resolves to a
|
|
394
|
+
* destination. Returns:
|
|
395
|
+
* { kind: 'none' } no library owns the slug (or none resolve)
|
|
396
|
+
* { kind: 'single', destination } exactly one library owns the slug and resolves
|
|
397
|
+
* { kind: 'ambiguous', candidates: string[] } two or more libraries own the slug and resolve
|
|
398
|
+
*
|
|
399
|
+
* The resolver only calls this on the shelf-constant fall-through
|
|
400
|
+
* branch, so it never overrides an existing libraryPrefix resolution.
|
|
401
|
+
*
|
|
402
|
+
* @param {object} record manifest.blueprints[] record
|
|
403
|
+
* @param {object | null | undefined} registry parsed rcf/blueprint-libraries.json
|
|
404
|
+
*/
|
|
405
|
+
function inferLibraryFromSlug(record, registry) {
|
|
406
|
+
const slug = typeof record?.slug === 'string' ? record.slug : null;
|
|
407
|
+
if (!slug) return { kind: 'none' };
|
|
408
|
+
const libs = Array.isArray(registry?.libraries) ? registry.libraries : [];
|
|
409
|
+
const owners = [];
|
|
410
|
+
for (const lib of libs) {
|
|
411
|
+
if (!lib || typeof lib !== 'object') continue;
|
|
412
|
+
if (typeof lib.libraryPrefix !== 'string' || lib.libraryPrefix.length === 0) continue;
|
|
413
|
+
const bps = Array.isArray(lib.blueprints) ? lib.blueprints : [];
|
|
414
|
+
const owns = bps.some((b) => b && typeof b.slug === 'string' && b.slug === slug);
|
|
415
|
+
if (!owns) continue;
|
|
416
|
+
const declared = typeof lib.issuesRepo === 'string' && lib.issuesRepo.length > 0 ? lib.issuesRepo : null;
|
|
417
|
+
const derivedRepo = declared ? null : parseGithubSource(lib.sourceRef ?? '');
|
|
418
|
+
if (!declared && !derivedRepo) continue;
|
|
419
|
+
const contact = typeof lib?.publisher?.contact === 'string' ? lib.publisher.contact : undefined;
|
|
420
|
+
owners.push({ lib, declared, derivedRepo, contact });
|
|
421
|
+
}
|
|
422
|
+
if (owners.length === 0) return { kind: 'none' };
|
|
423
|
+
if (owners.length === 1) {
|
|
424
|
+
const [o] = owners;
|
|
425
|
+
if (o.declared) {
|
|
426
|
+
const declaredVisibility = o.lib.issuesVisibility === 'private' ? 'private'
|
|
427
|
+
: o.lib.issuesVisibility === 'public' ? 'public'
|
|
428
|
+
: 'public';
|
|
429
|
+
return {
|
|
430
|
+
kind: 'single',
|
|
431
|
+
destination: {
|
|
432
|
+
repo: o.declared,
|
|
433
|
+
visibility: declaredVisibility,
|
|
434
|
+
kind: 'library',
|
|
435
|
+
derived: false,
|
|
436
|
+
source: 'library-slug-inference',
|
|
437
|
+
...(o.contact ? { publisherContact: o.contact } : {}),
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
kind: 'single',
|
|
443
|
+
destination: {
|
|
444
|
+
repo: o.derivedRepo,
|
|
445
|
+
visibility: 'public',
|
|
446
|
+
kind: 'library',
|
|
447
|
+
derived: true,
|
|
448
|
+
source: 'library-slug-inference',
|
|
449
|
+
...(o.contact ? { publisherContact: o.contact } : {}),
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
const candidates = owners.map((o) => o.lib.libraryPrefix).sort();
|
|
454
|
+
return { kind: 'ambiguous', candidates };
|
|
455
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Feedback fingerprint (TAC-4104-feedback-fingerprint, ADR-4102).
|
|
2
|
+
// Deterministic 12-hex fingerprint per entry that keys the same-defect
|
|
3
|
+
// fold when the submit path (slice 4) files issues.
|
|
4
|
+
//
|
|
5
|
+
// Canonical input (design section 6):
|
|
6
|
+
// sha-256("<kind>|<targetKey>|<anchor>|<symptomClass>") -> first 12 hex
|
|
7
|
+
// where
|
|
8
|
+
// - targetKey is the effective slug for blueprints (no version) or
|
|
9
|
+
// the verb path for core; a target that came in as
|
|
10
|
+
// `prefix:slug` is normalised to `prefix-slug`.
|
|
11
|
+
// - anchor is upper-cased, or `-` when absent.
|
|
12
|
+
// - symptomClass is one of the closed enum.
|
|
13
|
+
//
|
|
14
|
+
// Fallback (when the entry has no anchor): the canonical input becomes
|
|
15
|
+
// sha-256("<kind>|<targetKey>|<symptomClass>|<normalisedTitle>")
|
|
16
|
+
// where normalisedTitle is the first eight tokens of the title
|
|
17
|
+
// lower-cased, punctuation stripped and stop-words removed.
|
|
18
|
+
//
|
|
19
|
+
// Blueprint version is not part of the fingerprint (§6, §9) so a
|
|
20
|
+
// defect that persists across versions folds into one issue with the
|
|
21
|
+
// versions in the comments.
|
|
22
|
+
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
|
|
25
|
+
/** Length of the truncated fingerprint (hex chars). */
|
|
26
|
+
export const FINGERPRINT_HEX_LEN = 12;
|
|
27
|
+
|
|
28
|
+
/** Cheap English stop-word list used by the fallback title tokeniser. */
|
|
29
|
+
const STOP_WORDS = new Set([
|
|
30
|
+
'a', 'an', 'the', 'and', 'or', 'but', 'if', 'of', 'in', 'on', 'at',
|
|
31
|
+
'to', 'for', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
32
|
+
'it', 'this', 'that', 'these', 'those', 'as', 'by', 'with', 'from',
|
|
33
|
+
'into', 'over', 'under', 'up', 'down', 'not', 'no', 'do', 'does',
|
|
34
|
+
'did', 'has', 'have', 'had',
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Compute an entry fingerprint. Accepts the entry shape written by
|
|
39
|
+
* `rcf feedback add` (see src/feedback/store.js FeedbackEntry) and
|
|
40
|
+
* emits a 12-hex string keyed on the fields listed above.
|
|
41
|
+
*
|
|
42
|
+
* @param {object} entry
|
|
43
|
+
* @returns {string} 12 lower-case hex chars
|
|
44
|
+
*/
|
|
45
|
+
export function fingerprint(entry) {
|
|
46
|
+
const input = fingerprintInput(entry);
|
|
47
|
+
return createHash('sha256').update(input, 'utf8').digest('hex').slice(0, FINGERPRINT_HEX_LEN);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Return the exact canonical string that hashes to the fingerprint.
|
|
52
|
+
* Exposed for the disclosure line on `preview` and for the test
|
|
53
|
+
* corpus, so a maintainer can reproduce the value by hand.
|
|
54
|
+
*
|
|
55
|
+
* @param {object} entry
|
|
56
|
+
* @returns {string}
|
|
57
|
+
*/
|
|
58
|
+
export function fingerprintInput(entry) {
|
|
59
|
+
const kind = String(entry?.kind ?? '').toLowerCase();
|
|
60
|
+
const targetKey = deriveTargetKey(entry);
|
|
61
|
+
const anchor = normaliseAnchor(entry?.anchor);
|
|
62
|
+
const symptomClass = String(entry?.symptomClass ?? 'other');
|
|
63
|
+
if (anchor === '-') {
|
|
64
|
+
const normalisedTitle = normaliseTitle(entry?.title ?? '');
|
|
65
|
+
return `${kind}|${targetKey}|${symptomClass}|${normalisedTitle}`;
|
|
66
|
+
}
|
|
67
|
+
return `${kind}|${targetKey}|${anchor}|${symptomClass}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Derive the targetKey portion of the canonical input.
|
|
72
|
+
*
|
|
73
|
+
* blueprint: effectiveSlug from the entry.target if present, else
|
|
74
|
+
* a normalised form of the ref (`wsd:std-error-envelope`
|
|
75
|
+
* becomes `wsd-std-error-envelope`; already-dashed
|
|
76
|
+
* refs pass through unchanged).
|
|
77
|
+
* core: the verb path from entry.target.ref, lower-cased with
|
|
78
|
+
* whitespace collapsed to single spaces.
|
|
79
|
+
*
|
|
80
|
+
* @param {object} entry
|
|
81
|
+
* @returns {string}
|
|
82
|
+
*/
|
|
83
|
+
export function deriveTargetKey(entry) {
|
|
84
|
+
const t = entry?.target ?? {};
|
|
85
|
+
const kind = String(entry?.kind ?? '').toLowerCase();
|
|
86
|
+
if (kind === 'blueprint') {
|
|
87
|
+
if (typeof t.effectiveSlug === 'string' && t.effectiveSlug.length > 0) {
|
|
88
|
+
return t.effectiveSlug;
|
|
89
|
+
}
|
|
90
|
+
const ref = String(t.ref ?? '');
|
|
91
|
+
if (ref.includes(':')) return ref.replace(':', '-');
|
|
92
|
+
return ref;
|
|
93
|
+
}
|
|
94
|
+
const ref = String(t.ref ?? '');
|
|
95
|
+
return ref.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Normalise the anchor: upper-case, trim; return `-` when the value
|
|
100
|
+
* is nullish, empty or whitespace-only.
|
|
101
|
+
*
|
|
102
|
+
* @param {string | null | undefined} anchor
|
|
103
|
+
* @returns {string}
|
|
104
|
+
*/
|
|
105
|
+
export function normaliseAnchor(anchor) {
|
|
106
|
+
if (anchor == null) return '-';
|
|
107
|
+
const trimmed = String(anchor).trim();
|
|
108
|
+
if (trimmed === '') return '-';
|
|
109
|
+
return trimmed.toUpperCase();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Normalise a title for the fallback fingerprint: lower-case, strip
|
|
114
|
+
* punctuation, remove stop-words, keep the first eight remaining
|
|
115
|
+
* tokens joined by single spaces.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} title
|
|
118
|
+
* @returns {string}
|
|
119
|
+
*/
|
|
120
|
+
export function normaliseTitle(title) {
|
|
121
|
+
// F-slice-2-11: normalise every non-ASCII dash variant (em, en,
|
|
122
|
+
// figure, horizontal bar, hyphen, non-breaking hyphen, minus) to
|
|
123
|
+
// an ASCII hyphen first, then strip ALL punctuation including
|
|
124
|
+
// ASCII hyphens. "probe-fails" and its em-dash sibling
|
|
125
|
+
// "probe—fails" then hash the same.
|
|
126
|
+
const dashNormalised = String(title ?? '').replace(/[‐-―−-]/g, ' ');
|
|
127
|
+
const lowered = dashNormalised.toLowerCase();
|
|
128
|
+
const cleaned = lowered.replace(/[^a-z0-9\s]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
129
|
+
if (cleaned === '') return '';
|
|
130
|
+
const tokens = cleaned.split(' ').filter((t) => t.length > 0 && !STOP_WORDS.has(t));
|
|
131
|
+
return tokens.slice(0, 8).join(' ');
|
|
132
|
+
}
|