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
|
@@ -1,51 +1,92 @@
|
|
|
1
|
-
// Probe: hcloud dry-run mock
|
|
1
|
+
// Probe: hcloud dry-run mock.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
3
|
+
// accountBound: false. This is an offline mock-path fixture-shape
|
|
4
|
+
// scanner. A counting row for this family is a LIVE row whose
|
|
5
|
+
// identifier is a vendor-minted id (server id, snapshot id,
|
|
6
|
+
// firewall id, image id, engine request id, or the 64-hex Docker
|
|
7
|
+
// container id from `docker inspect`) with a derived observation
|
|
8
|
+
// from the vendor or the running server. The mock produces neither,
|
|
9
|
+
// so every row here is a `conformanceOnly` de-claim with
|
|
10
|
+
// `anchorAcId: null` and a `limitation` string naming the shipped
|
|
11
|
+
// AC clause the mock does not observe. Two rows carry the AC-37101-1
|
|
12
|
+
// and AC-37109-1 clauses (sole-reader source scan and provisioner
|
|
13
|
+
// ready shape; lifecycle event-secrecy scan and payload-key
|
|
14
|
+
// allow-list) as derived context but do not credit those ACs; the
|
|
15
|
+
// live observation is not carried on this blueprint under the
|
|
16
|
+
// shipped ACs (both are AMBER on E until a live row lands). Rows
|
|
17
|
+
// for AC-37103-1, AC-37108-1 and AC-37109-3 are the existing
|
|
18
|
+
// mock-path fixture-shape de-claims; the live observations live on
|
|
19
|
+
// the real-account probes.
|
|
8
20
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// fixture renderer writes it under hetzner/servers/rendered/ before the
|
|
13
|
-
// facade is exercised, and this probe reads it back and asserts an
|
|
14
|
-
// ssh-ed25519/ssh-rsa public-key line under the deploy user plus a
|
|
15
|
-
// NOPASSWD directive naming that user). The rendered-file assertion is
|
|
16
|
-
// what stops a mocked probe from passing while the real path fails on
|
|
17
|
-
// the same artefact (REQ-145 / AC-14501-1).
|
|
21
|
+
// `notObservableHere` is not used on these rows: the ACs are
|
|
22
|
+
// process/live-observable on the real-account probes, not
|
|
23
|
+
// browser-only shelf-shape.
|
|
18
24
|
//
|
|
19
25
|
// The probe body reads NO process.env.SIMULATE_ switch. Fixture-side
|
|
20
26
|
// mutations live in src/cloud-init-renderer.mjs, src/hcloud-mock.mjs
|
|
21
27
|
// and src/provisioner-facade.mjs and alter INPUT only.
|
|
22
|
-
//
|
|
23
|
-
// Assertions:
|
|
24
|
-
// - the facade opens on ready() and fires provisionerReady with a
|
|
25
|
-
// metadata-only payload {tool, apiHost}.
|
|
26
|
-
// - createServer parses the mocked JSON stdout and emits
|
|
27
|
-
// hetznerServerProvisioned with id, primaryIpv4, location=fsn1,
|
|
28
|
-
// serverType=cx23.
|
|
29
|
-
// - takeSnapshot fires hetznerSnapshotTaken with snapshot id and time.
|
|
30
|
-
// - destroyServer fires hetznerServerDestroyed with the id.
|
|
31
|
-
// - no event body across the run carries the token, an ssh private-key
|
|
32
|
-
// marker, or the rendered user-data bytes (event-secrecy check).
|
|
33
|
-
// - the rendered cloud-init file exists under the fixture's rendered
|
|
34
|
-
// directory and carries at least one ssh-ed25519 or ssh-rsa
|
|
35
|
-
// authorized-keys line under the deploy user plus a NOPASSWD
|
|
36
|
-
// directive naming that user (REQ-145 / AC-14501-1).
|
|
37
28
|
|
|
38
|
-
import { readFile,
|
|
39
|
-
import { relative, resolve } from 'node:path';
|
|
29
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
30
|
+
import { relative, resolve, join } from 'node:path';
|
|
40
31
|
import { FIXTURE_DIR, PROJECT_ROOT } from './probe-utils.mjs';
|
|
41
32
|
|
|
42
|
-
|
|
33
|
+
// This probe emits only `conformanceOnly` rows; no `anchorAcId` is
|
|
34
|
+
// exported at module scope. Each row carries `anchorAcId: null` and
|
|
35
|
+
// a `limitation` string naming the shipped AC the mock does not
|
|
36
|
+
// observe on this blueprint.
|
|
43
37
|
export const accountBound = false;
|
|
44
38
|
|
|
45
39
|
const TOKEN = 'test-fixture-token-000000000000000000000000000000000000000000';
|
|
46
40
|
const USER_DATA_MARKER = 'unattended-upgrades on for security updates';
|
|
47
41
|
const PRIVATE_KEY_MARKER = 'BEGIN OPENSSH PRIVATE KEY';
|
|
48
42
|
|
|
43
|
+
// REQ-006 permits exactly these event names in the fixture lifecycle.
|
|
44
|
+
// Payload key allow-list per event: any key not in the set is a
|
|
45
|
+
// leak the substring scan would miss (unexpected metadata reaching
|
|
46
|
+
// the observability sink).
|
|
47
|
+
const ALLOWED_EVENT_KEYS = {
|
|
48
|
+
provisionerReady: new Set(['event', 'tool', 'apiHost']),
|
|
49
|
+
hetznerServerProvisioned: new Set(['event', 'id', 'primaryIpv4', 'location', 'serverType', 'labels']),
|
|
50
|
+
hetznerSnapshotTaken: new Set(['event', 'serverId', 'snapshotId', 'wallClockTime']),
|
|
51
|
+
hetznerServerDestroyed: new Set(['event', 'id', 'wallClockTime']),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Recursively list every .mjs and .js file under a root directory,
|
|
55
|
+
// skipping node_modules and dot-dirs.
|
|
56
|
+
async function walkSource(root) {
|
|
57
|
+
const out = [];
|
|
58
|
+
const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
|
|
59
|
+
for (const e of entries) {
|
|
60
|
+
if (e.name === 'node_modules' || e.name.startsWith('.')) continue;
|
|
61
|
+
const full = join(root, e.name);
|
|
62
|
+
if (e.isDirectory()) out.push(...await walkSource(full));
|
|
63
|
+
else if (e.isFile() && /\.(mjs|js)$/.test(e.name)) out.push(full);
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function findSoleTokenReader(fixtureRoot, expectedReaderRelPath) {
|
|
69
|
+
const files = await walkSource(fixtureRoot);
|
|
70
|
+
const readers = [];
|
|
71
|
+
for (const f of files) {
|
|
72
|
+
let text;
|
|
73
|
+
try { text = await readFile(f, 'utf8'); } catch (_) { continue; }
|
|
74
|
+
// A "reader" is any line that names the variable and is not a
|
|
75
|
+
// comment or a documentation-only mention. Match any non-comment
|
|
76
|
+
// occurrence of HETZNER_ACCOUNT_API_KEY.
|
|
77
|
+
const lines = text.split('\n');
|
|
78
|
+
for (let i = 0; i < lines.length; i++) {
|
|
79
|
+
const line = lines[i];
|
|
80
|
+
if (!line.includes('HETZNER_ACCOUNT_API_KEY')) continue;
|
|
81
|
+
const stripped = line.trim();
|
|
82
|
+
if (stripped.startsWith('//') || stripped.startsWith('*')) continue;
|
|
83
|
+
readers.push({ file: relative(fixtureRoot, f), line: i + 1, snippet: line.trim().slice(0, 200) });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const unexpected = readers.filter((r) => r.file !== expectedReaderRelPath);
|
|
87
|
+
return { readers, unexpected, expectedReaderRelPath };
|
|
88
|
+
}
|
|
89
|
+
|
|
49
90
|
export default async function runProbe() {
|
|
50
91
|
const facadePath = resolve(FIXTURE_DIR, 'src/provisioner-facade.mjs');
|
|
51
92
|
const rendererPath = resolve(FIXTURE_DIR, 'src/cloud-init-renderer.mjs');
|
|
@@ -54,42 +95,29 @@ export default async function runProbe() {
|
|
|
54
95
|
const { renderCloudInitToFile } = await import(rendererPath);
|
|
55
96
|
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'));
|
|
56
97
|
const results = [];
|
|
98
|
+
let events = [];
|
|
99
|
+
|
|
100
|
+
// AC-37101-1 sole-reader source-tree scan is run first so its
|
|
101
|
+
// outcome can be folded into the single AC-37101-1 row below (both
|
|
102
|
+
// clauses combined). The provisioner facade module is expected to
|
|
103
|
+
// be the ONLY file in the fixture source tree that names
|
|
104
|
+
// HETZNER_ACCOUNT_API_KEY on a non-comment line, and there must be
|
|
105
|
+
// at least one such reader (zero readers fails the sole-reader
|
|
106
|
+
// observation, per the AC's "grep across the fixture source"
|
|
107
|
+
// clause).
|
|
108
|
+
const soleReader = await findSoleTokenReader(FIXTURE_DIR, 'src/provisioner-facade.mjs');
|
|
57
109
|
|
|
58
|
-
// Render the cloud-init to disk
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
110
|
+
// Render the cloud-init to disk (both mock and real paths consume
|
|
111
|
+
// the same file; the assertion that the file carries the deploy
|
|
112
|
+
// ssh-key and NOPASSWD lines is the sole responsibility of
|
|
113
|
+
// cloud-init-render-lint (AC-37104-1) and the real cloud-init
|
|
114
|
+
// baseline probe (AC-37105-1)).
|
|
62
115
|
const publicKeys = ['ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFakePubKeyForMockedRunHardeningH1 rcf-lite-ci-mock'];
|
|
63
116
|
const { renderedPath, rendered } = await renderCloudInitToFile(manifest, { publicKeys });
|
|
64
117
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// "mock passes while real path fails on the same artefact" class.
|
|
69
|
-
const renderedFromDisk = await readFile(renderedPath, 'utf8');
|
|
70
|
-
const sshKeyLine = /(ssh-ed25519|ssh-rsa)\s+/i.test(renderedFromDisk);
|
|
71
|
-
const nopasswdLine = /deploy\s+ALL\s*=\s*\(ALL\)\s+NOPASSWD/i.test(renderedFromDisk);
|
|
72
|
-
if (!sshKeyLine) {
|
|
73
|
-
results.push({
|
|
74
|
-
anchorAcId: 'AC-14501-1',
|
|
75
|
-
verdict: 'fail',
|
|
76
|
-
detail: `rendered cloud-init at ${relative(PROJECT_ROOT, renderedPath)} carries no ssh-ed25519 or ssh-rsa authorized-keys line for the deploy user; the real path would provision a server with an unusable authorized_keys entry.`,
|
|
77
|
-
});
|
|
78
|
-
} else if (!nopasswdLine) {
|
|
79
|
-
results.push({
|
|
80
|
-
anchorAcId: 'AC-14501-1',
|
|
81
|
-
verdict: 'fail',
|
|
82
|
-
detail: `rendered cloud-init at ${relative(PROJECT_ROOT, renderedPath)} carries no NOPASSWD directive for the deploy user; the six sudoed baseline checks would block on a tty prompt.`,
|
|
83
|
-
});
|
|
84
|
-
} else {
|
|
85
|
-
results.push({
|
|
86
|
-
anchorAcId: 'AC-14501-1',
|
|
87
|
-
verdict: 'pass',
|
|
88
|
-
detail: `rendered cloud-init at ${relative(PROJECT_ROOT, renderedPath)} carries an ssh public-key line for the deploy user (byteLength ${rendered.length}) and a NOPASSWD sudoers directive for that user; the mock and the real path consume the same artefact.`,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const { events, eventSink } = createEventLog();
|
|
118
|
+
const eventLog = createEventLog();
|
|
119
|
+
events = eventLog.events;
|
|
120
|
+
const eventSink = eventLog.eventSink;
|
|
93
121
|
const facade = createProvisionerFacade({
|
|
94
122
|
token: TOKEN,
|
|
95
123
|
tool: 'hcloud',
|
|
@@ -99,56 +127,290 @@ export default async function runProbe() {
|
|
|
99
127
|
try {
|
|
100
128
|
await facade.ready();
|
|
101
129
|
const server = await facade.createServer(manifest);
|
|
102
|
-
const snapshot = await facade.takeSnapshot(
|
|
130
|
+
const snapshot = await facade.takeSnapshot(
|
|
131
|
+
{ id: server.id, name: manifest.name },
|
|
132
|
+
`${manifest.name}-${new Date().toISOString()}`,
|
|
133
|
+
);
|
|
103
134
|
await facade.destroyServer(server);
|
|
104
135
|
const provisionerReady = events.find((e) => e.event === 'provisionerReady');
|
|
105
136
|
const provisioned = events.find((e) => e.event === 'hetznerServerProvisioned');
|
|
106
137
|
const snapped = events.find((e) => e.event === 'hetznerSnapshotTaken');
|
|
107
138
|
const destroyed = events.find((e) => e.event === 'hetznerServerDestroyed');
|
|
108
|
-
|
|
109
|
-
|
|
139
|
+
|
|
140
|
+
// AC-37101-1: single row combining BOTH clauses (source-tree
|
|
141
|
+
// sole-reader scan AND metadata-only provisionerReady payload).
|
|
142
|
+
// The row PASSES only if BOTH are observed positively; zero
|
|
143
|
+
// readers or an unexpected reader or a missing/malformed
|
|
144
|
+
// provisionerReady event FAILS the row.
|
|
145
|
+
const soleReaderSummary = {
|
|
146
|
+
expectedReader: soleReader.expectedReaderRelPath,
|
|
147
|
+
readerCount: soleReader.readers.length,
|
|
148
|
+
readers: soleReader.readers.map((r) => `${r.file}:${r.line}`),
|
|
149
|
+
source: 'fixture source-tree grep .mjs/.js',
|
|
150
|
+
};
|
|
151
|
+
// AC-37101-1: the mock cannot mint a vendor identifier. The
|
|
152
|
+
// sole-reader source-tree scan and the provisionerReady shape
|
|
153
|
+
// check are both carried on the row as derived context, but the
|
|
154
|
+
// row is a `conformanceOnly` de-claim of AC-37101-1; the
|
|
155
|
+
// verdict still gates on both clauses (zero readers, an
|
|
156
|
+
// unexpected reader outside src/provisioner-facade.mjs, a
|
|
157
|
+
// missing provisionerReady event, a wrong payload shape or
|
|
158
|
+
// unexpected keys FAIL the row).
|
|
159
|
+
const ac37101Limitation = 'AC-37101-1: sole-reader source scan and provisionerReady shape observed here as derived context, but the AC requires a vendor-minted identifier from a live provisioner run; this offline mock-path row is not credited. No live probe on this blueprint carries a positive AC-37101-1 observation, so AC-37101-1 is AMBER on E.';
|
|
160
|
+
if (soleReader.readers.length === 0) {
|
|
161
|
+
results.push({
|
|
162
|
+
anchorAcId: null,
|
|
163
|
+
conformanceOnly: true,
|
|
164
|
+
limitation: ac37101Limitation,
|
|
165
|
+
verdict: 'fail',
|
|
166
|
+
detail: `sole-reader source scan across the fixture .mjs/.js found ZERO non-comment references to HETZNER_ACCOUNT_API_KEY; the provisioner facade must be the sole reader and at least one reader must be observed positively.`,
|
|
167
|
+
evidence: {
|
|
168
|
+
...soleReaderSummary,
|
|
169
|
+
eventName: provisionerReady ? 'provisionerReady' : 'lifecycle-scan',
|
|
170
|
+
event: provisionerReady || null,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
} else if (soleReader.unexpected.length > 0) {
|
|
174
|
+
results.push({
|
|
175
|
+
anchorAcId: null,
|
|
176
|
+
conformanceOnly: true,
|
|
177
|
+
limitation: ac37101Limitation,
|
|
178
|
+
verdict: 'fail',
|
|
179
|
+
detail: `sole-reader source scan: HETZNER_ACCOUNT_API_KEY named outside src/provisioner-facade.mjs at ${soleReader.unexpected.map((r) => `${r.file}:${r.line}`).join(', ')}; the provisioner facade must be the SOLE reader.`,
|
|
180
|
+
evidence: {
|
|
181
|
+
...soleReaderSummary,
|
|
182
|
+
unexpectedReaders: soleReader.unexpected,
|
|
183
|
+
eventName: 'provisionerReady',
|
|
184
|
+
event: provisionerReady || null,
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
} else if (!provisionerReady) {
|
|
188
|
+
results.push({
|
|
189
|
+
anchorAcId: null,
|
|
190
|
+
conformanceOnly: true,
|
|
191
|
+
limitation: ac37101Limitation,
|
|
192
|
+
verdict: 'fail',
|
|
193
|
+
detail: `sole-reader scan observed ${soleReader.readers.length} reader(s), all inside ${soleReader.expectedReaderRelPath}; but provisionerReady did NOT fire on the injected event sink after ready(); events observed: ${events.map((e) => e.event).join(', ') || '(none)'}.`,
|
|
194
|
+
evidence: {
|
|
195
|
+
...soleReaderSummary,
|
|
196
|
+
eventName: 'provisionerReady',
|
|
197
|
+
eventFound: false,
|
|
198
|
+
observedEvents: events.map((e) => e.event),
|
|
199
|
+
},
|
|
200
|
+
});
|
|
110
201
|
} else if (provisionerReady.tool !== 'hcloud' || provisionerReady.apiHost !== 'https://api.hetzner.cloud/v1') {
|
|
111
|
-
results.push({
|
|
202
|
+
results.push({
|
|
203
|
+
anchorAcId: null,
|
|
204
|
+
conformanceOnly: true,
|
|
205
|
+
limitation: ac37101Limitation,
|
|
206
|
+
verdict: 'fail',
|
|
207
|
+
detail: `sole-reader scan observed ${soleReader.readers.length} reader(s) inside ${soleReader.expectedReaderRelPath}; provisionerReady payload shape is wrong: ${JSON.stringify(provisionerReady)}; expected {tool: 'hcloud', apiHost: 'https://api.hetzner.cloud/v1'}.`,
|
|
208
|
+
evidence: {
|
|
209
|
+
...soleReaderSummary,
|
|
210
|
+
eventName: 'provisionerReady',
|
|
211
|
+
event: provisionerReady,
|
|
212
|
+
expectedShape: { tool: 'hcloud', apiHost: 'https://api.hetzner.cloud/v1' },
|
|
213
|
+
},
|
|
214
|
+
});
|
|
112
215
|
} else {
|
|
113
|
-
|
|
216
|
+
const extraKeysOnEvent = Object.keys(provisionerReady).filter((k) => !['event', 'tool', 'apiHost'].includes(k));
|
|
217
|
+
if (extraKeysOnEvent.length > 0) {
|
|
218
|
+
results.push({
|
|
219
|
+
anchorAcId: null,
|
|
220
|
+
conformanceOnly: true,
|
|
221
|
+
limitation: ac37101Limitation,
|
|
222
|
+
verdict: 'fail',
|
|
223
|
+
detail: `sole-reader scan observed ${soleReader.readers.length} reader(s) inside ${soleReader.expectedReaderRelPath}; provisionerReady carries unexpected keys ${JSON.stringify(extraKeysOnEvent)} in addition to the metadata-only {event, tool, apiHost} set.`,
|
|
224
|
+
evidence: {
|
|
225
|
+
...soleReaderSummary,
|
|
226
|
+
eventName: 'provisionerReady',
|
|
227
|
+
event: provisionerReady,
|
|
228
|
+
unexpectedKeys: extraKeysOnEvent,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
} else {
|
|
232
|
+
results.push({
|
|
233
|
+
anchorAcId: null,
|
|
234
|
+
conformanceOnly: true,
|
|
235
|
+
limitation: ac37101Limitation,
|
|
236
|
+
verdict: 'pass',
|
|
237
|
+
detail: `sole-reader source scan observed exactly ${soleReader.readers.length} non-comment reader(s) of HETZNER_ACCOUNT_API_KEY across the fixture .mjs/.js, all inside ${soleReader.expectedReaderRelPath} (${soleReader.readers.map((r) => `${r.file}:${r.line}`).join(', ')}); provisionerReady fired with the metadata-only {tool, apiHost} payload.`,
|
|
238
|
+
evidence: {
|
|
239
|
+
...soleReaderSummary,
|
|
240
|
+
eventName: 'provisionerReady',
|
|
241
|
+
payloadKeys: Object.keys(provisionerReady).sort(),
|
|
242
|
+
observedTool: provisionerReady.tool,
|
|
243
|
+
observedApiHost: provisionerReady.apiHost,
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
114
247
|
}
|
|
248
|
+
|
|
249
|
+
// AC-37103-1 is a LIVE-only AC (its acceptance text requires the
|
|
250
|
+
// real-account apply plus a live `hcloud server list`). This
|
|
251
|
+
// mock-path row is a conformanceOnly fixture-shape observation
|
|
252
|
+
// (not a shelf-only property, so notObservableHere does NOT
|
|
253
|
+
// apply - that field is reserved for browser-only ACs); the row
|
|
254
|
+
// carries a shipped-AC limitation naming the live probe that
|
|
255
|
+
// observes the AC. The full-AC observation lives on
|
|
256
|
+
// real-account-throwaway-server-provision.
|
|
115
257
|
if (!provisioned || !provisioned.id || !provisioned.primaryIpv4 || provisioned.location !== 'fsn1' || provisioned.serverType !== 'cx23') {
|
|
116
|
-
results.push({
|
|
258
|
+
results.push({
|
|
259
|
+
anchorAcId: null,
|
|
260
|
+
conformanceOnly: true,
|
|
261
|
+
limitation: 'AC-37103-1: live inventory diff not observed here - mock-path fixture-shape check only; the AC observation is carried by real-account-throwaway-server-provision.',
|
|
262
|
+
verdict: 'fail',
|
|
263
|
+
detail: `mock-path fixture-shape check: hetznerServerProvisioned event body is missing or malformed: ${JSON.stringify(provisioned)}`,
|
|
264
|
+
evidence: { eventName: 'hetznerServerProvisioned', event: provisioned || null, expectedKeys: ['id', 'primaryIpv4', 'location', 'serverType'] },
|
|
265
|
+
});
|
|
117
266
|
} else {
|
|
118
|
-
results.push({
|
|
267
|
+
results.push({
|
|
268
|
+
anchorAcId: null,
|
|
269
|
+
conformanceOnly: true,
|
|
270
|
+
limitation: 'AC-37103-1: live inventory diff not observed here - mock-path fixture-shape check only; the AC observation is carried by real-account-throwaway-server-provision.',
|
|
271
|
+
verdict: 'pass',
|
|
272
|
+
detail: `mock-path fixture-shape check: facade emitted hetznerServerProvisioned with the expected key shape (id, primaryIpv4, location, serverType).`,
|
|
273
|
+
evidence: {
|
|
274
|
+
eventName: 'hetznerServerProvisioned',
|
|
275
|
+
id: provisioned.id,
|
|
276
|
+
primaryIpv4: provisioned.primaryIpv4,
|
|
277
|
+
location: provisioned.location,
|
|
278
|
+
serverType: provisioned.serverType,
|
|
279
|
+
payloadKeys: Object.keys(provisioned).sort(),
|
|
280
|
+
source: 'mock-facade',
|
|
281
|
+
expectedKeys: ['id', 'primaryIpv4', 'location', 'serverType'],
|
|
282
|
+
},
|
|
283
|
+
});
|
|
119
284
|
}
|
|
285
|
+
|
|
120
286
|
if (!snapped || !snapped.snapshotId || !snapped.wallClockTime) {
|
|
121
|
-
results.push({
|
|
287
|
+
results.push({
|
|
288
|
+
anchorAcId: null,
|
|
289
|
+
conformanceOnly: true,
|
|
290
|
+
limitation: 'AC-37108-1: live snapshot inventory not observed here - mock-path fixture-shape check only; the AC observation is carried by real-account-snapshot-on-demand.',
|
|
291
|
+
verdict: 'fail',
|
|
292
|
+
detail: `mock-path fixture-shape check: hetznerSnapshotTaken event body is missing or malformed: ${JSON.stringify(snapped)}`,
|
|
293
|
+
evidence: { eventName: 'hetznerSnapshotTaken', event: snapped || null, expectedKeys: ['snapshotId', 'wallClockTime'] },
|
|
294
|
+
});
|
|
295
|
+
} else {
|
|
296
|
+
results.push({
|
|
297
|
+
anchorAcId: null,
|
|
298
|
+
conformanceOnly: true,
|
|
299
|
+
limitation: 'AC-37108-1: live snapshot inventory not observed here - mock-path fixture-shape check only; the AC observation is carried by real-account-snapshot-on-demand.',
|
|
300
|
+
verdict: 'pass',
|
|
301
|
+
detail: `mock-path fixture-shape check: facade emitted hetznerSnapshotTaken with the expected key shape (snapshotId, wallClockTime).`,
|
|
302
|
+
evidence: {
|
|
303
|
+
eventName: 'hetznerSnapshotTaken',
|
|
304
|
+
snapshotId: snapped.snapshotId,
|
|
305
|
+
wallClockTime: snapped.wallClockTime,
|
|
306
|
+
payloadKeys: Object.keys(snapped).sort(),
|
|
307
|
+
source: 'mock-facade',
|
|
308
|
+
expectedKeys: ['snapshotId', 'wallClockTime'],
|
|
309
|
+
},
|
|
310
|
+
});
|
|
122
311
|
}
|
|
312
|
+
|
|
123
313
|
if (!destroyed || !destroyed.id) {
|
|
124
|
-
results.push({
|
|
314
|
+
results.push({
|
|
315
|
+
anchorAcId: null,
|
|
316
|
+
conformanceOnly: true,
|
|
317
|
+
limitation: 'AC-37109-3: repeat-run once-per-lifecycle observation not counted here - mock-path fixture-shape check only.',
|
|
318
|
+
verdict: 'fail',
|
|
319
|
+
detail: `mock-path fixture-shape check: hetznerServerDestroyed event body is missing or malformed: ${JSON.stringify(destroyed)}`,
|
|
320
|
+
evidence: { eventName: 'hetznerServerDestroyed', event: destroyed || null, expectedKeys: ['id'] },
|
|
321
|
+
});
|
|
322
|
+
} else {
|
|
323
|
+
results.push({
|
|
324
|
+
anchorAcId: null,
|
|
325
|
+
conformanceOnly: true,
|
|
326
|
+
limitation: 'AC-37109-3: repeat-run once-per-lifecycle observation not counted here - mock-path fixture-shape check only.',
|
|
327
|
+
verdict: 'pass',
|
|
328
|
+
detail: `mock-path fixture-shape check: facade emitted hetznerServerDestroyed with the destroyed id and a wall-clock timestamp in the payload.`,
|
|
329
|
+
evidence: {
|
|
330
|
+
eventName: 'hetznerServerDestroyed',
|
|
331
|
+
id: destroyed.id,
|
|
332
|
+
wallClockTime: destroyed.wallClockTime,
|
|
333
|
+
payloadKeys: Object.keys(destroyed).sort(),
|
|
334
|
+
source: 'mock-facade',
|
|
335
|
+
expectedKeys: ['id', 'wallClockTime'],
|
|
336
|
+
},
|
|
337
|
+
});
|
|
125
338
|
}
|
|
126
|
-
|
|
339
|
+
|
|
340
|
+
// AC-37109-1: event-secrecy scan across every event body PLUS
|
|
341
|
+
// payload-key allow-list: every event's keys must be a subset of
|
|
342
|
+
// the metadata fields REQ-006 permits. Unexpected keys FAIL the
|
|
343
|
+
// row (a leaked field the substring scan would miss).
|
|
127
344
|
const leaks = [];
|
|
345
|
+
const unexpectedKeys = [];
|
|
128
346
|
for (const e of events) {
|
|
129
347
|
const body = JSON.stringify(e);
|
|
130
348
|
if (body.includes(TOKEN)) leaks.push({ event: e.event, marker: 'HETZNER_ACCOUNT_API_KEY value' });
|
|
131
349
|
if (body.includes(PRIVATE_KEY_MARKER)) leaks.push({ event: e.event, marker: 'ssh private key' });
|
|
132
350
|
if (body.includes(USER_DATA_MARKER)) leaks.push({ event: e.event, marker: 'rendered user-data bytes' });
|
|
351
|
+
const allowed = ALLOWED_EVENT_KEYS[e.event];
|
|
352
|
+
if (!allowed) {
|
|
353
|
+
unexpectedKeys.push({ event: e.event, reason: 'unknown event name (not in the REQ-006 named lifecycle set)' });
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const extra = Object.keys(e).filter((k) => !allowed.has(k));
|
|
357
|
+
if (extra.length > 0) {
|
|
358
|
+
unexpectedKeys.push({ event: e.event, extraKeys: extra, allowedKeys: [...allowed].sort() });
|
|
359
|
+
}
|
|
133
360
|
}
|
|
134
|
-
|
|
361
|
+
// AC-37109-1: the mock lifecycle scan cannot mint a vendor
|
|
362
|
+
// identifier (mock ids are generated by the fixture-side
|
|
363
|
+
// hcloud-mock and are not vendor-echoed). The substring scan
|
|
364
|
+
// and the payload-key allow-list are carried on the row as
|
|
365
|
+
// derived context, but the row is a `conformanceOnly` de-claim;
|
|
366
|
+
// the verdict still gates on both clauses. No live probe on
|
|
367
|
+
// this blueprint carries a positive AC-37109-1 observation, so
|
|
368
|
+
// AC-37109-1 is AMBER on E.
|
|
369
|
+
const ac37109Limitation = 'AC-37109-1: event-secrecy substring scan and payload-key allow-list observed here as derived context on mock-emitted events, but the AC requires the live lifecycle sink from a vendor-driven run; this offline mock-path row is not credited.';
|
|
370
|
+
if (leaks.length > 0 || unexpectedKeys.length > 0) {
|
|
371
|
+
const bits = [];
|
|
372
|
+
if (leaks.length > 0) bits.push(`substring leak: ${leaks.map((l) => `${l.event} carries ${l.marker}`).join('; ')}`);
|
|
373
|
+
if (unexpectedKeys.length > 0) bits.push(`payload-key allow-list violated: ${unexpectedKeys.map((u) => u.extraKeys ? `${u.event}: extraKeys=${u.extraKeys.join(',')}` : `${u.event}: ${u.reason}`).join('; ')}`);
|
|
374
|
+
const failEvidence = {
|
|
375
|
+
eventName: 'lifecycle-scan',
|
|
376
|
+
leaks,
|
|
377
|
+
unexpectedKeys,
|
|
378
|
+
eventCount: events.length,
|
|
379
|
+
};
|
|
135
380
|
results.push({
|
|
136
|
-
anchorAcId:
|
|
381
|
+
anchorAcId: null,
|
|
382
|
+
conformanceOnly: true,
|
|
383
|
+
limitation: ac37109Limitation,
|
|
137
384
|
verdict: 'fail',
|
|
138
|
-
detail: `event-secrecy
|
|
385
|
+
detail: `event-secrecy fail: ${bits.join(' | ')}.`,
|
|
386
|
+
evidence: failEvidence,
|
|
139
387
|
});
|
|
140
388
|
} else {
|
|
389
|
+
const passEvidence = {
|
|
390
|
+
eventName: 'lifecycle-scan',
|
|
391
|
+
eventCount: events.length,
|
|
392
|
+
scannedMarkers: ['token value', 'ssh private key', 'user-data marker'],
|
|
393
|
+
allowedKeysByEvent: Object.fromEntries(Object.entries(ALLOWED_EVENT_KEYS).map(([k, v]) => [k, [...v].sort()])),
|
|
394
|
+
leaks: [],
|
|
395
|
+
unexpectedKeys: [],
|
|
396
|
+
};
|
|
141
397
|
results.push({
|
|
142
|
-
anchorAcId:
|
|
398
|
+
anchorAcId: null,
|
|
399
|
+
conformanceOnly: true,
|
|
400
|
+
limitation: ac37109Limitation,
|
|
143
401
|
verdict: 'pass',
|
|
144
|
-
detail: `event-secrecy scan across ${events.length} event bodies found no leak of the token, ssh private key, or user-data content.`,
|
|
402
|
+
detail: `event-secrecy scan across ${events.length} event bodies found no leak of the token, ssh private key, or user-data content; every event payload's keys are a subset of the REQ-006 named metadata set.`,
|
|
403
|
+
evidence: passEvidence,
|
|
145
404
|
});
|
|
146
405
|
}
|
|
147
406
|
} catch (err) {
|
|
148
407
|
results.push({
|
|
149
|
-
anchorAcId:
|
|
408
|
+
anchorAcId: null,
|
|
409
|
+
conformanceOnly: true,
|
|
410
|
+
limitation: 'AC-37101-1: provisioner facade lifecycle threw during the offline mock-path scan; the AC requires a live provisioner run.',
|
|
150
411
|
verdict: 'fail',
|
|
151
|
-
detail: `provisioner facade lifecycle threw: ${err.message}
|
|
412
|
+
detail: `provisioner facade lifecycle threw: ${err.message}`,
|
|
413
|
+
evidence: { eventName: 'lifecycle-error', error: err.message, errorStack: (err.stack || '').slice(0, 400) },
|
|
152
414
|
});
|
|
153
415
|
}
|
|
154
416
|
return {
|
|
@@ -158,7 +420,6 @@ export default async function runProbe() {
|
|
|
158
420
|
events: events.map((e) => ({ event: e.event, keys: Object.keys(e).sort() })),
|
|
159
421
|
renderedPath: relative(PROJECT_ROOT, renderedPath),
|
|
160
422
|
renderedByteLength: rendered.length,
|
|
161
|
-
renderedAssertions: { sshKeyLine, nopasswdLine },
|
|
162
423
|
},
|
|
163
424
|
};
|
|
164
425
|
}
|