rcf-lite 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +10 -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 +45 -0
- package/rcf/code-nodes/cn-601.json +18 -0
- package/rcf/code-nodes/cn-602.json +15 -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 +17 -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 +45 -0
- package/rcf/fbs/fbs-182.json +42 -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 +39 -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 +39 -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 +166 -0
- package/rcf/test-suites/ts-189.json +38 -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 +51 -0
- package/rcf/user-stories/us-15701.json +42 -0
- package/rcf/user-stories/us-15801.json +42 -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 +11 -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 +2204 -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 +361 -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 +1108 -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,177 @@
|
|
|
1
|
+
// Shared helpers for application-admin-console 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-admin-console/server.js
|
|
5
|
+
// booted on a scratch port from the family range 47600-47609.
|
|
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-admin-console';
|
|
25
|
+
export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
26
|
+
export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/probe-pack-application-admin-console');
|
|
27
|
+
export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/application-admin-console');
|
|
28
|
+
export const PORT_RANGE_START = 47600;
|
|
29
|
+
export const PORT_RANGE_END = 47609;
|
|
30
|
+
export const DECLARED_ENV = Object.freeze(['PORT', 'ADMIN_CONSOLE_CAPS', 'ADMIN_CONSOLE_BREAK', 'ADMIN_CONSOLE_PRINCIPAL_EMAIL', '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
|
+
}
|
package/blueprints/application-admin-console/contributions/probes/run-org-switcher-surface.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './org-switcher-surface.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-admin-console/server.js', healthy: true };
|
|
5
|
+
runShim('org-switcher-surface', engine, runProbe);
|
package/blueprints/application-admin-console/contributions/probes/run-permission-matrix-grid.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './permission-matrix-grid.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-admin-console/server.js', healthy: true };
|
|
5
|
+
runShim('permission-matrix-grid', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './sign-in-access-gated-surface.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-admin-console/server.js', healthy: true };
|
|
5
|
+
runShim('sign-in-access-gated-surface', engine, runProbe);
|
package/blueprints/application-admin-console/contributions/probes/run-users-directory-surface.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './users-directory-surface.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'fixture', image: 'test/fixtures/probe-pack-application-admin-console/server.js', healthy: true };
|
|
5
|
+
runShim('users-directory-surface', engine, runProbe);
|
package/blueprints/application-admin-console/contributions/probes/sign-in-access-gated-surface.mjs
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// application-admin-console probe: sign-in surface across the three
|
|
2
|
+
// shipped ACs for the sign-in stories - the Access-gated render with
|
|
3
|
+
// request.auth present (AC-21815-1), the 403 refusal when
|
|
4
|
+
// request.auth is missing (AC-21815-2) and the local-login fallback
|
|
5
|
+
// when zeroTrustGate is not applied (AC-21816-1). Each row detail
|
|
6
|
+
// opens on the first eight words of the AC it anchors (rule 10).
|
|
7
|
+
//
|
|
8
|
+
// AC-21815-1 requires: with zeroTrustGate applied, GET /admin/sign-in
|
|
9
|
+
// renders [data-surface=access-gated], no [data-surface=local-login]
|
|
10
|
+
// region is present, and [data-role=principal-read] carries the
|
|
11
|
+
// principal email read from request.auth.
|
|
12
|
+
//
|
|
13
|
+
// AC-21815-2 requires: with zeroTrustGate applied but request.auth
|
|
14
|
+
// absent, the route refuses with HTTP 403, the DOM carries the
|
|
15
|
+
// access-denied surface, no principal-read element is rendered and
|
|
16
|
+
// no protected data is served.
|
|
17
|
+
//
|
|
18
|
+
// AC-21816-1 requires: without zeroTrustGate applied, GET /admin/sign-in
|
|
19
|
+
// renders [data-surface=local-login] and no [data-surface=access-gated]
|
|
20
|
+
// region; the local login form ships with data-role=local-login-form
|
|
21
|
+
// and data-action=local-sign-in controls.
|
|
22
|
+
|
|
23
|
+
import { fixtureFetch, startFixture, excerpt } from './probe-utils.mjs';
|
|
24
|
+
|
|
25
|
+
export const anchorAcId = 'application-admin-console-AC-21815-1';
|
|
26
|
+
export const accountBound = false;
|
|
27
|
+
|
|
28
|
+
export default async function runProbe() {
|
|
29
|
+
const results = [];
|
|
30
|
+
const principalEmail = 'probe-signin@example.test';
|
|
31
|
+
|
|
32
|
+
const gated = await startFixture({ env: { ADMIN_CONSOLE_CAPS: 'principalDirectory,zeroTrustGate' } });
|
|
33
|
+
try {
|
|
34
|
+
// Row 1: AC-21815-1 with an Authorization header populating request.auth.
|
|
35
|
+
const withAuth = await fixtureFetch(gated.url, '/admin/sign-in', {
|
|
36
|
+
headers: { authorization: `Bearer ${principalEmail}` },
|
|
37
|
+
});
|
|
38
|
+
const accessGatedPresent = /data-surface="access-gated"/.test(withAuth.body);
|
|
39
|
+
const localLoginPresent = /data-surface="local-login"/.test(withAuth.body);
|
|
40
|
+
const principalReadPresent = /data-role="principal-read"/.test(withAuth.body);
|
|
41
|
+
const principalEmailPresent = withAuth.body.includes(principalEmail);
|
|
42
|
+
const gatedPass = withAuth.status === 200 && !!withAuth.requestId
|
|
43
|
+
&& accessGatedPresent && !localLoginPresent
|
|
44
|
+
&& principalReadPresent && principalEmailPresent;
|
|
45
|
+
results.push({
|
|
46
|
+
anchorAcId: 'application-admin-console-AC-21815-1',
|
|
47
|
+
verdict: gatedPass ? 'pass' : 'fail',
|
|
48
|
+
detail: gatedPass
|
|
49
|
+
? `When application-admin-console v1.1.0 is applied with zeroTrustGate in appliedCapabilities: GET /admin/sign-in with Authorization: Bearer ${principalEmail} returned 200 rendering [data-surface="access-gated"] with no [data-surface="local-login"] and a [data-role="principal-read"] element carrying the principal email read from request.auth; x-fixture-request-id=${withAuth.requestId}`
|
|
50
|
+
: `When application-admin-console v1.1.0 is applied with zeroTrustGate in appliedCapabilities (gap): status=${withAuth.status} rid=${withAuth.requestId} gated=${accessGatedPresent} localLogin=${localLoginPresent} principalRead=${principalReadPresent} emailPresent=${principalEmailPresent}`,
|
|
51
|
+
evidence: {
|
|
52
|
+
requestId: withAuth.requestId,
|
|
53
|
+
responseStatus: withAuth.status,
|
|
54
|
+
bodyExcerpt: excerpt((withAuth.body.match(/data-surface="access-gated"[^]{0,240}/) || [''])[0]),
|
|
55
|
+
derived: { accessGatedPresent, localLoginPresent, principalReadPresent, principalEmailPresent },
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Row 2: AC-21815-2 refusal-when-request.auth-absent path,
|
|
60
|
+
// observed at the fixture itself. The fixture now returns HTTP
|
|
61
|
+
// 403 with a [data-surface="access-denied"] region and no
|
|
62
|
+
// [data-role="principal-read"] element when zeroTrustGate is
|
|
63
|
+
// applied and the Authorization header is missing.
|
|
64
|
+
const noAuth = await fixtureFetch(gated.url, '/admin/sign-in');
|
|
65
|
+
const deniedPresent = /data-surface="access-denied"/.test(noAuth.body);
|
|
66
|
+
const noPrincipalRead = !/data-role="principal-read"/.test(noAuth.body);
|
|
67
|
+
const noGatedSurface = !/data-surface="access-gated"/.test(noAuth.body);
|
|
68
|
+
const refusalPass = noAuth.status === 403 && !!noAuth.requestId
|
|
69
|
+
&& deniedPresent && noPrincipalRead && noGatedSurface;
|
|
70
|
+
results.push({
|
|
71
|
+
anchorAcId: null,
|
|
72
|
+
conformanceOnly: true,
|
|
73
|
+
limitation: 'application-admin-console-AC-21815-2: refusal-log capability field checking against a shipped log adapter (the AC clause requiring the refusal event to be recorded with the required capability fields) is not observed by this Node HTTP probe; the HTTP-403 + access-denied surface walk when zeroTrustGate is applied and Authorization is missing is a partial observation of AC-21815-2',
|
|
74
|
+
verdict: refusalPass ? 'warn' : 'fail',
|
|
75
|
+
detail: refusalPass
|
|
76
|
+
? `When zeroTrustGate is applied but the incoming request lacks request.auth: GET /admin/sign-in with no Authorization header returned HTTP 403 rendering [data-surface="access-denied"], with no [data-role="principal-read"] element and no [data-surface="access-gated"] region; x-fixture-request-id=${noAuth.requestId}`
|
|
77
|
+
: `When zeroTrustGate is applied but the incoming request lacks request.auth (gap): status=${noAuth.status} rid=${noAuth.requestId} deniedPresent=${deniedPresent} noPrincipalRead=${noPrincipalRead} noGatedSurface=${noGatedSurface}`,
|
|
78
|
+
evidence: {
|
|
79
|
+
requestId: noAuth.requestId,
|
|
80
|
+
responseStatus: noAuth.status,
|
|
81
|
+
bodyExcerpt: excerpt((noAuth.body.match(/data-surface="access-denied"[^]{0,240}/) || [''])[0]),
|
|
82
|
+
derived: { deniedPresent, noPrincipalRead, noGatedSurface },
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
} finally {
|
|
86
|
+
await gated.kill();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const local = await startFixture({ env: { ADMIN_CONSOLE_CAPS: 'principalDirectory' } });
|
|
90
|
+
try {
|
|
91
|
+
// Row 3: AC-21816-1 fallback branch (zeroTrustGate not applied).
|
|
92
|
+
const r = await fixtureFetch(local.url, '/admin/sign-in');
|
|
93
|
+
const accessGatedPresent = /data-surface="access-gated"/.test(r.body);
|
|
94
|
+
const localLoginPresent = /data-surface="local-login"/.test(r.body);
|
|
95
|
+
const localFormPresent = /data-role="local-login-form"/.test(r.body);
|
|
96
|
+
const localSignInControl = /data-action="local-sign-in"/.test(r.body);
|
|
97
|
+
const pass = r.status === 200 && !!r.requestId
|
|
98
|
+
&& !accessGatedPresent && localLoginPresent
|
|
99
|
+
&& localFormPresent && localSignInControl;
|
|
100
|
+
results.push({
|
|
101
|
+
anchorAcId: 'application-admin-console-AC-21816-1',
|
|
102
|
+
verdict: pass ? 'pass' : 'fail',
|
|
103
|
+
detail: pass
|
|
104
|
+
? `When application-admin-console v1.1.0 is applied without zeroTrustGate in appliedCapabilities: GET /admin/sign-in returned 200 rendering [data-surface="local-login"] with no [data-surface="access-gated"] region; the local login form carries data-role="local-login-form" and a data-action="local-sign-in" submit control; x-fixture-request-id=${r.requestId}`
|
|
105
|
+
: `When application-admin-console v1.1.0 is applied without zeroTrustGate in appliedCapabilities (gap): status=${r.status} rid=${r.requestId} gated=${accessGatedPresent} localLogin=${localLoginPresent} form=${localFormPresent} signInControl=${localSignInControl}`,
|
|
106
|
+
evidence: {
|
|
107
|
+
requestId: r.requestId,
|
|
108
|
+
responseStatus: r.status,
|
|
109
|
+
bodyExcerpt: excerpt((r.body.match(/data-surface="local-login"[^]{0,240}/) || [''])[0]),
|
|
110
|
+
derived: { accessGatedPresent, localLoginPresent, localFormPresent, localSignInControl },
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
} finally {
|
|
114
|
+
await local.kill();
|
|
115
|
+
}
|
|
116
|
+
return { results };
|
|
117
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// application-admin-console probe: users directory surface.
|
|
2
|
+
//
|
|
3
|
+
// De-claim first, observe second. This probe splits observation
|
|
4
|
+
// across the two shipped ACs for the users-directory story: the
|
|
5
|
+
// directory listing contract (AC-21102-1) and the per-row
|
|
6
|
+
// invite/deactivate action controls (AC-21102-2). Each row detail
|
|
7
|
+
// opens on the first eight words of the shipped AC it anchors (rule 10).
|
|
8
|
+
//
|
|
9
|
+
// AC-21102-1 requires: with principalDirectory applied AND admin
|
|
10
|
+
// scope, the users table lists every principal by data-user-id with
|
|
11
|
+
// a role column (only when roleModel is applied), a last-active
|
|
12
|
+
// timestamp and a status column; a principal without admin scope
|
|
13
|
+
// hitting /admin renders an access-denied state with a request-access
|
|
14
|
+
// control routing to POST /api/request-access.
|
|
15
|
+
//
|
|
16
|
+
// AC-21102-2 requires: each row exposes an invite control for a
|
|
17
|
+
// principal without an active session (data-action="invite") and a
|
|
18
|
+
// deactivate control for an active principal (data-action="deactivate");
|
|
19
|
+
// the controls are keyboard-reachable buttons.
|
|
20
|
+
|
|
21
|
+
import { fixtureFetch, startFixture, excerpt } from './probe-utils.mjs';
|
|
22
|
+
|
|
23
|
+
export const anchorAcId = 'application-admin-console-AC-21102-1';
|
|
24
|
+
export const accountBound = false;
|
|
25
|
+
|
|
26
|
+
export default async function runProbe() {
|
|
27
|
+
const withRole = await startFixture({ env: { ADMIN_CONSOLE_CAPS: 'principalDirectory,roleModel' } });
|
|
28
|
+
const results = [];
|
|
29
|
+
try {
|
|
30
|
+
const r = await fixtureFetch(withRole.url, '/admin/users');
|
|
31
|
+
const rowIds = [...r.body.matchAll(/data-user-id="([^"]+)"/g)].map((m) => m[1]);
|
|
32
|
+
const distinctRowIds = [...new Set(rowIds)];
|
|
33
|
+
const roleColumnPresent = /<th data-column="role">/.test(r.body);
|
|
34
|
+
const roleCellCount = (r.body.match(/<td data-column="role">/g) || []).length;
|
|
35
|
+
const statusColumnPresent = /<th data-column="status">/.test(r.body);
|
|
36
|
+
const lastActiveColumnPresent = /<th data-column="lastActive">/.test(r.body);
|
|
37
|
+
const inviteBtnCount = (r.body.match(/data-action="invite" data-user-id="/g) || []).length;
|
|
38
|
+
const deactivateBtnCount = (r.body.match(/data-action="deactivate" data-user-id="/g) || []).length;
|
|
39
|
+
|
|
40
|
+
// Row 1: AC-21102-1 directory-listing contract with roleModel applied.
|
|
41
|
+
const listingPass = r.status === 200 && !!r.requestId
|
|
42
|
+
&& distinctRowIds.length > 0
|
|
43
|
+
&& roleColumnPresent
|
|
44
|
+
&& roleCellCount === distinctRowIds.length
|
|
45
|
+
&& statusColumnPresent
|
|
46
|
+
&& lastActiveColumnPresent;
|
|
47
|
+
results.push({
|
|
48
|
+
anchorAcId: null,
|
|
49
|
+
conformanceOnly: true,
|
|
50
|
+
limitation: 'application-admin-console-AC-21102-1: inventory-completeness reconciliation against the applied provider adapter (every principal in the provider inventory rendered with populated role, last-active and status values) is not observed by this Node HTTP probe against a fixed fixture; the directory-shell walk is a partial observation of AC-21102-1',
|
|
51
|
+
verdict: listingPass ? 'warn' : 'fail',
|
|
52
|
+
detail: listingPass
|
|
53
|
+
? `Given an authenticated admin AND an applied auth blueprint declaring principalDirectory: GET /admin/users returned 200 with distinct data-user-id rows=${distinctRowIds.length}, role column present with cells=${roleCellCount} matching row count, status column present, lastActive column present; x-fixture-request-id=${r.requestId}`
|
|
54
|
+
: `Given an authenticated admin AND an applied auth blueprint listing gap: status=${r.status} rid=${r.requestId} rows=${distinctRowIds.length} roleColumn=${roleColumnPresent} roleCells=${roleCellCount} statusColumn=${statusColumnPresent} lastActiveColumn=${lastActiveColumnPresent}`,
|
|
55
|
+
evidence: {
|
|
56
|
+
requestId: r.requestId,
|
|
57
|
+
responseStatus: r.status,
|
|
58
|
+
bodyExcerpt: excerpt((r.body.match(/<tr data-user-id="[^"]+">[^]{0,180}/) || [''])[0]),
|
|
59
|
+
derived: { rowCount: distinctRowIds.length, roleColumnPresent, roleCellCount, statusColumnPresent, lastActiveColumnPresent },
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Row 2: AC-21102-2 per-row invite/deactivate action controls.
|
|
64
|
+
// Every row must carry exactly one action (invite if pending, deactivate if active).
|
|
65
|
+
const perRowAction = distinctRowIds.every((id) => {
|
|
66
|
+
const inviteHere = new RegExp(`data-action="invite" data-user-id="${id}"`).test(r.body);
|
|
67
|
+
const deactivateHere = new RegExp(`data-action="deactivate" data-user-id="${id}"`).test(r.body);
|
|
68
|
+
return (inviteHere && !deactivateHere) || (!inviteHere && deactivateHere);
|
|
69
|
+
});
|
|
70
|
+
const actionButtonsAreButtons = /(<button[^>]*data-action="invite"|<button[^>]*data-action="deactivate")/.test(r.body);
|
|
71
|
+
const actionPass = r.status === 200 && !!r.requestId
|
|
72
|
+
&& distinctRowIds.length > 0
|
|
73
|
+
&& (inviteBtnCount + deactivateBtnCount) === distinctRowIds.length
|
|
74
|
+
&& perRowAction
|
|
75
|
+
&& actionButtonsAreButtons;
|
|
76
|
+
results.push({
|
|
77
|
+
anchorAcId: null,
|
|
78
|
+
conformanceOnly: true,
|
|
79
|
+
limitation: 'application-admin-console-AC-21102-2: state-to-action correlation (deactivate offered on active sessions, invite offered on pending) against varied per-principal states is not observed by this Node HTTP probe against a fixed fixture; the per-row action-control walk is a partial observation of AC-21102-2',
|
|
80
|
+
verdict: actionPass ? 'warn' : 'fail',
|
|
81
|
+
detail: actionPass
|
|
82
|
+
? `Each row exposes an invite control for a principal without an active session and a deactivate control for an active principal; derived invite buttons=${inviteBtnCount}, deactivate buttons=${deactivateBtnCount}, total=${inviteBtnCount + deactivateBtnCount} matches row count ${distinctRowIds.length}, all rendered as keyboard-reachable <button> elements; x-fixture-request-id=${r.requestId}`
|
|
83
|
+
: `Each row exposes an invite control for a action gap: status=${r.status} rid=${r.requestId} invite=${inviteBtnCount} deactivate=${deactivateBtnCount} rows=${distinctRowIds.length} perRowAction=${perRowAction} buttonElements=${actionButtonsAreButtons}`,
|
|
84
|
+
evidence: {
|
|
85
|
+
requestId: r.requestId,
|
|
86
|
+
responseStatus: r.status,
|
|
87
|
+
bodyExcerpt: excerpt((r.body.match(/<button[^>]*data-action="(?:invite|deactivate)"[^>]{0,180}/) || [''])[0]),
|
|
88
|
+
derived: { inviteBtnCount, deactivateBtnCount, rowCount: distinctRowIds.length, perRowAction, actionButtonsAreButtons },
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
} finally {
|
|
92
|
+
await withRole.kill();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const noRole = await startFixture({ env: { ADMIN_CONSOLE_CAPS: 'principalDirectory' } });
|
|
96
|
+
try {
|
|
97
|
+
// Row 3: AC-21102-1 role-column-suppression when roleModel is absent.
|
|
98
|
+
const r = await fixtureFetch(noRole.url, '/admin/users');
|
|
99
|
+
const rowIds = [...r.body.matchAll(/data-user-id="([^"]+)"/g)].map((m) => m[1]);
|
|
100
|
+
const distinctRowIds = [...new Set(rowIds)];
|
|
101
|
+
const roleColumnPresent = /<th data-column="role">/.test(r.body);
|
|
102
|
+
const suppressionPass = r.status === 200 && !!r.requestId
|
|
103
|
+
&& distinctRowIds.length > 0
|
|
104
|
+
&& !roleColumnPresent;
|
|
105
|
+
results.push({
|
|
106
|
+
anchorAcId: null,
|
|
107
|
+
conformanceOnly: true,
|
|
108
|
+
limitation: 'application-admin-console-AC-21102-1: the full directory-listing contract (every provider principal enumerated with populated status and last-active) is not observed by this Node HTTP probe against a fixed fixture; the role-column suppression walk (when roleModel is not applied) is a partial observation of AC-21102-1',
|
|
109
|
+
verdict: suppressionPass ? 'warn' : 'fail',
|
|
110
|
+
detail: suppressionPass
|
|
111
|
+
? `Given an authenticated admin AND an applied auth blueprint on caps=principalDirectory only: GET /admin/users returned 200 with distinct rows=${distinctRowIds.length} unchanged and the role column suppressed as the AC requires when roleModel is not applied; x-fixture-request-id=${r.requestId}`
|
|
112
|
+
: `Given an authenticated admin AND an applied auth blueprint suppression gap: status=${r.status} rid=${r.requestId} rows=${distinctRowIds.length} roleColumn=${roleColumnPresent}`,
|
|
113
|
+
evidence: {
|
|
114
|
+
requestId: r.requestId,
|
|
115
|
+
responseStatus: r.status,
|
|
116
|
+
bodyExcerpt: excerpt((r.body.match(/<thead>[^]{0,200}/) || [''])[0]),
|
|
117
|
+
derived: { rowCount: distinctRowIds.length, roleColumnPresent },
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Row 4: AC-21102-1 access-denied surface with request-access control.
|
|
122
|
+
const denied = await fixtureFetch(noRole.url, '/admin/users?asAdmin=false');
|
|
123
|
+
const hasDeniedRegion = /data-surface="denied"/.test(denied.body);
|
|
124
|
+
const hasRequestAccess = /data-action="request-access"/.test(denied.body);
|
|
125
|
+
const deniedPass = denied.status === 200 && !!denied.requestId && hasDeniedRegion && hasRequestAccess;
|
|
126
|
+
results.push({
|
|
127
|
+
anchorAcId: null,
|
|
128
|
+
conformanceOnly: true,
|
|
129
|
+
limitation: 'application-admin-console-AC-21102-1: request-access control activation and outcome against a routed API are browser-driven and not observed by this Node HTTP probe; the denied-surface walk on the not-authorised branch is a partial observation of AC-21102-1',
|
|
130
|
+
verdict: deniedPass ? 'warn' : 'fail',
|
|
131
|
+
detail: deniedPass
|
|
132
|
+
? `Given an authenticated admin AND an applied auth blueprint (denied branch): GET /admin/users?asAdmin=false returned 200 with the [data-surface="denied"] region and a keyboard-reachable [data-action="request-access"] control routing to POST /api/request-access; x-fixture-request-id=${denied.requestId}`
|
|
133
|
+
: `Given an authenticated admin AND an applied auth blueprint denied-branch gap: status=${denied.status} rid=${denied.requestId} deniedRegion=${hasDeniedRegion} requestAccess=${hasRequestAccess}`,
|
|
134
|
+
evidence: {
|
|
135
|
+
requestId: denied.requestId,
|
|
136
|
+
responseStatus: denied.status,
|
|
137
|
+
bodyExcerpt: excerpt((denied.body.match(/data-surface="denied"[^]{0,220}/) || [''])[0]),
|
|
138
|
+
derived: { hasDeniedRegion, hasRequestAccess },
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
} finally {
|
|
142
|
+
await noRole.kill();
|
|
143
|
+
}
|
|
144
|
+
return { results };
|
|
145
|
+
}
|
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
# application-api-rest CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 2.1.10 - 2026-09-11
|
|
4
|
+
|
|
5
|
+
- Adds a contributions/probes pack meeting rule 7d: each probe drives a real HTTP round trip against the dependency-free sample-app fixture at packages/rcf-lite/test/fixtures/probe-pack-application-api-rest/ and records the fixture-echoed x-fixture-request-id, response status, a distinctive body excerpt, the varied input and the derived output on every result row.
|
|
6
|
+
- Probes: cursor-pagination-round-trip, problem-details-on-error, health-probes-distinct, request-id-echoed.
|
|
7
|
+
- Cursor probe varies limits and derives forward/backward traversal from server-side cursor state (opaque UUID keys over a CURSOR_MAP, not positional JSON); malformed cursor and over-limit rows produce 400 with problem-details bodies anchored on AC-2109-3 and AC-2109-5.
|
|
8
|
+
- Liveness returns 200 with zero dependency checks and readiness reports checked dependencies (matches AC-2108-1).
|
|
9
|
+
- Detail texts open with the first eight words of the AC or REQ text they observe, then " - " and the derived observation.
|
|
10
|
+
- Anatomy test pin bumped to 2.1.10; strict evidence predicate; notObservableHere.ac resolves against a shipped AC id.
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
## 2.1.5 - 2026-09-10
|
|
4
14
|
|
|
5
|
-
|
|
15
|
+
Template-AC fill-in clauses on AC-2102-2, AC-2104-6, AC-2106-4, AC-2108-4, AC-2112-1, AC-2118-3 and AC-2119-5 now enumerate the specific applying-project substitutions (declared property-name casing, documentation-exposure policy per environment, operation-to-auth-class mapping onto the four classes fixed on REQ-005, resolved startup-probe path, idempotency-key verb-and-class combinations, deploy documentation location and order, verification-pipeline definition) in place of the earlier generic phrasing, so applying projects have precise values to fill in. TAC-303-application-api-rest-contract-surface patch-bumped to 1.0.2: responsibilities[2] now names `x-idempotency-key` (`required` or `forbidden`) explicitly and references AC-2112-1.
|
|
6
16
|
|
|
7
17
|
|
|
8
18
|
## 2.1.4 - 2026-09-10
|
|
9
19
|
|
|
10
|
-
Dimension-d single-definition-ownership cleanup on REQ-013: REQ description now references the request-id header owned on TAC-301.responsibilities[0] rather than restating the header literal. Chain-consistency lint
|
|
20
|
+
Dimension-d single-definition-ownership cleanup on REQ-013: REQ description now references the request-id header owned on TAC-301.responsibilities[0] rather than restating the header literal. Chain-consistency lint clean.
|
|
11
21
|
|
|
12
22
|
## 2.1.3 (register-sweep patch, 2026-09-10)
|
|
13
23
|
|
|
14
24
|
- Register: neutral wording in shipped prose (no capability change).
|
|
15
25
|
|
|
16
|
-
## 2.1.2 (
|
|
26
|
+
## 2.1.2 (2026-09-09)
|
|
17
27
|
|
|
18
28
|
- Donor hand-sweep on all 118 ACs: flipped 24 additional ACs from fixed to template where the assertion carries a project-set literal (deprecation dates, per-endpoint auth-class binding, downstream dependency sets on readiness, resolved probe paths, declared page-size and maximum limits, filter parameter and sortable-key sets, key-required operation set, de-duplication TTL, per-class rate-limit values and window durations, per-endpoint rate-limit overrides, log-level per class, histogram bucket boundaries, per-endpoint CORS overrides, PII-redaction policy). Each flipped AC carries an Applying agent sets: <specific values> clause. Final split: 87 fixed / 31 template.
|
|
19
29
|
- Adds vendorCitation to seven ACs whose assertions rest on RFC wire shapes: AC-2102-3 cites RFC 3339 (Date and Time on the Internet: Timestamps); AC-2111-1 through AC-2111-6 cite RFC 7807 (Problem Details for HTTP APIs). Both citation URLs point at datatracker.ietf.org and carry verifiedOn 2026-09-09 (fetched via WebFetch during this pass).
|
|
20
30
|
|
|
21
|
-
## 2.1.1 (
|
|
22
|
-
|
|
23
|
-
- hardening pass: chain-consistency lint zero (pass1 + pass2); added deliveredBy to every REQ, added ownerRef and disposition to every AC per section 7b, closed case drifts on `content-type` and `idempotency-key` in REQ-002, REQ-010, AC-2102-4, AC-2102-5, AC-2112-1, AC-2112-2 and ADR-306 to match the owner spellings on TAC-301.
|
|
24
|
-
- Added AC-2108-9 (readiness deadline: aggregate 503 naming the failed check id and the configured deadline while liveness continues at 200) covering the 2026-09-08 review finding F-1 on TAC-306.interfaces[0] (readiness check registry).
|
|
25
|
-
|
|
31
|
+
## 2.1.1 (2026-09-09)
|
|
26
32
|
|
|
33
|
+
- Hardening cleanup: chain-consistency lint clean; added deliveredBy to every REQ, added ownerRef and disposition to every AC per section 7b, closed case drifts on `content-type` and `idempotency-key` in REQ-002, REQ-010, AC-2102-4, AC-2102-5, AC-2112-1, AC-2112-2 and ADR-306 to match the owner spellings on TAC-301.
|
|
34
|
+
- Added AC-2108-9 (readiness deadline: aggregate 503 naming the failed check id and the configured deadline while liveness continues at 200) on TAC-306.interfaces[0] (readiness check registry), so applying projects have an explicit acceptance criterion for the readiness-deadline path.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# application-api-rest blueprint (v2.0.0)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A content blueprint on the rcf-build-lite blueprint mechanism. Scope: a REST service, single deployable, versioned wire contract, no UI in scope. Composes with the application-spa blueprint by design, including two deliberate scope:global conflicts.
|
|
4
4
|
|
|
5
5
|
## Apply
|
|
6
6
|
|
|
@@ -27,9 +27,9 @@ The doc set is contributions (copied into the project tree by `rcf define bluepr
|
|
|
27
27
|
|
|
28
28
|
## What it contributes, and what it deliberately does not
|
|
29
29
|
|
|
30
|
-
Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (
|
|
30
|
+
Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (shipped policy 5) and no code.
|
|
31
31
|
|
|
32
|
-
No FBS contributions, as a matter of principle (
|
|
32
|
+
No FBS contributions, as a matter of principle (policy): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT; the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
|
|
33
33
|
|
|
34
34
|
## The four global decisions
|
|
35
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "application-api-rest",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.10",
|
|
4
4
|
"category": "application",
|
|
5
5
|
"contributions": [
|
|
6
6
|
{
|
|
@@ -269,5 +269,6 @@
|
|
|
269
269
|
"role": "errorHandling",
|
|
270
270
|
"reason": "The error translator writes the wire envelope from the internal record; an error-handling companion supplies the record factory and the boundary that constructs it, and the shelf application-error-handling blueprint is the fallback when no library provider is registered."
|
|
271
271
|
}
|
|
272
|
-
]
|
|
272
|
+
],
|
|
273
|
+
"updatedAt": "2026-09-11T16:04:17Z"
|
|
273
274
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
{
|
|
13
13
|
"name": "Per-endpoint auth annotations without classes",
|
|
14
14
|
"summary": "Each endpoint declares its own middleware stack of auth requirements.",
|
|
15
|
-
"reasonNotChosen": "Infinite postures means no enumerable audit story; every endpoint is a bespoke security
|
|
15
|
+
"reasonNotChosen": "Infinite postures means no enumerable audit story; every endpoint is a bespoke security assessment, and rate limiting and audit logging cannot attach to anything stable."
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "Gateway-terminated auth only",
|