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,155 @@
|
|
|
1
|
+
// application-empty-error-states probe: permission-denied
|
|
2
|
+
// (AC-22104-1) and the offline buffer lifecycle (AC-22105-1).
|
|
3
|
+
//
|
|
4
|
+
// AC-22105-1 requires observing the buffered-write lifecycle
|
|
5
|
+
// (intercepted-write when the transport is offline, buffered with
|
|
6
|
+
// idempotency-per-token, flushed on reconnect, delivered count
|
|
7
|
+
// visible). The lifecycle is server-observable via the fixture's
|
|
8
|
+
// /probe/offline/state, /probe/offline/buffer and
|
|
9
|
+
// /probe/offline/reconnect endpoints - a probe can flip the state
|
|
10
|
+
// to offline, POST a varied idempotency token, verify the count
|
|
11
|
+
// increased and the token deduplicates a duplicate POST, trigger
|
|
12
|
+
// reconnect, then verify the buffer drained and the delivered
|
|
13
|
+
// count rose. The polite live-region announcement of the flushed
|
|
14
|
+
// count is browser-driven (client script wires the announce) and
|
|
15
|
+
// is not part of what this row observes.
|
|
16
|
+
|
|
17
|
+
import { fixtureFetch, startFixture, excerpt } from './probe-utils.mjs';
|
|
18
|
+
import { randomUUID } from 'node:crypto';
|
|
19
|
+
|
|
20
|
+
export const anchorAcId = 'application-empty-error-states-AC-22104-1';
|
|
21
|
+
export const accountBound = false;
|
|
22
|
+
|
|
23
|
+
export default async function runProbe() {
|
|
24
|
+
const fixture = await startFixture();
|
|
25
|
+
const results = [];
|
|
26
|
+
try {
|
|
27
|
+
const pd = await fixtureFetch(fixture.url, '/probe/permission-denied');
|
|
28
|
+
const region = /data-surface="permission-denied"[^>]*role="region"/.test(pd.body);
|
|
29
|
+
const causeMatch = pd.body.match(/<span data-cause>([^<]+)<\/span>/);
|
|
30
|
+
const causeText = causeMatch ? causeMatch[1] : '';
|
|
31
|
+
// AC-22104-1 requires a class-level cause string with no digits-run
|
|
32
|
+
// of 4 or more and no per-resource identifier shape.
|
|
33
|
+
const causeShape = causeText.length > 0 && !/\d{4,}/.test(causeText);
|
|
34
|
+
const action = /data-action="request-access"/.test(pd.body);
|
|
35
|
+
const causeClass = /data-cause-class="scope-missing"/.test(pd.body);
|
|
36
|
+
const pass = pd.status === 403 && !!pd.requestId && region && causeShape && action && causeClass;
|
|
37
|
+
results.push({
|
|
38
|
+
anchorAcId: null,
|
|
39
|
+
conformanceOnly: true,
|
|
40
|
+
limitation: 'application-empty-error-states-AC-22104-1: the exact cause-shape regex (no UUID form, no identifier-prefixed slug) demanded by the AC is not enforced by this Node HTTP probe; the 403 + region + request-access + class-level-cause walk is a partial observation of AC-22104-1',
|
|
41
|
+
verdict: pass ? 'warn' : 'fail',
|
|
42
|
+
detail: pass
|
|
43
|
+
? `Given a mocked 403 response with a per-resource cause: observed role="region", class-level cause "${causeText}" (no 4+ digit run), [data-action="request-access"] control and data-cause-class="scope-missing" on the rendered surface; x-fixture-request-id=${pd.requestId}`
|
|
44
|
+
: `Given a mocked 403 response with a per-resource cause (evidence gap): status=${pd.status} rid=${pd.requestId} region=${region} cause="${causeText}" causeShape=${causeShape} action=${action} causeClass=${causeClass}`,
|
|
45
|
+
evidence: {
|
|
46
|
+
requestId: pd.requestId,
|
|
47
|
+
responseStatus: pd.status,
|
|
48
|
+
bodyExcerpt: excerpt((pd.body.match(/data-surface="permission-denied"[^]{0,220}/) || [''])[0]),
|
|
49
|
+
derived: { region, causeText, causeShape, action, causeClass },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// AC-22105-1 server-observable buffer lifecycle: flip state
|
|
54
|
+
// offline, POST a varied idempotency token, verify buffer grew,
|
|
55
|
+
// POST the same token and verify dedupe, POST a second distinct
|
|
56
|
+
// token, trigger reconnect and verify the buffer drained with
|
|
57
|
+
// the expected delivered count. Every step drives a varied
|
|
58
|
+
// input the fixture cannot see coming, and every assertion is on
|
|
59
|
+
// a derived output the fixture had no choice about.
|
|
60
|
+
const principalId = 'probe-offline-' + randomUUID();
|
|
61
|
+
// Baseline read (fresh principal begins with the seeded buffer of size 1).
|
|
62
|
+
const initial = await fixtureFetch(fixture.url, `/probe/offline/state?principal-id=${principalId}`);
|
|
63
|
+
const initialState = JSON.parse(initial.body || '{}');
|
|
64
|
+
// Flip to offline.
|
|
65
|
+
const flipOffline = await fixtureFetch(fixture.url, `/probe/offline/state?principal-id=${principalId}`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: { 'content-type': 'application/json' },
|
|
68
|
+
body: JSON.stringify({ state: 'offline' }),
|
|
69
|
+
});
|
|
70
|
+
// Enqueue a distinct token.
|
|
71
|
+
const tokenA = 'probe-write-' + randomUUID();
|
|
72
|
+
const enqA1 = await fixtureFetch(fixture.url, `/probe/offline/buffer?principal-id=${principalId}`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: { 'content-type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ idempotencyToken: tokenA, payload: { kind: 'note', body: 'first' } }),
|
|
76
|
+
});
|
|
77
|
+
const enqA1Body = JSON.parse(enqA1.body || '{}');
|
|
78
|
+
// Duplicate write with the SAME token must dedupe (no count increase).
|
|
79
|
+
const enqA2 = await fixtureFetch(fixture.url, `/probe/offline/buffer?principal-id=${principalId}`, {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers: { 'content-type': 'application/json' },
|
|
82
|
+
body: JSON.stringify({ idempotencyToken: tokenA, payload: { kind: 'note', body: 'first-again' } }),
|
|
83
|
+
});
|
|
84
|
+
const enqA2Body = JSON.parse(enqA2.body || '{}');
|
|
85
|
+
// Enqueue a second distinct token (count must go up).
|
|
86
|
+
const tokenB = 'probe-write-' + randomUUID();
|
|
87
|
+
const enqB = await fixtureFetch(fixture.url, `/probe/offline/buffer?principal-id=${principalId}`, {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
headers: { 'content-type': 'application/json' },
|
|
90
|
+
body: JSON.stringify({ idempotencyToken: tokenB, payload: { kind: 'note', body: 'second' } }),
|
|
91
|
+
});
|
|
92
|
+
const enqBBody = JSON.parse(enqB.body || '{}');
|
|
93
|
+
// Reconnect and drain.
|
|
94
|
+
const reconnect = await fixtureFetch(fixture.url, `/probe/offline/reconnect?principal-id=${principalId}`, { method: 'POST' });
|
|
95
|
+
const reconnectBody = JSON.parse(reconnect.body || '{}');
|
|
96
|
+
// Final GET reads state after reconnect: buffer drained.
|
|
97
|
+
const finalState = await fixtureFetch(fixture.url, `/probe/offline/state?principal-id=${principalId}`);
|
|
98
|
+
const finalStateBody = JSON.parse(finalState.body || '{}');
|
|
99
|
+
// Expectations per AC-22105-1:
|
|
100
|
+
// - offline enqueue grows the buffer count on distinct token
|
|
101
|
+
// - duplicate token does not grow the count (dedupe)
|
|
102
|
+
// - reconnect returns flushed count === buffer count at reconnect time
|
|
103
|
+
// - final state shows buffer empty and delivered count rose by the
|
|
104
|
+
// flushed count
|
|
105
|
+
const seededCount = initialState.bufferCount ?? 0;
|
|
106
|
+
const bufferAfterA1 = enqA1Body.bufferCount ?? 0;
|
|
107
|
+
const bufferAfterA2 = enqA2Body.bufferCount ?? 0;
|
|
108
|
+
const bufferAfterB = enqBBody.bufferCount ?? 0;
|
|
109
|
+
const flushedCount = reconnectBody.flushedCount ?? -1;
|
|
110
|
+
const deliveredAfter = finalStateBody.deliveredCount ?? -1;
|
|
111
|
+
const enqueueGrew = bufferAfterA1 === seededCount + 1;
|
|
112
|
+
const deduped = bufferAfterA2 === bufferAfterA1 && enqA2Body.deduped === true;
|
|
113
|
+
const secondEnqueueGrew = bufferAfterB === bufferAfterA1 + 1;
|
|
114
|
+
const flushedMatches = flushedCount === bufferAfterB;
|
|
115
|
+
const drained = (finalStateBody.bufferCount ?? -1) === 0 && finalStateBody.state === 'online';
|
|
116
|
+
const deliveredMatches = deliveredAfter === flushedCount;
|
|
117
|
+
const bufferPass = initial.status === 200 && !!initial.requestId
|
|
118
|
+
&& flipOffline.status === 200
|
|
119
|
+
&& enqA1.status === 200 && enqA2.status === 200 && enqB.status === 200
|
|
120
|
+
&& reconnect.status === 200 && finalState.status === 200
|
|
121
|
+
&& enqueueGrew && deduped && secondEnqueueGrew && flushedMatches && drained && deliveredMatches;
|
|
122
|
+
results.push({
|
|
123
|
+
anchorAcId: null,
|
|
124
|
+
conformanceOnly: true,
|
|
125
|
+
limitation: 'application-empty-error-states-AC-22105-1: the polite live-region announcement of the flushed count and the rendered banner / buffer-count visible on the SPA (the AC clauses beyond the server-side buffer lifecycle) are browser-driven and not observed by this Node HTTP probe; the offline-flip / enqueue / dedupe / reconnect / drain lifecycle is a partial observation of AC-22105-1',
|
|
126
|
+
verdict: bufferPass ? 'warn' : 'fail',
|
|
127
|
+
detail: bufferPass
|
|
128
|
+
? `Given navigator.onLine simulated false via the runtime seam: with the server-side buffer keyed to a fresh principalId, POST /probe/offline/state{state:offline} flipped the state; two distinct idempotency tokens enqueued (buffer count seededCount=${seededCount} -> ${bufferAfterA1} -> ${bufferAfterB}); duplicate token deduped (deduped=${enqA2Body.deduped}, count stayed ${bufferAfterA2}); POST /probe/offline/reconnect drained ${flushedCount} writes; final state shows bufferCount=0, state=online, deliveredCount=${deliveredAfter} equal to flushedCount; x-fixture-request-id (initial GET)=${initial.requestId}`
|
|
129
|
+
: `Given navigator.onLine simulated false via the runtime seam (evidence gap): seeded=${seededCount} afterA1=${bufferAfterA1} afterA2=${bufferAfterA2} afterB=${bufferAfterB} flushed=${flushedCount} delivered=${deliveredAfter} state=${finalStateBody.state} enqueueGrew=${enqueueGrew} deduped=${deduped} secondGrew=${secondEnqueueGrew} flushedMatches=${flushedMatches} drained=${drained} deliveredMatches=${deliveredMatches}`,
|
|
130
|
+
evidence: {
|
|
131
|
+
requestId: initial.requestId,
|
|
132
|
+
responseStatus: initial.status,
|
|
133
|
+
bodyExcerpt: excerpt(JSON.stringify({ initial: initialState, afterEnq: enqBBody, reconnect: reconnectBody, final: finalStateBody })),
|
|
134
|
+
derived: {
|
|
135
|
+
principalId,
|
|
136
|
+
seededCount,
|
|
137
|
+
bufferAfterA1,
|
|
138
|
+
bufferAfterA2,
|
|
139
|
+
bufferAfterB,
|
|
140
|
+
flushedCount,
|
|
141
|
+
deliveredAfter,
|
|
142
|
+
enqueueGrew,
|
|
143
|
+
deduped,
|
|
144
|
+
secondEnqueueGrew,
|
|
145
|
+
flushedMatches,
|
|
146
|
+
drained,
|
|
147
|
+
deliveredMatches,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
} finally {
|
|
152
|
+
await fixture.kill();
|
|
153
|
+
}
|
|
154
|
+
return { results };
|
|
155
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// Shared helpers for application-empty-error-states contributions/probes/.
|
|
2
|
+
//
|
|
3
|
+
// The real engine for every probe in this pack is the fixture HTTP
|
|
4
|
+
// server at packages/rcf-lite/test/fixtures/probe-pack-application-empty-error-states/server.js
|
|
5
|
+
// booted on a scratch port from the family range 47630-47639.
|
|
6
|
+
// The fixture echoes a per-request x-fixture-request-id header on
|
|
7
|
+
// every response; probes record that id and a response body excerpt
|
|
8
|
+
// as positive evidence per rule 7d.
|
|
9
|
+
//
|
|
10
|
+
// No account credentials or network calls: every probe is
|
|
11
|
+
// local-fixture-driven, so no probe carries an account-bound branch
|
|
12
|
+
// or a CI_HAS_* gate. Declared env vars are the fixture's own
|
|
13
|
+
// PORT and (where the fixture reads them) the CAPS/state switches
|
|
14
|
+
// the probes drive via query string.
|
|
15
|
+
|
|
16
|
+
import { spawn } from 'node:child_process';
|
|
17
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { createServer } from 'node:net';
|
|
19
|
+
import { dirname, resolve } from 'node:path';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
|
|
22
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
export const SLUG = 'application-empty-error-states';
|
|
25
|
+
export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
26
|
+
export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/probe-pack-application-empty-error-states');
|
|
27
|
+
export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/application-empty-error-states');
|
|
28
|
+
export const PORT_RANGE_START = 47630;
|
|
29
|
+
export const PORT_RANGE_END = 47639;
|
|
30
|
+
export const DECLARED_ENV = Object.freeze(['PORT', 'EMPTY_ERROR_STATES_BREAK', 'PROBE_BREAK']);
|
|
31
|
+
export const REQUEST_ID_HEADER = 'x-fixture-request-id';
|
|
32
|
+
|
|
33
|
+
// Pick a free port from the fixture family range. Falls back to
|
|
34
|
+
// asking the OS for an ephemeral port only if the whole range is
|
|
35
|
+
// held by other workers (never expected on a single-machine run).
|
|
36
|
+
export async function pickPort() {
|
|
37
|
+
for (let port = PORT_RANGE_START; port <= PORT_RANGE_END; port += 1) {
|
|
38
|
+
if (await canBind(port)) return port;
|
|
39
|
+
}
|
|
40
|
+
return await bindEphemeral();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function canBind(port) {
|
|
44
|
+
return new Promise((res) => {
|
|
45
|
+
const s = createServer();
|
|
46
|
+
s.once('error', () => res(false));
|
|
47
|
+
s.listen(port, '127.0.0.1', () => {
|
|
48
|
+
const bound = s.address();
|
|
49
|
+
s.close(() => res(!!bound));
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function bindEphemeral() {
|
|
55
|
+
return new Promise((res) => {
|
|
56
|
+
const s = createServer();
|
|
57
|
+
s.listen(0, '127.0.0.1', () => {
|
|
58
|
+
const port = s.address().port;
|
|
59
|
+
s.close(() => res(port));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Spawns the fixture server as a child on `port` with the given
|
|
65
|
+
// env overlay; resolves once the fixture has printed LISTENING and
|
|
66
|
+
// returns { child, url, kill } (kill is synchronous best-effort).
|
|
67
|
+
export async function startFixture({ port, env = {} } = {}) {
|
|
68
|
+
const boundPort = port ?? await pickPort();
|
|
69
|
+
const child = spawn(process.execPath, ['server.js'], {
|
|
70
|
+
cwd: FIXTURE_DIR,
|
|
71
|
+
env: { ...process.env, PORT: String(boundPort), ...env },
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
73
|
+
});
|
|
74
|
+
await new Promise((res, rej) => {
|
|
75
|
+
const timer = setTimeout(() => rej(new Error(`fixture did not print LISTENING within 4s on port ${boundPort}`)), 4000);
|
|
76
|
+
let stderrBuf = '';
|
|
77
|
+
child.stderr.on('data', (chunk) => { stderrBuf += String(chunk); });
|
|
78
|
+
child.on('exit', (code) => rej(new Error(`fixture exited early (code=${code}) stderr=${stderrBuf.slice(0, 400)}`)));
|
|
79
|
+
child.stdout.on('data', (chunk) => {
|
|
80
|
+
if (String(chunk).includes(`LISTENING ${boundPort}`)) { clearTimeout(timer); res(); }
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
const url = new URL(`http://127.0.0.1:${boundPort}`);
|
|
84
|
+
return {
|
|
85
|
+
child,
|
|
86
|
+
url,
|
|
87
|
+
port: boundPort,
|
|
88
|
+
// Await child exit and propagate any error. A teardown failure
|
|
89
|
+
// must fail the verdict (the teardown-propagation rule);
|
|
90
|
+
// no swallowed errors here.
|
|
91
|
+
kill: () => new Promise((res, rej) => {
|
|
92
|
+
let settled = false;
|
|
93
|
+
const done = (err) => { if (settled) return; settled = true; err ? rej(err) : res(); };
|
|
94
|
+
child.once('exit', () => done());
|
|
95
|
+
child.once('error', (err) => done(err));
|
|
96
|
+
try { child.kill('SIGTERM'); } catch (err) { return done(err); }
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
if (settled) return;
|
|
99
|
+
try { child.kill('SIGKILL'); } catch (err) { return done(err); }
|
|
100
|
+
}, 4000);
|
|
101
|
+
}),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Issue an HTTP request against the fixture and return
|
|
106
|
+
// { status, headers, body, requestId }.
|
|
107
|
+
export async function fixtureFetch(url, pathAndQuery, init = {}) {
|
|
108
|
+
const target = new URL(pathAndQuery, url);
|
|
109
|
+
const res = await fetch(target, init);
|
|
110
|
+
const body = await res.text();
|
|
111
|
+
const requestId = res.headers.get(REQUEST_ID_HEADER);
|
|
112
|
+
return { status: res.status, headers: Object.fromEntries(res.headers.entries()), body, requestId };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function excerpt(body, maxLen = 240) {
|
|
116
|
+
if (typeof body !== 'string') return '';
|
|
117
|
+
return body.length <= maxLen ? body : body.slice(0, maxLen) + '…';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function aggregate(results) {
|
|
121
|
+
// Positive-evidence rule: no-checks-ran is a fail.
|
|
122
|
+
if (!Array.isArray(results) || results.length === 0) return 'fail';
|
|
123
|
+
if (results.some((r) => r.verdict === 'fail')) return 'fail';
|
|
124
|
+
// Any warn row lifts the aggregate to warn, including honest
|
|
125
|
+
// notObservableHere de-claims. A probe whose rows are all warn
|
|
126
|
+
// aggregates to warn, not pass; the shelf reads amber and the tally
|
|
127
|
+
// accepts a warn aggregate as problems=0 when no fail row is present.
|
|
128
|
+
if (results.some((r) => r && r.verdict === 'warn')) return 'warn';
|
|
129
|
+
return 'pass';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function writeReport({ probeName, engine, results, extra }) {
|
|
133
|
+
await mkdir(REPORT_DIR, { recursive: true });
|
|
134
|
+
const report = {
|
|
135
|
+
slug: SLUG,
|
|
136
|
+
probeName,
|
|
137
|
+
runAt: new Date().toISOString(),
|
|
138
|
+
engine,
|
|
139
|
+
results,
|
|
140
|
+
aggregateVerdict: aggregate(results),
|
|
141
|
+
...(extra ?? {}),
|
|
142
|
+
};
|
|
143
|
+
const filepath = resolve(REPORT_DIR, `${probeName}.json`);
|
|
144
|
+
await writeFile(filepath, JSON.stringify(report, null, 2) + '\n', 'utf8');
|
|
145
|
+
return { report, path: filepath };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export async function runShim(probeName, engine, mainFn) {
|
|
149
|
+
try {
|
|
150
|
+
const outcome = (await mainFn()) ?? { results: [] };
|
|
151
|
+
const { results, extra } = outcome;
|
|
152
|
+
const { report, path: filepath } = await writeReport({ probeName, engine, results, extra });
|
|
153
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
154
|
+
process.stdout.write(`report written to ${filepath}\n`);
|
|
155
|
+
if (report.aggregateVerdict === 'fail') process.exitCode = 1;
|
|
156
|
+
} catch (err) {
|
|
157
|
+
// Positive-evidence rule (exception fallback): exception rows have no
|
|
158
|
+
// observed AC; anchor null (never a fabricated id like
|
|
159
|
+
// "unknown"), carry an evidence object with the error excerpt.
|
|
160
|
+
const message = err && err.message ? err.message : String(err);
|
|
161
|
+
const stack = err && err.stack ? err.stack : String(err);
|
|
162
|
+
const results = [{
|
|
163
|
+
anchorAcId: null,
|
|
164
|
+
verdict: 'fail',
|
|
165
|
+
detail: `probe threw: ${message}`,
|
|
166
|
+
evidence: {
|
|
167
|
+
errorMessage: message,
|
|
168
|
+
errorExcerpt: excerpt(stack, 480),
|
|
169
|
+
},
|
|
170
|
+
}];
|
|
171
|
+
const { report, path: filepath } = await writeReport({ probeName, engine, results });
|
|
172
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
173
|
+
process.stderr.write(`probe error: ${stack}\n`);
|
|
174
|
+
process.stderr.write(`report written to ${filepath}\n`);
|
|
175
|
+
process.exitCode = 1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './empty-list-and-no-search.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-empty-error-states/server.js', healthy: true };
|
|
5
|
+
runShim('empty-list-and-no-search', engine, runProbe);
|
package/blueprints/application-empty-error-states/contributions/probes/run-error-boundary-alert.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './error-boundary-alert.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-empty-error-states/server.js', healthy: true };
|
|
5
|
+
runShim('error-boundary-alert', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './forbidden-and-server-error.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-empty-error-states/server.js', healthy: true };
|
|
5
|
+
runShim('forbidden-and-server-error', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './not-found-and-recovery.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-empty-error-states/server.js', healthy: true };
|
|
5
|
+
runShim('not-found-and-recovery', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './permission-denied-and-offline.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-empty-error-states/server.js', healthy: true };
|
|
5
|
+
runShim('permission-denied-and-offline', engine, runProbe);
|
|
@@ -1,17 +1,56 @@
|
|
|
1
1
|
# application-error-handling CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.0.12 - 2026-09-11
|
|
4
|
+
|
|
5
|
+
- The AC-16102-4 (mid-stream close) row's shipped comment block in two-boundaries-registered.mjs is rewritten to describe the row as a full anchored counting result rather than a conformanceOnly slice with a browser-network limitation: every clause of the AC (connection closed without rewriting the wire, exactly one companion emission at error level naming the streaming-in-progress condition, and category 'unknown' unless supplied) is observable on this pack, and no browser-network sub-clause is carved out.
|
|
6
|
+
- The AC-16102-4 row's detail is rewritten to open with the AC's first eight words ("Given a handler that throws AFTER the response") and describes the observation directly, without the earlier "server-observable slice" wording. The predicate, evidence and verdict are unchanged; only the shipped comment and detail prose move.
|
|
7
|
+
- The shared anatomy result-shape helper (packages/rcf-lite/test/blueprint/_result-shape.mjs) adds a fourth tightening rule: a counting row (a row that reached the post-notObservableHere / post-conformanceOnly branch) must carry at least one shipped anchor - anchorAcId or anchorReqId. A negative synthetic case (unanchored counting row must fail) and a positive synthetic case (anchored counting row must pass) join the existing negative-cases helper; every family's anatomy suite exercises them via runResultShapeNegativeCases.
|
|
8
|
+
- Anatomy test pin bumped to 1.0.12.
|
|
9
|
+
|
|
10
|
+
## 1.0.11 - 2026-09-11
|
|
11
|
+
|
|
12
|
+
- AC-16102-4 (mid-stream close) is now a full counting row anchored on AC-16102-4 rather than conformanceOnly: the shipped AC description names only the connection-close, the exact companion emission, the level, message and category, and every clause is server-observable on this pack. The row records anchorAcId, verdict, a detail opening on the AC's first eight words, and evidence carrying route /stream-then-throw, status 200, the fixture-stamped x-fixture-request-id and a fully-populated derived object with the premature-close, exactly-one mid-stream emission, level, message-names-condition and category flags. The invented "browser-network view" limitation clause is dropped; AC-16102-4 no longer carries a browser-only sub-clause.
|
|
13
|
+
- Detail texts continue to open with the first eight words of the AC or REQ text they observe.
|
|
14
|
+
- Anatomy test pin bumped to 1.0.11.
|
|
15
|
+
|
|
16
|
+
## 1.0.10 - 2026-09-11
|
|
17
|
+
|
|
18
|
+
- AC-16102-4 (mid-stream close) pass predicate now REQUIRES the premature socket close: the two-boundaries-registered probe verdict is pass iff midStatus===200, prematureClose===true, exactlyOneMidEmission, midCategoryUnknown, midLevelError, and midMessageNamesCondition. A normal completed 200 response that happens to carry the partial-body prefix fails this row. `partialBodyReceived` is still recorded on evidence.derived but does not participate in the verdict.
|
|
19
|
+
- The probe now reads the response body incrementally via the ReadableStream reader so the partial-body prefix delivered before the socket abort is retained in evidence.derived.partialBodyReceived (and in evidence.bodyExcerpt) even when the read then throws; earlier revisions used res.text() which discarded already-delivered chunks on the abort.
|
|
20
|
+
- Anatomy test pin bumped to 1.0.10.
|
|
21
|
+
|
|
22
|
+
## 1.0.9 - 2026-09-11
|
|
23
|
+
|
|
24
|
+
- /stream-then-throw now flushes headers, writes the partial body and, once the write drains, tears the socket down via req.socket.destroy(); res.end() is deliberately not called, so a well-behaved client observes a premature-close error after receiving the 200 headers and the partial-body prefix.
|
|
25
|
+
- Companion invocations now record level (always 'error') and message alongside category, correlationId and source, so probes can observe the emitted level and the emitted message without parsing stderr.
|
|
26
|
+
- AC-16102-4 (mid-stream close) is a conformanceOnly row anchored on AC-16102-4: the probe drives /stream-then-throw and observes (i) the client's premature-close error after the partial-body prefix landed, (ii) exactly one companion emission with category='unknown', level='error', and a message naming the streaming-in-progress condition, and (iii) the recorded 200 status and x-fixture-request-id on the response. The limitation names that the browser-network view of the aborted socket (what a browser network log records for the close condition) is the only clause of AC-16102-4 not observed here.
|
|
27
|
+
- AC-16105-4 is now a conformanceOnly row anchored on AC-16105-4 in the category-vocabulary probe: the probe observes only clause (c), the record-construction refusal of an unelicited category token via /construct/<token>, and the limitation names that clauses (a) and (b) (the mapper reading the applied per-class contract for an elicited additional category and writing the elicited retry hint) require an applying project with a classification-additions elicit and a per-class retry contract, which this probe pack does not ship.
|
|
28
|
+
- Detail texts continue to open with the first eight words of the AC or REQ text they observe.
|
|
29
|
+
- Anatomy test pin bumped to 1.0.9.
|
|
30
|
+
|
|
31
|
+
## 1.0.8 - 2026-09-11
|
|
32
|
+
|
|
33
|
+
- Adds a contributions/probes pack meeting rule 7d.
|
|
34
|
+
- Probes: two-boundaries-registered, category-vocabulary, record-shape-adr-1701.
|
|
35
|
+
- Framework boundary probe drives /throw-handler whose handler throws an Error whose induced stack carries system-path substrings and a file-URI substring; the wire body is inspected for those substrings and for stack markers. That observation targets AC-16102-2 and is anchored to it.
|
|
36
|
+
- Process boundary probe spawns the fixture as a child with crashOnRequest=true, hits /crash-real which schedules a real uncaught throw via setImmediate after the response is committed; the registered uncaughtException handler emits the error record (code, category unknown, message, correlationId, cause with stack, context) ONLY through the injected logging companion (no direct stdout or stderr write of the record per REQ-004), then writes a level=info type=companion-dump JSON line to stderr carrying the companion's invocations array, then process.exit(1); the probe reads the companion-dump stderr line and OS exit code from the child.on('exit') event.
|
|
37
|
+
- REQ-004 companion-invocation observation reads the companion-dump stderr line the child writes just before process.exit; both the framework path (an in-process /throw-handler request) AND the process path (the emit written by the uncaughtException handler before process.exit) show up in the companion's invocation list on that same child. No in-process /crash-process short-circuit is used for REQ-004 evidence.
|
|
38
|
+
- AC-16102-4 (mid-stream close) is a conformanceOnly row anchored on AC-16102-4 in this version: the probe drives /stream-then-throw so the fixture flushes headers, writes a partial body, then the framework boundary catches a mid-stream exception, emits EXACTLY ONE record through the injected companion factory naming the streaming-in-progress condition with category 'unknown'; the row observes exact-one-emission and category server-side and carries a limitation naming that the browser-network wire-close half is not observable on a server-driven probe pack.
|
|
39
|
+
- The process-boundary result records the correlationId as its own record.correlationId, and the evidence status field carries the OS exit code (numeric), not an HTTP-shaped fabrication.
|
|
40
|
+
- Detail texts open with the first eight words of the AC or REQ text they observe.
|
|
41
|
+
- Anatomy test pin bumped to 1.0.8.
|
|
42
|
+
|
|
43
|
+
|
|
3
44
|
## 1.0.3 (register-sweep patch, 2026-09-10)
|
|
4
45
|
|
|
5
46
|
- Register: neutral wording in shipped prose (no capability change).
|
|
6
47
|
|
|
7
|
-
## 1.0.2 (
|
|
48
|
+
## 1.0.2 (2026-09-09)
|
|
8
49
|
|
|
9
50
|
- Adds top-level elicits[] block on blueprint.json declaring the one apply-time answer (classification-additions); backed by REQ-003 naming the transient/permanent/unknown defaults and the elicited-additions grammar per section 7c.
|
|
10
51
|
- Adds refusal-path ACs to US-16102 (stack-and-path scrubbing, non-Error throw defaults, mid-stream exception connection close), US-16104 (non-object context refusal, nested-and-array redaction, circular context handling), US-16105 (permanent no-Retry-After, unknown mapped as permanent, elicited-category retry contract), US-16106 (no-companion fallback stderr JSON single line, direct console.error passthrough, companion factory throw fallback), US-16107 (null-injection refusal, stub invocation contract, transportWriter throw recovery). US-16101 and US-16103 also extended with clean-shutdown preservation, browser-runtime path, double-throw handling, deep cause chain, cause-context redaction and null-vs-undefined cause discipline. Every story now at the 7a floor (4-5 ACs per story, 30 ACs total).
|
|
11
52
|
|
|
12
|
-
## 1.0.1 (
|
|
13
|
-
|
|
14
|
-
- hardening pass: chain-consistency lint zero (pass1 + pass2); added deliveredBy to every REQ, added ownerRef and disposition to every AC per section 7b, closed `boundaryFor` and `transportWriter` restatements on AC-16107-1 via ownerRef back to TAC-1701.
|
|
15
|
-
- Added AC-16101-2 (unhandled promise rejection: one record under the `unknown` category, process terminates with exit code 1) covering the 2026-09-08 review finding F-1 on TAC-1701.responsibilities[0].
|
|
16
|
-
|
|
53
|
+
## 1.0.1 (2026-09-09)
|
|
17
54
|
|
|
55
|
+
- Hardening cleanup: chain-consistency lint clean; added deliveredBy to every REQ, added ownerRef and disposition to every AC per section 7b, closed `boundaryFor` and `transportWriter` restatements on AC-16107-1 via ownerRef back to TAC-1701.
|
|
56
|
+
- Added AC-16101-2 (unhandled promise rejection: one record under the `unknown` category, process terminates with exit code 1) on TAC-1701.responsibilities[0], so applying projects have an explicit acceptance criterion for the unhandled-rejection path.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "application-error-handling",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"category": "application",
|
|
5
5
|
"providesRoles": [
|
|
6
6
|
"errorHandling"
|
|
@@ -108,5 +108,6 @@
|
|
|
108
108
|
"elicited": false,
|
|
109
109
|
"standardsTraceClause": "generic enterprise practice"
|
|
110
110
|
}
|
|
111
|
-
]
|
|
111
|
+
],
|
|
112
|
+
"updatedAt": "2026-09-11T16:04:17Z"
|
|
112
113
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// category-vocabulary probe for application-error-handling v1.0.12.
|
|
2
|
+
//
|
|
3
|
+
// Verifies the ADR-1702 recommended default vocabulary (transient,
|
|
4
|
+
// permanent, unknown) via REQ-003 for the pass rows and AC-16105-4
|
|
5
|
+
// for the unelicited-token refusal row.
|
|
6
|
+
//
|
|
7
|
+
// anchorReqId: application-error-handling-REQ-003 on the accepted
|
|
8
|
+
// vocabulary rows; anchorAcId: application-error-handling-AC-16105-4
|
|
9
|
+
// on the refusal row.
|
|
10
|
+
|
|
11
|
+
import { startFixture, evidenceFromResponse, conformanceOnlyResult } from './probe-utils.mjs';
|
|
12
|
+
|
|
13
|
+
export const anchorReqId = 'application-error-handling-REQ-003';
|
|
14
|
+
export const accountBound = false;
|
|
15
|
+
|
|
16
|
+
const RECOMMENDED = ['transient', 'permanent', 'unknown'];
|
|
17
|
+
|
|
18
|
+
export default async function runProbe() {
|
|
19
|
+
const { startServer } = await import('../../../../packages/rcf-lite/test/fixtures/probe-pack-application-error-handling/server.js');
|
|
20
|
+
const fixture = await startFixture({ startServer, port: 0 });
|
|
21
|
+
try {
|
|
22
|
+
const results = [];
|
|
23
|
+
for (const cat of RECOMMENDED) {
|
|
24
|
+
const res = await fetch(`${fixture.baseUrl}/construct/${cat}`);
|
|
25
|
+
const body = await res.text();
|
|
26
|
+
const rec = JSON.parse(body);
|
|
27
|
+
const pass = res.status === 200 && rec.category === cat;
|
|
28
|
+
results.push({
|
|
29
|
+
anchorReqId: 'application-error-handling-REQ-003',
|
|
30
|
+
verdict: pass ? 'pass' : 'fail',
|
|
31
|
+
detail: pass
|
|
32
|
+
? `Every error class is classified transient, permanent or - /construct/${cat} returned record with category="${cat}"`
|
|
33
|
+
: `Every error class is classified transient, permanent or - category fault: cat=${cat} status=${res.status} returnedCategory=${rec.category}`,
|
|
34
|
+
evidence: evidenceFromResponse({
|
|
35
|
+
route: `/construct/${cat}`,
|
|
36
|
+
response: res,
|
|
37
|
+
bodyText: body,
|
|
38
|
+
extraFields: {
|
|
39
|
+
input: { requestedCategory: cat },
|
|
40
|
+
derived: { returnedCategory: rec.category },
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// AC-16105-4 partial slice: the AC covers an applying project
|
|
47
|
+
// that elicited additional categories via the
|
|
48
|
+
// classification-additions elicit and asserts (a) the mapper
|
|
49
|
+
// reads the applied per-class contract, (b) it writes the
|
|
50
|
+
// elicited retry hint alongside the ADR-1702 defaults, and
|
|
51
|
+
// (c) an unelicited category token is refused at record
|
|
52
|
+
// construction per REQ-002. This probe pack ships no
|
|
53
|
+
// classification-additions elicit and no applied per-class
|
|
54
|
+
// retry contract, so clauses (a) and (b) cannot be observed
|
|
55
|
+
// here. The probe observes clause (c) only: /construct/<token>
|
|
56
|
+
// returns 400 naming the refused token and the accepted set,
|
|
57
|
+
// which is the record-construction refusal REQ-002 requires.
|
|
58
|
+
// The row is conformanceOnly anchored on AC-16105-4 with a
|
|
59
|
+
// limitation naming the two clauses not observed here.
|
|
60
|
+
const bad = await fetch(`${fixture.baseUrl}/construct/notARealCategory`);
|
|
61
|
+
const badBody = await bad.text();
|
|
62
|
+
const badParsed = JSON.parse(badBody);
|
|
63
|
+
const refusalOk = bad.status === 400
|
|
64
|
+
&& badParsed.error === 'unelicited-category'
|
|
65
|
+
&& badParsed.refused === 'notARealCategory'
|
|
66
|
+
&& Array.isArray(badParsed.accepted)
|
|
67
|
+
&& RECOMMENDED.every((c) => badParsed.accepted.includes(c));
|
|
68
|
+
results.push(conformanceOnlyResult({
|
|
69
|
+
anchorAcId: 'application-error-handling-AC-16105-4',
|
|
70
|
+
anchorReqId: 'application-error-handling-REQ-003',
|
|
71
|
+
verdict: refusalOk ? 'pass' : 'fail',
|
|
72
|
+
detail: refusalOk
|
|
73
|
+
? `Given a project that elicited additional categories via - refusal-of-unelicited slice observed: /construct/notARealCategory returns 400 error=unelicited-category refused=${badParsed.refused} accepted=${JSON.stringify(badParsed.accepted)}`
|
|
74
|
+
: `Given a project that elicited additional categories via - refusal fault: status=${bad.status} error=${badParsed.error} refused=${badParsed.refused} accepted=${JSON.stringify(badParsed.accepted)}`,
|
|
75
|
+
evidence: evidenceFromResponse({
|
|
76
|
+
route: '/construct/notARealCategory',
|
|
77
|
+
response: bad,
|
|
78
|
+
bodyText: badBody,
|
|
79
|
+
extraFields: {
|
|
80
|
+
input: { requestedCategory: 'notARealCategory' },
|
|
81
|
+
derived: { httpStatus: bad.status, refused: badParsed.refused, accepted: badParsed.accepted },
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
limitation: 'application-error-handling-AC-16105-4: the AC also requires (a) that the mapper reads the applied per-class contract for an elicited additional category and (b) that the wire response carries the retry hint the elicited class contract specifies; this probe pack ships no classification-additions elicit and no applied per-class retry contract, so those two clauses are not observed here. The observed clause is (c): an unelicited category token is refused at record construction (REQ-002 refusal path)',
|
|
85
|
+
}));
|
|
86
|
+
return { results };
|
|
87
|
+
} finally {
|
|
88
|
+
await fixture.close();
|
|
89
|
+
}
|
|
90
|
+
}
|