rcf-lite 0.21.0 → 0.22.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 +16 -0
- package/blueprints/application-account-settings/CHANGELOG.md +12 -0
- package/blueprints/application-account-settings/README.md +114 -0
- package/blueprints/application-account-settings/blueprint.json +234 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2601-application-account-settings-capability-vocabulary.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2603-application-account-settings-theme-persistence.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2604-application-account-settings-reauth-window.json +20 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +18 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +41 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +28 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +35 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +40 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25101.json +34 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25102.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25103.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25104.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +33 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25107.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25108.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25109.json +33 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25110.json +27 -0
- package/blueprints/application-account-settings/docs/topics.md +48 -0
- package/blueprints/application-account-settings/guide/application-account-settings.md +30 -0
- package/blueprints/application-account-settings/probe-packs/application-account-settings.pack.mjs +246 -0
- package/blueprints/application-admin-console/docs/topics.md +7 -0
- package/blueprints/application-api-rest/docs/topics.md +8 -1
- package/blueprints/application-charts/docs/topics.md +7 -0
- package/blueprints/application-dashboard/docs/topics.md +7 -0
- package/blueprints/application-datatable/docs/topics.md +7 -0
- package/blueprints/application-empty-error-states/CHANGELOG.md +9 -0
- package/blueprints/application-empty-error-states/README.md +88 -0
- package/blueprints/application-empty-error-states/blueprint.json +119 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2301-application-empty-error-states-status-contract.json +25 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2302-application-empty-error-states-stack-trace-visibility.json +25 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2303-application-empty-error-states-offline-strategy.json +25 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +18 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +46 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +36 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +40 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22101.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22102.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22103.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22104.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22105.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22106.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22107.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22108.json +29 -0
- package/blueprints/application-empty-error-states/docs/topics.md +53 -0
- package/blueprints/application-empty-error-states/guide/application-empty-error-states.md +50 -0
- package/blueprints/application-empty-error-states/probe-packs/application-empty-error-states.pack.mjs +284 -0
- package/blueprints/application-error-handling/docs/topics.md +7 -0
- package/blueprints/application-file-upload/CHANGELOG.md +9 -0
- package/blueprints/application-file-upload/README.md +85 -0
- package/blueprints/application-file-upload/blueprint.json +114 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2401-application-file-upload-transport.json +25 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2402-application-file-upload-accepted-set.json +25 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2403-application-file-upload-virus-scan.json +25 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +18 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +46 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +47 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +46 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23101.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23103.json +29 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23104.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +29 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23106.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23107.json +28 -0
- package/blueprints/application-file-upload/docs/topics.md +58 -0
- package/blueprints/application-file-upload/guide/application-file-upload.md +48 -0
- package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +238 -0
- package/blueprints/application-forms-wizard/CHANGELOG.md +9 -0
- package/blueprints/application-forms-wizard/README.md +102 -0
- package/blueprints/application-forms-wizard/blueprint.json +120 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2501-application-forms-wizard-navigation.json +25 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2502-application-forms-wizard-save-and-return.json +25 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2503-application-forms-wizard-step-indicator.json +25 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +18 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +46 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +40 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +40 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24102.json +29 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24103.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24104.json +29 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24105.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24106.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24107.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24108.json +29 -0
- package/blueprints/application-forms-wizard/docs/topics.md +49 -0
- package/blueprints/application-forms-wizard/guide/application-forms-wizard.md +48 -0
- package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +233 -0
- package/blueprints/application-notifications-in-app/docs/topics.md +7 -0
- package/blueprints/application-onboarding-tour/CHANGELOG.md +12 -0
- package/blueprints/application-onboarding-tour/README.md +77 -0
- package/blueprints/application-onboarding-tour/blueprint.json +164 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2701-application-onboarding-tour-dismissal-policy.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2702-application-onboarding-tour-completion-store-shape.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2703-application-onboarding-tour-checklist-anchor.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +41 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +35 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +34 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26101.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26102.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26103.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26104.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26105.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26106.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26107.json +27 -0
- package/blueprints/application-onboarding-tour/docs/topics.md +48 -0
- package/blueprints/application-onboarding-tour/guide/application-onboarding-tour.md +59 -0
- package/blueprints/application-onboarding-tour/probe-packs/application-onboarding-tour.pack.mjs +231 -0
- package/blueprints/application-spa/docs/topics.md +8 -1
- package/blueprints/delivery-ci-workflows/docs/topics.md +8 -1
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +8 -1
- package/blueprints/email-smtp-resend/docs/topics.md +8 -1
- package/blueprints/object-storage-s3/CHANGELOG.md +13 -0
- package/blueprints/object-storage-s3/README.md +108 -0
- package/blueprints/object-storage-s3/blueprint.json +72 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2901-object-storage-s3-adapter.json +30 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2902-object-storage-s3-presigned-ttl-floor.json +25 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2903-object-storage-s3-multipart-threshold.json +25 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2904-object-storage-s3-contract.json +25 -0
- package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +103 -0
- package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +43 -0
- package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +84 -0
- package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +101 -0
- package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +85 -0
- package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +84 -0
- package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +64 -0
- package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +10 -0
- package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +7 -0
- package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +18 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +57 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +36 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +36 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +43 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +25 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +25 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28107.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28108.json +34 -0
- package/blueprints/object-storage-s3/docs/topics.md +62 -0
- package/blueprints/object-storage-s3/guide/object-storage-s3.md +207 -0
- package/blueprints/observability-essentials/docs/topics.md +8 -1
- package/blueprints/observability-logging/CHANGELOG.md +4 -0
- package/blueprints/observability-logging/README.md +3 -0
- package/blueprints/observability-logging/blueprint.json +3 -2
- package/blueprints/observability-logging/docs/topics.md +7 -0
- package/blueprints/observability-probe-endpoints/docs/topics.md +8 -1
- package/blueprints/persistence-data-d1/docs/topics.md +8 -1
- package/blueprints/persistence-data-postgres/CHANGELOG.md +12 -0
- package/blueprints/persistence-data-postgres/README.md +101 -0
- package/blueprints/persistence-data-postgres/blueprint.json +80 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +30 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2802-persistence-data-postgres-migration-shape.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2803-persistence-data-postgres-runner-mode.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2804-persistence-data-postgres-recovery.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2805-persistence-data-postgres-connection-pool-posture.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +56 -0
- package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +75 -0
- package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +56 -0
- package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +186 -0
- package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +76 -0
- package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +173 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-facade-round-trip.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-migration-apply.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-pool-posture-smoke.mjs +9 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-prepared-statement-scan.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-recovery-restore-round-trip.mjs +9 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-transaction-atomicity.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +79 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +58 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +40 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +35 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +40 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +34 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +25 -0
- package/blueprints/persistence-data-postgres/docs/topics.md +64 -0
- package/blueprints/persistence-data-postgres/guide/persistence-data-postgres.md +172 -0
- package/blueprints/persistence-data-sqlite/docs/topics.md +8 -1
- package/blueprints/security-auth-clerk/CHANGELOG.md +4 -0
- package/blueprints/security-auth-clerk/README.md +3 -0
- package/blueprints/security-auth-clerk/blueprint.json +147 -30
- package/blueprints/security-auth-clerk/docs/topics.md +8 -1
- package/blueprints/security-auth-keycloak/CHANGELOG.md +4 -0
- package/blueprints/security-auth-keycloak/README.md +3 -0
- package/blueprints/security-auth-keycloak/blueprint.json +182 -37
- package/blueprints/security-auth-keycloak/docs/topics.md +8 -1
- package/blueprints/security-auth-magic-link/CHANGELOG.md +4 -0
- package/blueprints/security-auth-magic-link/README.md +3 -0
- package/blueprints/security-auth-magic-link/blueprint.json +159 -33
- package/blueprints/security-auth-magic-link/docs/topics.md +8 -1
- package/blueprints/security-auth-oauth2/CHANGELOG.md +4 -0
- package/blueprints/security-auth-oauth2/README.md +3 -0
- package/blueprints/security-auth-oauth2/blueprint.json +158 -32
- package/blueprints/security-auth-oauth2/docs/topics.md +8 -1
- package/blueprints/security-secrets-management/CHANGELOG.md +11 -0
- package/blueprints/security-secrets-management/blueprint.json +2 -1
- package/blueprints/security-secrets-management/docs/topics.md +8 -1
- package/fixtures/canary-manifest.json +9 -9
- package/package.json +1 -1
- package/rcf/code-nodes/cn-134.json +13 -0
- package/rcf/code-nodes/cn-135.json +12 -0
- package/rcf/code-nodes/cn-136.json +13 -0
- package/rcf/code-nodes/cn-137.json +13 -0
- package/rcf/code-nodes/cn-138.json +12 -0
- package/rcf/code-nodes/cn-139.json +12 -0
- package/rcf/code-nodes/cn-140.json +13 -0
- package/rcf/code-nodes/cn-141.json +13 -0
- package/rcf/code-nodes/cn-142.json +12 -0
- package/rcf/code-nodes/cn-143.json +13 -0
- package/rcf/code-nodes/cn-144.json +13 -0
- package/rcf/code-nodes/cn-145.json +12 -0
- package/rcf/code-nodes/cn-146.json +12 -0
- package/rcf/code-nodes/cn-147.json +13 -0
- package/rcf/code-nodes/cn-148.json +13 -0
- package/rcf/code-nodes/cn-149.json +12 -0
- package/rcf/code-nodes/cn-150.json +13 -0
- package/rcf/code-nodes/cn-151.json +13 -0
- package/rcf/code-nodes/cn-152.json +12 -0
- package/rcf/code-nodes/cn-153.json +12 -0
- package/rcf/code-nodes/cn-154.json +13 -0
- package/rcf/code-nodes/cn-155.json +14 -0
- package/rcf/code-nodes/cn-156.json +13 -0
- package/rcf/code-nodes/cn-157.json +13 -0
- package/rcf/code-nodes/cn-158.json +12 -0
- package/rcf/code-nodes/cn-159.json +13 -0
- package/rcf/code-nodes/cn-160.json +12 -0
- package/rcf/code-nodes/cn-161.json +12 -0
- package/rcf/code-nodes/cn-162.json +13 -0
- package/rcf/code-nodes/cn-163.json +12 -0
- package/rcf/code-nodes/cn-164.json +13 -0
- package/rcf/code-nodes/cn-165.json +12 -0
- package/rcf/code-nodes/cn-166.json +12 -0
- package/rcf/code-nodes/cn-167.json +12 -0
- package/rcf/code-nodes/cn-168.json +12 -0
- package/rcf/code-nodes/cn-169.json +12 -0
- package/rcf/code-nodes/cn-170.json +12 -0
- package/rcf/code-nodes/cn-171.json +12 -0
- package/rcf/code-nodes/cn-172.json +12 -0
- package/rcf/code-nodes/cn-173.json +12 -0
- package/rcf/code-nodes/cn-174.json +12 -0
- package/rcf/code-nodes/cn-175.json +13 -0
- package/rcf/code-nodes/cn-176.json +12 -0
- package/rcf/code-nodes/cn-177.json +12 -0
- package/rcf/code-nodes/cn-178.json +12 -0
- package/rcf/code-nodes/cn-179.json +12 -0
- package/rcf/code-nodes/cn-180.json +13 -0
- package/rcf/code-nodes/cn-181.json +12 -0
- package/rcf/code-nodes/cn-182.json +13 -0
- package/rcf/code-nodes/cn-183.json +12 -0
- package/rcf/code-nodes/cn-184.json +13 -0
- package/rcf/code-nodes/cn-185.json +12 -0
- package/rcf/code-nodes/cn-186.json +12 -0
- package/rcf/code-nodes/cn-200.json +14 -0
- package/rcf/code-nodes/cn-201.json +13 -0
- package/rcf/code-nodes/cn-202.json +14 -0
- package/rcf/code-nodes/cn-203.json +14 -0
- package/rcf/code-nodes/cn-204.json +13 -0
- package/rcf/code-nodes/cn-205.json +14 -0
- package/rcf/fbs/fbs-043.json +23 -0
- package/rcf/fbs/fbs-044.json +23 -0
- package/rcf/fbs/fbs-045.json +23 -0
- package/rcf/fbs/fbs-046.json +24 -0
- package/rcf/fbs/fbs-047.json +24 -0
- package/rcf/fbs/fbs-060.json +22 -0
- package/rcf/fbs/fbs-061.json +20 -0
- package/rcf/requirements/req-024.json +69 -0
- package/rcf/requirements/req-025.json +59 -0
- package/rcf/requirements/req-026.json +154 -0
- package/rcf/requirements/req-027.json +33 -0
- package/rcf/requirements/req-028.json +13 -0
- package/rcf/requirements/req-040.json +13 -0
- package/rcf/requirements/req-041.json +125 -0
- package/rcf/test-suites/ts-053.json +70 -0
- package/rcf/test-suites/ts-054.json +70 -0
- package/rcf/test-suites/ts-055.json +77 -0
- package/rcf/test-suites/ts-056.json +78 -0
- package/rcf/test-suites/ts-057.json +78 -0
- package/rcf/test-suites/ts-070.json +62 -0
- package/rcf/test-suites/ts-071.json +62 -0
- package/rcf/user-stories/us-2401.json +62 -0
- package/rcf/user-stories/us-2501.json +58 -0
- package/rcf/user-stories/us-2601.json +51 -0
- package/rcf/user-stories/us-2701.json +55 -0
- package/rcf/user-stories/us-2801.json +55 -0
- package/rcf/user-stories/us-4001.json +69 -0
- package/rcf/user-stories/us-4101.json +69 -0
- package/releases/releases.yaml +11 -1
- package/src/blueprint/apply.js +10 -1
- package/src/blueprint/capabilities.js +41 -2
- package/src/cli/blueprint.js +8 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
// application-file-upload probe pack (v1.0.0).
|
|
2
|
+
//
|
|
3
|
+
// Four surface-observable checks, one per contract, anchored to the
|
|
4
|
+
// blueprint's contributed AC ids:
|
|
5
|
+
// AC-23101-1 input surface (file input, drop-zone, keyboard-opener)
|
|
6
|
+
// AC-23102-1 progress announcer (polite tick format + monotonic advance)
|
|
7
|
+
// AC-23103-1 refusal contract (aria-describedby, no bytes for refused)
|
|
8
|
+
// AC-23104-1 chunked transport (multipart chunks OR tus Upload-Offset)
|
|
9
|
+
//
|
|
10
|
+
// Every check drives the real Playwright browser the T-0 runner
|
|
11
|
+
// injects. URLs are composed by the withUrl(runtimeUrl, path) helper
|
|
12
|
+
// per the round 3 T-3 fix train; no bare string concatenation.
|
|
13
|
+
//
|
|
14
|
+
// Sample-app fixture:
|
|
15
|
+
// packages/rcf-lite/test/fixtures/probe-pack-application-file-upload/
|
|
16
|
+
// Fixture ships /upload with a ?transport=multipart default and a
|
|
17
|
+
// ?transport=tus alternative plus break switches (?break=no-input,
|
|
18
|
+
// ?break=no-live-region, ?break=send-refused, ?break=no-chunks) so
|
|
19
|
+
// the negative runs can be driven from a single boot.
|
|
20
|
+
|
|
21
|
+
function withUrl(runtimeUrl, path) {
|
|
22
|
+
return new URL(path, runtimeUrl).toString();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Progress tick format the announcer TAC pins per ADR-2402:
|
|
26
|
+
// "<uploaded> of <total> files, <PP> percent"
|
|
27
|
+
const POLITE_FORMAT = /^\d+ of \d+ files, \d{1,3} percent$/;
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
packName: 'application-file-upload',
|
|
31
|
+
version: '1.0.0',
|
|
32
|
+
blueprintSlug: 'application-file-upload',
|
|
33
|
+
// Applies to any FBS that binds the input TAC or whose navModel
|
|
34
|
+
// routes name the operator-configured upload path. References BOTH
|
|
35
|
+
// `tacIds` AND `route` per the loader source-scan rule (T-0
|
|
36
|
+
// AC-1701-3, cross-check with authoring standard 8c).
|
|
37
|
+
appliesTo: ({ fbs }) => {
|
|
38
|
+
const routes = fbs?.designStage?.navModel?.routes ?? [];
|
|
39
|
+
const tacIds = fbs?.contextRequirements?.tacIds ?? [];
|
|
40
|
+
if (tacIds.includes('TAC-2401-application-file-upload-input')) return true;
|
|
41
|
+
return routes.some((r) => typeof r?.path === 'string' && /\/upload(\/|$|\?)/.test(r.path));
|
|
42
|
+
},
|
|
43
|
+
boot: { bootCommand: null, waitForUrl: null, waitForSelector: null },
|
|
44
|
+
checks: [
|
|
45
|
+
{
|
|
46
|
+
id: 'AC-23101-1',
|
|
47
|
+
severity: 'block',
|
|
48
|
+
description: 'input surface renders a labelled file input, a drop-zone region and a keyboard-focusable opener that opens the picker on Enter (WCAG 2.5.7)',
|
|
49
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
50
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
51
|
+
await browser.goto(withUrl(runtimeUrl, '/upload'));
|
|
52
|
+
const dom = await browser.evaluate(() => {
|
|
53
|
+
const region = document.querySelector('[data-surface="file-upload"]');
|
|
54
|
+
if (!region) return { present: false };
|
|
55
|
+
const fileInput = region.querySelector('input[type="file"]');
|
|
56
|
+
const dropZone = region.querySelector('[data-drop-zone]');
|
|
57
|
+
const opener = region.querySelector('[data-open-picker]');
|
|
58
|
+
const inputId = fileInput ? fileInput.id : null;
|
|
59
|
+
const label = inputId ? document.querySelector(`label[for="${inputId}"]`) : null;
|
|
60
|
+
const ariaLabel = fileInput ? fileInput.getAttribute('aria-label') : null;
|
|
61
|
+
const openerFocusable = opener ? opener.tabIndex >= 0 || opener.tagName === 'BUTTON' : false;
|
|
62
|
+
return {
|
|
63
|
+
present: true,
|
|
64
|
+
hasFileInput: !!fileInput,
|
|
65
|
+
hasDropZone: !!dropZone,
|
|
66
|
+
hasOpener: !!opener,
|
|
67
|
+
openerFocusable,
|
|
68
|
+
hasLabel: !!label,
|
|
69
|
+
hasAriaLabel: !!ariaLabel,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
if (!dom.present) return { verdict: 'fail', detail: 'upload region [data-surface="file-upload"] not found' };
|
|
73
|
+
if (!dom.hasFileInput) return { verdict: 'fail', detail: 'upload region missing input[type="file"]' };
|
|
74
|
+
if (!dom.hasDropZone) return { verdict: 'fail', detail: 'upload region missing [data-drop-zone]' };
|
|
75
|
+
if (!dom.hasOpener) return { verdict: 'fail', detail: 'upload region missing keyboard [data-open-picker] control (WCAG 2.5.7: drop-zone must not be the only path)' };
|
|
76
|
+
if (!dom.openerFocusable) return { verdict: 'fail', detail: '[data-open-picker] control not keyboard-focusable' };
|
|
77
|
+
if (!dom.hasLabel && !dom.hasAriaLabel) return { verdict: 'fail', detail: 'file input carries neither an associated <label> nor aria-label' };
|
|
78
|
+
return { verdict: 'pass', detail: 'file input, drop-zone and keyboard opener present; accessible name bound' };
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'AC-23102-1',
|
|
83
|
+
severity: 'block',
|
|
84
|
+
description: 'progress announcer emits a polite tick in the closed format and the aggregate percent advances monotonically during an upload',
|
|
85
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
86
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
87
|
+
await browser.goto(withUrl(runtimeUrl, '/upload?transport=multipart&autostart=1&seed=demo'));
|
|
88
|
+
// Read the polite wrapper twice with the fixture's polling
|
|
89
|
+
// interval between so we can prove monotonic advance.
|
|
90
|
+
const firstRead = await browser.evaluate(() => {
|
|
91
|
+
const live = document.querySelector('[data-live-region="polite"]');
|
|
92
|
+
const row = document.querySelector('[data-file-row] [data-file-progress]');
|
|
93
|
+
return {
|
|
94
|
+
text: live ? live.textContent.trim() : null,
|
|
95
|
+
ariaLive: live ? live.getAttribute('aria-live') : null,
|
|
96
|
+
rowPercent: row ? Number(row.getAttribute('aria-valuenow') ?? row.textContent.trim()) : null,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
// Fixture ticks every ~150ms; poll for advance.
|
|
100
|
+
const secondRead = await browser.evaluate(async () => {
|
|
101
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
102
|
+
const live = document.querySelector('[data-live-region="polite"]');
|
|
103
|
+
const row = document.querySelector('[data-file-row] [data-file-progress]');
|
|
104
|
+
return {
|
|
105
|
+
text: live ? live.textContent.trim() : null,
|
|
106
|
+
rowPercent: row ? Number(row.getAttribute('aria-valuenow') ?? row.textContent.trim()) : null,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
if (!firstRead.text) return { verdict: 'fail', detail: '[data-live-region="polite"] wrapper missing' };
|
|
110
|
+
if (firstRead.ariaLive !== 'polite') return { verdict: 'fail', detail: `[data-live-region="polite"] wrapper aria-live expected "polite", got ${JSON.stringify(firstRead.ariaLive)}` };
|
|
111
|
+
if (!POLITE_FORMAT.test(firstRead.text)) {
|
|
112
|
+
return { verdict: 'fail', detail: `polite tick text did not match /^\\d+ of \\d+ files, \\d{1,3} percent$/: ${JSON.stringify(firstRead.text)}` };
|
|
113
|
+
}
|
|
114
|
+
if (firstRead.rowPercent == null || Number.isNaN(firstRead.rowPercent)) {
|
|
115
|
+
return { verdict: 'fail', detail: 'per-file [data-file-progress] not present or not numeric' };
|
|
116
|
+
}
|
|
117
|
+
if (secondRead.rowPercent == null || secondRead.rowPercent < firstRead.rowPercent) {
|
|
118
|
+
return { verdict: 'fail', detail: `aggregate progress did not advance monotonically: first=${firstRead.rowPercent}, second=${secondRead.rowPercent}` };
|
|
119
|
+
}
|
|
120
|
+
return { verdict: 'pass', detail: `firstTick=${JSON.stringify(firstRead.text)} firstRow=${firstRead.rowPercent} secondRow=${secondRead.rowPercent}` };
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'AC-23103-1',
|
|
125
|
+
severity: 'block',
|
|
126
|
+
description: 'a refused file renders an aria-describedby-bound error, moves focus to the retry control, and is never sent to the server',
|
|
127
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
128
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
129
|
+
await browser.goto(withUrl(runtimeUrl, '/upload?transport=multipart&seed=refused'));
|
|
130
|
+
const dom = await browser.evaluate(async () => {
|
|
131
|
+
// Wait for the upload loop to run to completion (or for
|
|
132
|
+
// the deadline). We can't read the request log honestly
|
|
133
|
+
// before the loop has had a chance to run: on the
|
|
134
|
+
// ?break=send-refused negative branch the refused row's
|
|
135
|
+
// bytes only land after the loop reaches that row. The
|
|
136
|
+
// fixture completes a two-file demo set in roughly
|
|
137
|
+
// 2 * 3 * 120ms + jitter = ~800ms.
|
|
138
|
+
const deadline = Date.now() + 3000;
|
|
139
|
+
while (Date.now() < deadline) {
|
|
140
|
+
const slot = document.querySelector('[data-assertive-slot]');
|
|
141
|
+
if (slot && slot.textContent && slot.textContent.trim().length > 0) break;
|
|
142
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
143
|
+
}
|
|
144
|
+
const region = document.querySelector('[data-surface="file-upload"]');
|
|
145
|
+
if (!region) return { present: false };
|
|
146
|
+
const row = region.querySelector('[data-file-row][data-refused="true"]');
|
|
147
|
+
if (!row) return { present: true, hasRefusedRow: false };
|
|
148
|
+
const describedBy = row.getAttribute('aria-describedby');
|
|
149
|
+
const errId = describedBy ? describedBy.split(/\s+/)[0] : null;
|
|
150
|
+
const err = errId ? row.querySelector(`#${CSS.escape(errId)}`) || document.getElementById(errId) : null;
|
|
151
|
+
const reason = row.getAttribute('data-refusal-reason');
|
|
152
|
+
const retry = row.querySelector('[data-recovery="retry"]');
|
|
153
|
+
const network = Array.isArray(window.__uploadRequestLog) ? window.__uploadRequestLog : [];
|
|
154
|
+
const refusedFilename = row.getAttribute('data-refused-filename') || null;
|
|
155
|
+
const sentRefused = refusedFilename
|
|
156
|
+
? network.some((r) => r && typeof r.body === 'string' && r.body.includes(refusedFilename))
|
|
157
|
+
: false;
|
|
158
|
+
return {
|
|
159
|
+
present: true,
|
|
160
|
+
hasRefusedRow: true,
|
|
161
|
+
hasErr: !!err,
|
|
162
|
+
errText: err ? err.textContent.trim() : null,
|
|
163
|
+
reason,
|
|
164
|
+
hasRetry: !!retry,
|
|
165
|
+
refusedFilename,
|
|
166
|
+
sentRefused,
|
|
167
|
+
network,
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
if (!dom.present) return { verdict: 'fail', detail: 'upload region not found' };
|
|
171
|
+
if (!dom.hasRefusedRow) return { verdict: 'fail', detail: 'no [data-file-row][data-refused="true"] on the refused seed' };
|
|
172
|
+
if (!dom.hasErr) return { verdict: 'fail', detail: 'refused row aria-describedby does not resolve to a [data-error-message] element' };
|
|
173
|
+
const allowedReasons = ['mime-refused', 'size-refused', 'virus-refused'];
|
|
174
|
+
if (!allowedReasons.includes(dom.reason)) {
|
|
175
|
+
return { verdict: 'fail', detail: `refused row [data-refusal-reason] expected one of ${JSON.stringify(allowedReasons)}, got ${JSON.stringify(dom.reason)}` };
|
|
176
|
+
}
|
|
177
|
+
if (!dom.hasRetry) return { verdict: 'fail', detail: 'refused row missing [data-recovery="retry"] control' };
|
|
178
|
+
if (dom.sentRefused) {
|
|
179
|
+
return { verdict: 'fail', detail: `refused filename ${JSON.stringify(dom.refusedFilename)} appears in the upload request log` };
|
|
180
|
+
}
|
|
181
|
+
return { verdict: 'pass', detail: `reason=${JSON.stringify(dom.reason)} err=${JSON.stringify(dom.errText)} no refused bytes on the wire (${dom.network.length} recorded upload requests)` };
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'AC-23104-1',
|
|
186
|
+
severity: 'block',
|
|
187
|
+
description: 'the transport uploads in chunks; on the tus branch each PATCH request carries Upload-Offset, on the multipart branch [data-chunks-uploaded] on the DOM exceeds one',
|
|
188
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
189
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
190
|
+
// Read the transport preference off the base runtimeUrl's own
|
|
191
|
+
// query string (the withUrl helper resolves a fresh path
|
|
192
|
+
// against the base, which drops the query). The pack anchors
|
|
193
|
+
// on the base URL's ?transport= so a caller running the tus
|
|
194
|
+
// branch passes --url http://.../upload?transport=tus and the
|
|
195
|
+
// pack observes it here.
|
|
196
|
+
let configuredTransport = null;
|
|
197
|
+
try { configuredTransport = new URL(runtimeUrl).searchParams.get('transport'); } catch { /* runtimeUrl may be a bare path in tests */ }
|
|
198
|
+
const transport = configuredTransport === 'tus' ? 'tus' : 'multipart';
|
|
199
|
+
await browser.goto(withUrl(runtimeUrl, `/upload?transport=${transport}&seed=large&autostart=1`));
|
|
200
|
+
const dom = await browser.evaluate(async () => {
|
|
201
|
+
// Wait for the upload to complete (or for the deadline).
|
|
202
|
+
// The pack needs to observe the final chunk count, not the
|
|
203
|
+
// first: an early break at chunks > 0 would read 1 and
|
|
204
|
+
// spuriously fail the chunked-upload assertion on a fast
|
|
205
|
+
// fixture. The fixture completes a 5-chunk upload in
|
|
206
|
+
// roughly 5 * 120ms = 600ms.
|
|
207
|
+
const deadline = Date.now() + 3000;
|
|
208
|
+
while (Date.now() < deadline) {
|
|
209
|
+
const row = document.querySelector('[data-file-row]');
|
|
210
|
+
const state = row ? row.getAttribute('data-file-state') : null;
|
|
211
|
+
if (state === 'complete') break;
|
|
212
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
213
|
+
}
|
|
214
|
+
const row = document.querySelector('[data-file-row]');
|
|
215
|
+
const region = document.querySelector('[data-surface="file-upload"]');
|
|
216
|
+
const transportAttr = region ? region.getAttribute('data-transport') : null;
|
|
217
|
+
const chunksUploaded = row ? Number(row.getAttribute('data-chunks-uploaded') ?? '0') : 0;
|
|
218
|
+
const patchOffsets = Array.isArray(window.__tusPatchOffsets) ? window.__tusPatchOffsets : [];
|
|
219
|
+
return { transportAttr, chunksUploaded, patchOffsets };
|
|
220
|
+
});
|
|
221
|
+
if (dom.transportAttr !== transport) {
|
|
222
|
+
return { verdict: 'fail', detail: `upload region [data-transport] expected ${JSON.stringify(transport)}, got ${JSON.stringify(dom.transportAttr)}` };
|
|
223
|
+
}
|
|
224
|
+
if (dom.chunksUploaded < 2) {
|
|
225
|
+
return { verdict: 'fail', detail: `[data-chunks-uploaded] expected > 1 (chunked upload), got ${dom.chunksUploaded}` };
|
|
226
|
+
}
|
|
227
|
+
if (transport === 'tus') {
|
|
228
|
+
const numeric = dom.patchOffsets.filter((v) => typeof v === 'number' && Number.isFinite(v));
|
|
229
|
+
if (numeric.length === 0) {
|
|
230
|
+
return { verdict: 'fail', detail: `no PATCH request recorded with a numeric Upload-Offset header (window.__tusPatchOffsets=${JSON.stringify(dom.patchOffsets)})` };
|
|
231
|
+
}
|
|
232
|
+
return { verdict: 'pass', detail: `tus branch: chunks=${dom.chunksUploaded}, Upload-Offset headers=${JSON.stringify(numeric)}` };
|
|
233
|
+
}
|
|
234
|
+
return { verdict: 'pass', detail: `multipart branch: chunks=${dom.chunksUploaded}` };
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# application-forms-wizard CHANGELOG
|
|
2
|
+
|
|
3
|
+
## 1.0.0 (visual round T-3, spec 2026-09-06)
|
|
4
|
+
|
|
5
|
+
- First ratified version of the shelf's forms-wizard blueprint. Five REQs (task-list contract with the closed GOV.UK vocabulary Cannot start yet, Not started, In progress, Completed and an ARIA progressbar wrapper; per-step validation timing with on-blur before first submit then on-change after first failure and a full pass on submit reusing SPA forms-engine TAC-205; error-summary contract with a top-of-page summary, skip links, aria-invalid on the field, aria-describedby to the field-level message and focus moved to the summary heading; summary-review contract with a summary-list per step, Change links per row and answer retention on save; save-and-return contract with a server-side draft table or a client-side local buffer with a sync tick, refuses to ship if neither is wired), eight USs 24101 to 24108 binding one runtime-observable AC per contract plus three cross-cutting cases (linear-vs-free navigation, in-progress list, no-in-progress empty state delegated to application-empty-error-states), three TACs 2501 to 2503 (task-list shell, error-summary contract, draft store), three ADRs 2501 to 2503 (navigation posture linear default with elicited free branch, save-and-return transport with no recommendedDefault so the abandoned-draft loss class does not ship silently, step-indicator shape with task-list default and elicited ARIA progressbar-only or breadcrumb). No new global topics.
|
|
6
|
+
- Ships `probe-packs/application-forms-wizard.pack.mjs`: four surface-observable browser-verify checks anchored one per core contract (`AC-24101-1` task-list, `AC-24103-1` error-summary, `AC-24104-1` summary-review, `AC-24105-1` save-and-return). Every URL is composed by the `withUrl(runtimeUrl, path)` helper per the round 3 T-3 fix train; no bare string concatenation. The pack-level `appliesTo` predicate references BOTH `tacIds` (TAC-2501) AND `route` (the operator-configured wizard-route glob).
|
|
7
|
+
- Ships a dependency-free sample-app fixture at `packages/rcf-lite/test/fixtures/probe-pack-application-forms-wizard/` with a Node HTTP server realising the four wizard surfaces honestly (`/task-list`, `/step/<n>`, `/summary`, `/in-progress`), both save-and-return transports on their query branches (`?draft-store=server` default posting to `/drafts`, `?draft-store=local` writing to `localStorage` with a sync tick), and four break switches (`?break=task-list-vocab`, `?break=no-summary`, `?break=no-retain`, `?break=no-draft`) driving the negative runs from a single boot. The fixture ships its own README naming PORT, every `?step=`, `?draft-store=`, `?nav=`, `?seed=`, `?refused=`, `?preseed=`, `?edit=`, every `?break=`, the manual boot line and the two-line gate-reviewer boot.
|
|
8
|
+
- Declares `suggestedCompanions` `logging` (every step transition, validation failure and save-and-return event writes one request-scoped log line with the correlation identifier and the step slug) and `errorHandling` (the error-summary contract constructs an internal error record per failed field through the applied error-handling factory). Does NOT declare `providesRoles` (leaf blueprint per spec). Does NOT declare `capabilities` and does NOT declare `requiresAppliedCapabilities` (no auth required).
|
|
9
|
+
- Consumes `application-empty-error-states` for the no-in-progress empty state on the /in-progress list surface; the wizard's TAC-2503 delegates the zero-drafts case to the sibling's empty-list state and reads `[data-surface="empty-list"]` with a `[data-recovery="create"]` control from the sibling. T-4 `application-account-settings` will consume this blueprint for its multi-part account setup flow and the summary-review confirm-before-save gate.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Forms wizard blueprint (v1.0.0)
|
|
2
|
+
|
|
3
|
+
Vendor-neutral multi-step forms wizard contract for an rcf-lite application. Ships the GOV.UK Design System task-list pattern with a per-step completion state from the closed vocabulary (Cannot start yet, Not started, In progress, Completed), an ARIA progressbar wrapper on the task-list surface, the per-step validation timing rule (on-blur before first submit, on-change after first failure, full pass on submit), the top-of-page error-summary contract with skip links plus aria-invalid plus focus-to-heading on submit failure, the summary-review pattern with change-per-row and answer retention across an edit-and-save round-trip, and the save-and-return contract with a server-side draft table or a client-side local buffer with a sync tick. Ships a Playwright probe pack under `probe-packs/application-forms-wizard.pack.mjs` whose four checks each anchor one core contract, refuse on the corresponding break switch, and fire against the sample-app fixture on the shelf gate.
|
|
4
|
+
|
|
5
|
+
## Apply
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
rcf define blueprint add <path-to>/blueprints/application-forms-wizard
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Applies 19 contributions (5 REQs, 8 USs, 3 TACs, 3 ADRs) cleanly on any fresh init project. No `requiresAppliedCapabilities`, no auth prerequisite. The three elicits (ADR-2501 navigation posture with recommendedDefault linear, ADR-2502 save-and-return transport with no recommendedDefault, ADR-2503 step-indicator shape with recommendedDefault task-list) either ship recommended defaults so the apply proceeds silently, or (ADR-2502 alone) require a project answer at apply time because the abandoned-draft loss class is genuinely per-project.
|
|
12
|
+
|
|
13
|
+
## Anatomy
|
|
14
|
+
|
|
15
|
+
| Piece | Where | What |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Metadata | `blueprint.json` | Slug, version 1.0.0, category `application`, `suggestedCompanions: [logging, errorHandling]`, 19 contributions in the 24xxx / 25xx band |
|
|
18
|
+
| Doc set | `contributions/` | 5 REQs, 8 USs (each carrying one runtime-observable AC), 3 TACs, 3 ADRs |
|
|
19
|
+
| Probe pack | `probe-packs/application-forms-wizard.pack.mjs` | Four surface-observable browser-verify checks, one per core contract |
|
|
20
|
+
| Guide | `guide/application-forms-wizard.md` | Operator-facing: when to reach, when not, mechanism-reach gaps |
|
|
21
|
+
| Coordination vocabulary | `docs/topics.md` | Shelf id band registry update; no new global topics claimed; cross-reference to `application-empty-error-states` for the no-in-progress empty case |
|
|
22
|
+
| Sample-app fixture | `packages/rcf-lite/test/fixtures/probe-pack-application-forms-wizard/` | Dependency-free Node HTTP server the pack is probed against on the shelf gate |
|
|
23
|
+
|
|
24
|
+
## The task-list vocabulary
|
|
25
|
+
|
|
26
|
+
The four state strings are a closed enum at v1.0.0. Every task-list row exposes one. A fifth state (Skipped, Locked, or another word) is a v1.1.0 minor bump. Every README, guide, pack `checks[]` and `docs/topics.md` row names the same four strings.
|
|
27
|
+
|
|
28
|
+
| State | Meaning |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `Cannot start yet` | A prerequisite step is unfinished. On linear navigation the row renders as a non-anchor span. |
|
|
31
|
+
| `Not started` | The step is reachable and has no answers. |
|
|
32
|
+
| `In progress` | The step has partial answers. |
|
|
33
|
+
| `Completed` | The step is fully valid. |
|
|
34
|
+
|
|
35
|
+
## The validation timing rule
|
|
36
|
+
|
|
37
|
+
REQ-002 commits to the three-mode timing rule from the GOV.UK Design System error-message pattern. The rule delegates every validation to the SPA blueprint's forms-engine TAC-205 so a project applying `application-spa` does not compose two overlapping engines; a project without `application-spa` supplies an engine of its own choice against TAC-2502's interfaces.
|
|
38
|
+
|
|
39
|
+
- On blur before the first submit on a step, each field validates on leaving focus.
|
|
40
|
+
- After the first submit failure on a field, subsequent input events on that field update the message on every change (so the operator sees the message clear as they correct it).
|
|
41
|
+
- On the next submit the engine rebuilds the error set from scratch.
|
|
42
|
+
|
|
43
|
+
## The error-summary contract
|
|
44
|
+
|
|
45
|
+
On submit refusal the step renders `[data-surface="error-summary"]` at the top of the page with a heading and one skip link per failed field; the skip link's `href` targets the field id. Every failed field carries `aria-invalid="true"` and `aria-describedby` pointing at its per-field error message. On failure focus moves to the summary heading. Per WCAG 2.2 SC 3.3.1 Error Identification and SC 3.3.3 Error Suggestion.
|
|
46
|
+
|
|
47
|
+
## The summary-review pattern
|
|
48
|
+
|
|
49
|
+
After every step is Completed the wizard renders `[data-surface="summary-review"]` with one `[data-summary-list-section]` per step. Each section carries a `<dl>` summary list; each row is a `[data-summary-row]` with a `<dt>` label, a `<dd>` value and a `[data-recovery="change"]` link back to the step. Editing on the target step and saving returns to the summary review with every other answer preserved verbatim. Per GOV.UK Design System summary-list pattern; per WCAG 2.2 SC 3.3.4 Error Prevention.
|
|
50
|
+
|
|
51
|
+
## The save-and-return contract
|
|
52
|
+
|
|
53
|
+
ADR-2502 commits to two transports without recommendedDefault. The server-side draft table (`POST /drafts` on advance, `GET /drafts` on entry) keys drafts by operator identifier; the client-side local buffer writes into `window.localStorage` under `draft:<wizard-slug>:<step-slug>` and renders `[data-sync-tick]` carrying an ISO-8601 timestamp on every write. A wizard applied without either transport is refused at build gate; ADR-2502 is a required elicit. Per WCAG 2.2 SC 3.3.7 Redundant Entry.
|
|
54
|
+
|
|
55
|
+
## The no-in-progress empty case
|
|
56
|
+
|
|
57
|
+
The in-progress-list surface delegates the zero-drafts case to the `application-empty-error-states` empty-list state (`[data-surface="empty-list"]` with a `[data-recovery="create"]` control). The wizard blueprint does not ship its own empty component; a project applying both blueprints reads the same surface from either lane.
|
|
58
|
+
|
|
59
|
+
## Elicited parameters
|
|
60
|
+
|
|
61
|
+
- **Step manifest.** The ordered list of steps, one entry per step with a slug, a title and a prerequisites array. Required at apply time; the shipped example manifest is three steps.
|
|
62
|
+
- **Save-and-return transport.** Default: none; ADR-2502 elicits `server-draft-table` or `client-local-buffer`. Required at apply time.
|
|
63
|
+
- **Which steps are optional.** A per-step flag defaulting to `required: true`. Optional steps do not gate the summary review.
|
|
64
|
+
- **Linear or free step navigation.** Default: linear. ADR-2501 elicits `free`.
|
|
65
|
+
- **Step indicator shape.** Default: task-list. ADR-2503 elicits `aria-progressbar-only` or `breadcrumb`.
|
|
66
|
+
|
|
67
|
+
## The one runtime gate
|
|
68
|
+
|
|
69
|
+
`probe-packs/application-forms-wizard.pack.mjs` ships four checks the `rcf verify browser` runner invokes on any FBS whose surface binds `TAC-2501-application-forms-wizard-task-list` or whose nav model routes name an operator-configured wizard path. Each check drives the real Playwright browser the runner provisions, reads the DOM and the accessibility tree, and returns a verdict. URLs are composed by the `withUrl(runtimeUrl, path)` helper per the round 3 T-3 fix train; no bare string concatenation.
|
|
70
|
+
|
|
71
|
+
## Quality bar
|
|
72
|
+
|
|
73
|
+
WCAG 2.2 AA across every surface: 2.4.6 Headings and Labels (task-list state per row, summary heading on submit failure), 3.3.1 Error Identification (error-summary names every failed field), 3.3.3 Error Suggestion (per-field message names the correction, not just the fault), 3.3.4 Error Prevention (summary-review is reversible before submit), 3.3.7 Redundant Entry (drafts persist across sessions). GOV.UK Design System task-list pattern, summary-list pattern, complete-multiple-tasks pattern. `standardsTrace` on the blueprint is empty (this is a general-enterprise-practice blueprint); each ADR contribution carries `standardsTraceClause` naming the pattern or SC identifier it implements.
|
|
74
|
+
|
|
75
|
+
## Known mechanism-reach gaps
|
|
76
|
+
|
|
77
|
+
Runtime-observable ACs the pack does NOT bind directly (checklist section 6.g), listed individually per AC id:
|
|
78
|
+
|
|
79
|
+
- **AC-24102-1 validation timing.** The pack asserts the field-level message element and the aria-describedby binding via the fixture's refused branch; it does NOT additionally drive a real focus-and-blur sequence through the browser transport nor probe the transition from on-blur-only to on-change-after-failure. A v1.1.0 minor bump can drive keyboard events and diff the message text across events.
|
|
80
|
+
- **AC-24101-1 focus-move-to-task-list.** The pack asserts the task-list rows and the progressbar values; it does NOT additionally probe that focus lands on the task-list on route entry. A v1.1.0 minor bump can drive the accessibility tree and diff.
|
|
81
|
+
- **AC-24103-1 tab-order sweep.** The pack asserts focus lands on the summary heading; it does NOT additionally probe the full tab order across the failed fields. A v1.1.0 minor bump can walk the tab order.
|
|
82
|
+
- **AC-24106-1 linear-vs-free anchor rendering.** The pack does not have a dedicated check; the fixture's `?nav=free` and `?nav=linear` branches render honestly and consumers can probe the shape by inspection. A v1.1.0 minor bump can add a fifth check anchoring AC-24106-1 directly.
|
|
83
|
+
- **AC-24107-1 in-progress list enumeration.** The pack does not have a dedicated check; the `/in-progress` surface is inspected by the anatomy tests. A v1.1.0 minor bump can add a fifth check anchoring AC-24107-1 directly.
|
|
84
|
+
- **AC-24108-1 empty-state delegation.** The pack does not re-probe the empty-list wrapper here; the sibling `application-empty-error-states` pack already asserts it. Consumers apply both blueprints and the empty case is covered by the sibling pack. A v1.1.0 minor bump can add a cross-check that reads the empty wrapper on the `/in-progress` route.
|
|
85
|
+
- **AC-24105-1 cross-tab hydration.** The pack asserts the localStorage write and the sync tick on the local branch; it does NOT additionally probe cross-tab hydration or server-side dedupe on the server branch. Both are v1.1.0 minor-bump candidates.
|
|
86
|
+
- **AC-24104-1 keyboard-focus-on-change-link.** The pack asserts the change link and the answer retention; it does NOT additionally probe that following the change link places keyboard focus on the target field. A v1.1.0 minor bump can drive the click and read the active element on the target step.
|
|
87
|
+
|
|
88
|
+
## Companions
|
|
89
|
+
|
|
90
|
+
`suggestedCompanions` declares `logging` (every step transition, validation failure and save-and-return event writes one request-scoped log line with the correlation identifier and the step slug through the applied logger factory) and `errorHandling` (the error-summary contract constructs an internal error record per failed field through the applied error-handling factory). Neither is required to apply the blueprint; a project without a logging companion still renders every state, it just does not emit a per-step log line.
|
|
91
|
+
|
|
92
|
+
## Consumers
|
|
93
|
+
|
|
94
|
+
- `application-account-settings` (T-4 of this round) consumes the wizard task-list pattern for its multi-part account setup flow and the summary-review pattern for its confirm-before-save gate.
|
|
95
|
+
|
|
96
|
+
## Composition with application-spa
|
|
97
|
+
|
|
98
|
+
`application-spa` REQ-006 ships the forms-engine (TAC-205) that this blueprint's TAC-2502 delegates validation to. This blueprint composes with SPA; the topic-ownership boundary lives in `docs/topics.md`. SPA holds the forms-engine and the field-component library; this sibling holds the wizard shell, the task-list, the error-summary contract, the summary review and the save-and-return draft store.
|
|
99
|
+
|
|
100
|
+
## Composition with application-empty-error-states
|
|
101
|
+
|
|
102
|
+
The in-progress list's zero-drafts case delegates to the sibling's empty-list surface. This blueprint's TAC-2503 does not ship an empty component; the consumer applies both blueprints and the empty case reads consistently across the application. The topic-ownership boundary line lives in `docs/topics.md`, cross-referenced from the sibling's `docs/topics.md`.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "application-forms-wizard",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "application",
|
|
5
|
+
"suggestedCompanions": [
|
|
6
|
+
{
|
|
7
|
+
"role": "logging",
|
|
8
|
+
"reason": "Every step transition, validation failure and save-and-return event writes one request-scoped log line with the correlation identifier and the step slug through the applied logger factory."
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"role": "errorHandling",
|
|
12
|
+
"reason": "The error-summary contract constructs an internal error record per failed field through the applied error-handling factory so the aria-describedby binding renders a consistent message shape across steps."
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"contributions": [
|
|
16
|
+
{
|
|
17
|
+
"id": "application-forms-wizard-REQ-001",
|
|
18
|
+
"kind": "req",
|
|
19
|
+
"path": "requirements/application-forms-wizard-req-001.json"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "application-forms-wizard-REQ-002",
|
|
23
|
+
"kind": "req",
|
|
24
|
+
"path": "requirements/application-forms-wizard-req-002.json"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "application-forms-wizard-REQ-003",
|
|
28
|
+
"kind": "req",
|
|
29
|
+
"path": "requirements/application-forms-wizard-req-003.json"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "application-forms-wizard-REQ-004",
|
|
33
|
+
"kind": "req",
|
|
34
|
+
"path": "requirements/application-forms-wizard-req-004.json"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "application-forms-wizard-REQ-005",
|
|
38
|
+
"kind": "req",
|
|
39
|
+
"path": "requirements/application-forms-wizard-req-005.json"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "application-forms-wizard-US-24101",
|
|
43
|
+
"kind": "us",
|
|
44
|
+
"path": "user-stories/application-forms-wizard-us-24101.json"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "application-forms-wizard-US-24102",
|
|
48
|
+
"kind": "us",
|
|
49
|
+
"path": "user-stories/application-forms-wizard-us-24102.json"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "application-forms-wizard-US-24103",
|
|
53
|
+
"kind": "us",
|
|
54
|
+
"path": "user-stories/application-forms-wizard-us-24103.json"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "application-forms-wizard-US-24104",
|
|
58
|
+
"kind": "us",
|
|
59
|
+
"path": "user-stories/application-forms-wizard-us-24104.json"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "application-forms-wizard-US-24105",
|
|
63
|
+
"kind": "us",
|
|
64
|
+
"path": "user-stories/application-forms-wizard-us-24105.json"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "application-forms-wizard-US-24106",
|
|
68
|
+
"kind": "us",
|
|
69
|
+
"path": "user-stories/application-forms-wizard-us-24106.json"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "application-forms-wizard-US-24107",
|
|
73
|
+
"kind": "us",
|
|
74
|
+
"path": "user-stories/application-forms-wizard-us-24107.json"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "application-forms-wizard-US-24108",
|
|
78
|
+
"kind": "us",
|
|
79
|
+
"path": "user-stories/application-forms-wizard-us-24108.json"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "TAC-2501-application-forms-wizard-task-list",
|
|
83
|
+
"kind": "tac",
|
|
84
|
+
"path": "tacs/tac-2501-application-forms-wizard-task-list.json"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "TAC-2502-application-forms-wizard-error-summary",
|
|
88
|
+
"kind": "tac",
|
|
89
|
+
"path": "tacs/tac-2502-application-forms-wizard-error-summary.json"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "TAC-2503-application-forms-wizard-draft-store",
|
|
93
|
+
"kind": "tac",
|
|
94
|
+
"path": "tacs/tac-2503-application-forms-wizard-draft-store.json"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "ADR-2501-application-forms-wizard-navigation",
|
|
98
|
+
"kind": "adr",
|
|
99
|
+
"path": "adrs/adr-2501-application-forms-wizard-navigation.json",
|
|
100
|
+
"recommendedDefault": true,
|
|
101
|
+
"elicited": true,
|
|
102
|
+
"standardsTraceClause": "GOV.UK Design System step-by-step navigation pattern"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "ADR-2502-application-forms-wizard-save-and-return",
|
|
106
|
+
"kind": "adr",
|
|
107
|
+
"path": "adrs/adr-2502-application-forms-wizard-save-and-return.json",
|
|
108
|
+
"elicited": true,
|
|
109
|
+
"standardsTraceClause": "GOV.UK Design System save and return pattern; generic enterprise practice"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "ADR-2503-application-forms-wizard-step-indicator",
|
|
113
|
+
"kind": "adr",
|
|
114
|
+
"path": "adrs/adr-2503-application-forms-wizard-step-indicator.json",
|
|
115
|
+
"recommendedDefault": true,
|
|
116
|
+
"elicited": true,
|
|
117
|
+
"standardsTraceClause": "GOV.UK Design System task list pattern; WCAG 2.2 SC 2.4.6 Headings and Labels"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-2501-application-forms-wizard-navigation",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Step navigation posture is linear by default with free-step as the elicited alternative",
|
|
8
|
+
"context": "Wizards divide on how much freedom the operator has to jump between steps. A linear posture forbids advancing until the current step is Completed and disables backward jumps to steps whose prerequisites the domain says must be Completed first (an application with a payment step gated on shipping details, say). A free posture lets the operator pick any step at any time and computes the completion states independently. Neither is wrong; the choice is a per-project posture driven by the domain the wizard serves. GOV.UK Design System publishes the step-by-step navigation pattern as the widely-adopted linear model.",
|
|
9
|
+
"decision": "Adopt linear as the recommended default. The shipped task-list disables rows whose [data-step-state] is Cannot start yet by rendering them as spans without an href. Projects that want free navigation elicit ADR-2501 to the free branch and every row renders as an anchor. recommendedDefault is true because linear is the safer starting posture for a domain the shelf blueprint does not know; elicited is true because the switch is a real per-project answer.",
|
|
10
|
+
"consequences": "Projects on the default get a linear wizard out of the box with no configuration; the task-list refuses out-of-order entry and the operator walks the manifest in order. Projects electing free get an unconstrained task-list at the price of surfacing every prerequisite the domain implies through the manifest and the copy. All three step-indicator shapes (ADR-2503) render on both branches; the difference is only the click-through on rows whose prerequisites are unfinished.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Free-step as the shipped default",
|
|
14
|
+
"summary": "Ship free navigation everywhere and rely on per-step validation to catch out-of-order entries.",
|
|
15
|
+
"reasonNotChosen": "Loses the affordance the domain often needs (a payment step should not be reachable before shipping details); reads as more forgiving but pushes the domain rule into copy rather than into the surface."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Two-step wizard with no task-list",
|
|
19
|
+
"summary": "Ship no task-list at all and rely on Back and Next.",
|
|
20
|
+
"reasonNotChosen": "Loses the completion overview and the ARIA progressbar; a wizard with three or more steps benefits materially from the task-list surface."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
24
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-2502-application-forms-wizard-save-and-return",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Save-and-return transport ships as server-side draft table or client-side local buffer with no recommendedDefault",
|
|
8
|
+
"context": "The abandoned-draft loss class is genuinely per-project. An application whose operators sign in on shared kiosks with rotating identities cannot rely on a local buffer keyed to the browser; the draft must live on a server-side draft table keyed to the operator identifier so the operator can walk to a different device and continue. An application whose operators run on a single personal device with intermittent connectivity is better served by a local buffer that survives a network drop and syncs on the next flush. A shipped default in either direction quietly ships the wrong loss class for at least one common posture, so this blueprint declines to pick one.",
|
|
9
|
+
"decision": "Ship two transports: server-draft-table (POST /drafts and GET /drafts against operator-configured endpoints) and client-local-buffer (localStorage keyed by wizard slug and step slug with a per-write ISO-8601 sync tick). ADR-2502 records the elicit as required, elicited is true, and no recommendedDefault is committed: a project applying application-forms-wizard MUST answer the elicit and the build gate refuses when neither transport is wired. The GOV.UK Design System save and return pattern informs the server branch; the local branch is generic enterprise practice.",
|
|
10
|
+
"consequences": "Projects with a server-side draft table get audit-trail-clean per-operator persistence at the price of a server endpoint and a persistence adapter. Projects with a client-side local buffer get zero-server-work persistence at the price of losing drafts when the operator switches device. A project that has not decided cannot silently ship on the shelf default because there is none; the elicit is a real gate. The pack drives both transports on the sample fixture and refuses on the ?draft-store=none branch to prove the missing-transport case fails at severity block.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Server-only as the shipped default",
|
|
14
|
+
"summary": "Ship server-draft-table as the sole transport and refuse projects without a server endpoint.",
|
|
15
|
+
"reasonNotChosen": "Refuses to apply on a hobby SPA with no server; the shelf blueprint has to be reachable by every applied posture."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Local-only as the shipped default",
|
|
19
|
+
"summary": "Ship client-local-buffer as the sole transport and refuse projects with cross-device operators.",
|
|
20
|
+
"reasonNotChosen": "Ships the wrong loss class for kiosk-shape and multi-device operators; audit-trail-first projects cannot use it."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
24
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-2503-application-forms-wizard-step-indicator",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Step indicator shape defaults to task-list, with ARIA progressbar and breadcrumb as elicited alternatives",
|
|
8
|
+
"context": "Wizards indicate the operator's position through one of three widely-adopted shapes. A task-list (the GOV.UK Design System task list pattern) surfaces every step as a row with a completion state; the operator sees the whole shape at a glance and can jump to a specific step. An ARIA progressbar surfaces a single wrapper carrying aria-valuenow and aria-valuemax; the operator gets a compact completion count without a per-step enumeration. A breadcrumb surfaces the linear path with the current step highlighted; the operator sees the trail and can walk back but does not see the future steps' state. All three satisfy WCAG 2.2 SC 2.4.6 Headings and Labels; the choice is a per-project posture driven by the wizard's shape and the design system.",
|
|
9
|
+
"decision": "Adopt task-list as the recommended default; the shipped surface renders it with the ARIA progressbar wrapper on top per REQ-001 so every project gets the completion count for free. Projects that prefer a compact indicator elicit the aria-progressbar-only branch and the task-list rows collapse into the progressbar's aria-valuetext. Projects that prefer a trail elicit the breadcrumb branch and the task-list rows render as breadcrumb entries. recommendedDefault is true on task-list; elicited is true because the alternative is a real per-project answer.",
|
|
10
|
+
"consequences": "Projects on the default get the task-list plus the progressbar with no configuration; the pack anchors on the task-list surface and the progressbar wrapper. Projects electing aria-progressbar-only lose the per-step enumeration and the row jump; the pack skips AC-24106-1 (linear-vs-free row rendering has no rows). Projects electing breadcrumb keep the trail affordance and lose the future-state enumeration; the pack asserts the breadcrumb entries in place of the task-list rows.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "ARIA progressbar as the shipped default",
|
|
14
|
+
"summary": "Ship the compact progressbar and no task-list.",
|
|
15
|
+
"reasonNotChosen": "Loses the completion overview and the row-jump affordance; a wizard with three or more steps benefits materially from the task-list."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Breadcrumb as the shipped default",
|
|
19
|
+
"summary": "Ship the trail and no task-list.",
|
|
20
|
+
"reasonNotChosen": "Loses the future-step state enumeration; the operator cannot see at a glance what remains."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
24
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "application-forms-wizard-REQ-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Task-list contract: per-step completion state announced through the GOV.UK vocabulary Cannot start yet, Not started, In progress, Completed",
|
|
5
|
+
"description": "The wizard renders a task-list surface listing every step in a stable order. Each step exposes one of four completion states from the closed GOV.UK vocabulary: Cannot start yet (a prerequisite step is unfinished), Not started (the step is reachable but has no answers), In progress (the step has partial answers), Completed (the step is fully valid). The task-list carries an ARIA progressbar shape naming the total step count and the number completed. The four state strings are a closed enum at v1.0.0; a fifth state is a v1.1.0 minor bump. The surface anchors on TAC-2501 (task-list shell) and is vendor-neutral: the blueprint contributes WHAT strings under WHAT condition, not the visual token set.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "application",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Per visual round 4 spec section 5.3, REQ 1.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:application-forms-wizard",
|
|
12
|
+
"category:01-task-list-contract"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
17
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "application-forms-wizard-REQ-002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Per-step validation timing: on-blur before first submit, then on-change after the first failure, and a full pass on submit reusing the SPA forms-engine",
|
|
5
|
+
"description": "Every step validates its own answers before advancing. Validation timing is on-blur before the first submit attempt on a step (a field validates when the operator leaves it), then on-change after the first submit failure on that field (so the operator sees the message clear as they correct it), and a full pass on submit that rebuilds the error set from scratch. Validation delegates to the SPA blueprint's forms-engine TAC-205 so a project already applying application-spa does not compose two overlapping engines. On refusal the engine surfaces the failed fields to the error-summary contract (REQ-003). The timing rule is a closed set at v1.0.0; different projects can elicit stricter (validate on every change from the start) via a project-level ADR but the shipped default is the three-mode rule above.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "application",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Per visual round 4 spec section 5.3, REQ 2.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:application-forms-wizard",
|
|
12
|
+
"category:02-validation-timing"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
17
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "application-forms-wizard-REQ-003",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Error-summary contract: top-of-page summary with skip links per failed field, aria-invalid on the field, and focus moved to the summary heading on submit failure",
|
|
5
|
+
"description": "On submit refusal the step renders a top-of-page error summary region carrying a heading and one skip link per failed field. Each skip link's target is a focusable field element; the field carries aria-invalid=\"true\" while unresolved and aria-describedby pointing at the field-level error message. On submit failure the client moves focus to the summary heading so a screen-reader user hears the error class and can walk the skip links; visual users see the heading anchor scroll into view. The summary and per-field bindings anchor on TAC-2502 (error-summary contract). Per WCAG 2.2 SC 3.3.1 Error Identification and SC 3.3.3 Error Suggestion.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "application",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Per visual round 4 spec section 5.3, REQ 3.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:application-forms-wizard",
|
|
12
|
+
"category:03-error-summary"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-06T18:00:00Z",
|
|
17
|
+
"updatedAt": "2026-09-06T18:00:00Z"
|
|
18
|
+
}
|