rcf-lite 0.22.0 → 0.24.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 +38 -0
- package/bin/rcf.js +13 -2
- package/blueprints/application-account-settings/docs/topics.md +9 -1
- package/blueprints/application-admin-console/CHANGELOG.md +12 -0
- package/blueprints/application-admin-console/blueprint.json +34 -1
- package/blueprints/application-admin-console/contributions/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +25 -0
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-014.json +17 -0
- package/blueprints/application-admin-console/contributions/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +32 -0
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21815.json +27 -0
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21816.json +27 -0
- package/blueprints/application-admin-console/docs/topics.md +9 -1
- package/blueprints/application-admin-console/guide/application-admin-console.md +24 -0
- package/blueprints/application-admin-console/probe-packs/application-admin-console.pack.mjs +26 -1
- package/blueprints/application-api-rest/docs/topics.md +9 -1
- package/blueprints/application-charts/docs/topics.md +9 -1
- package/blueprints/application-dashboard/docs/topics.md +9 -1
- package/blueprints/application-datatable/docs/topics.md +9 -1
- package/blueprints/application-empty-error-states/docs/topics.md +9 -1
- package/blueprints/application-error-handling/docs/topics.md +9 -1
- package/blueprints/application-file-upload/docs/topics.md +9 -1
- package/blueprints/application-forms-wizard/docs/topics.md +9 -1
- package/blueprints/application-notifications-in-app/docs/topics.md +9 -1
- package/blueprints/application-onboarding-tour/docs/topics.md +9 -1
- package/blueprints/application-spa/docs/topics.md +10 -2
- package/blueprints/delivery-ci-workflows/docs/topics.md +9 -1
- package/blueprints/deploy-cloudflare-workers/CHANGELOG.md +69 -0
- package/blueprints/deploy-cloudflare-workers/README.md +12 -0
- package/blueprints/deploy-cloudflare-workers/blueprint.json +234 -36
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1306-deploy-cloudflare-workers-spa-shape.json +30 -0
- package/blueprints/deploy-cloudflare-workers/contributions/probes/assets-manifest-scan.mjs +207 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-013.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-014.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12113.json +36 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12114.json +27 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12115.json +27 -0
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +10 -2
- package/blueprints/deploy-cloudflare-workers/guide/deploy-cloudflare-workers.md +25 -0
- package/blueprints/edge-cloudflare-access/CHANGELOG.md +23 -0
- package/blueprints/edge-cloudflare-access/README.md +141 -0
- package/blueprints/edge-cloudflare-access/blueprint.json +197 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +14 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +12 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +12 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +100 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/audit-event-secrecy.mjs +70 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-fixture.mjs +63 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-reject.mjs +95 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/probe-utils.mjs +90 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/real-account-gated-url.mjs +65 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-admin-console-gate-surface.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-audit-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-fixture.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-reject.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-real-account-gated-url.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-wrangler-seam.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/wrangler-seam.mjs +203 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-001.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-002.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-003.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-004.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-005.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-006.json +18 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +31 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +33 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34101.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34102.json +28 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34103.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34104.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34105.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34106.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34107.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34108.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34109.json +27 -0
- package/blueprints/edge-cloudflare-access/docs/topics.md +68 -0
- package/blueprints/edge-cloudflare-access/guide/edge-cloudflare-access.md +180 -0
- package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +10 -0
- package/blueprints/edge-cloudflare-rate-limiting/README.md +73 -0
- package/blueprints/edge-cloudflare-rate-limiting/blueprint.json +174 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/event-secrecy.mjs +104 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-presence.mjs +95 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-schema-validate.mjs +130 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/probe-utils.mjs +111 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/real-account-burst-and-429.mjs +104 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-presence.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-schema-validate.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-real-account-burst-and-429.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-001.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-002.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-003.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-004.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-005.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/schemas/rate-limit-rule.schema.json +67 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +31 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +25 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +26 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36101.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36102.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36103.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36104.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36105.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36106.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36107.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36108.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +68 -0
- package/blueprints/edge-cloudflare-rate-limiting/guide/edge-cloudflare-rate-limiting.md +88 -0
- package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +20 -0
- package/blueprints/edge-cloudflare-turnstile/README.md +95 -0
- package/blueprints/edge-cloudflare-turnstile/blueprint.json +161 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/event-secrecy.mjs +51 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/guard-shape-scan.mjs +48 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/probe-utils.mjs +139 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-guard-shape-scan.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-secret-shape-scan.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-siteverify-fixture.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/secret-shape-scan.mjs +77 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/siteverify-fixture.mjs +53 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-001.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-002.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-003.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-004.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-005.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +26 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +36 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +25 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35101.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35102.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35103.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35104.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35105.json +36 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35106.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35107.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35108.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/docs/topics.md +68 -0
- package/blueprints/edge-cloudflare-turnstile/guide/edge-cloudflare-turnstile.md +104 -0
- package/blueprints/edge-cloudflare-turnstile/probe-packs/edge-cloudflare-turnstile.pack.mjs +146 -0
- package/blueprints/email-smtp-resend/docs/topics.md +9 -1
- package/blueprints/jobs-background/CHANGELOG.md +16 -0
- package/blueprints/jobs-background/README.md +105 -0
- package/blueprints/jobs-background/blueprint.json +149 -0
- package/blueprints/jobs-background/contributions/adrs/adr-3101-jobs-background-model.json +27 -0
- package/blueprints/jobs-background/contributions/adrs/adr-3102-jobs-background-scheduler-mode.json +25 -0
- package/blueprints/jobs-background/contributions/adrs/adr-3103-jobs-background-requires-applied-capabilities.json +25 -0
- package/blueprints/jobs-background/contributions/adrs/adr-3104-jobs-background-timeout-floor.json +25 -0
- package/blueprints/jobs-background/contributions/probes/apply-time-override.mjs +95 -0
- package/blueprints/jobs-background/contributions/probes/apply-time-refusal.mjs +82 -0
- package/blueprints/jobs-background/contributions/probes/event-secrecy.mjs +69 -0
- package/blueprints/jobs-background/contributions/probes/fake-clock-cron.mjs +65 -0
- package/blueprints/jobs-background/contributions/probes/probe-utils.mjs +91 -0
- package/blueprints/jobs-background/contributions/probes/retry-and-fail.mjs +65 -0
- package/blueprints/jobs-background/contributions/probes/run-apply-time-override.mjs +10 -0
- package/blueprints/jobs-background/contributions/probes/run-apply-time-refusal.mjs +11 -0
- package/blueprints/jobs-background/contributions/probes/run-event-secrecy.mjs +11 -0
- package/blueprints/jobs-background/contributions/probes/run-fake-clock-cron.mjs +11 -0
- package/blueprints/jobs-background/contributions/probes/run-retry-and-fail.mjs +11 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-001.json +18 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-002.json +18 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-003.json +18 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-004.json +18 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-005.json +18 -0
- package/blueprints/jobs-background/contributions/requirements/jobs-background-req-006.json +18 -0
- package/blueprints/jobs-background/contributions/tacs/tac-3101-jobs-background-job-definition.json +50 -0
- package/blueprints/jobs-background/contributions/tacs/tac-3102-jobs-background-scheduler.json +50 -0
- package/blueprints/jobs-background/contributions/tacs/tac-3103-jobs-background-run-log.json +49 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30101.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30102.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30103.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30104.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30105.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30106.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30107.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30108.json +25 -0
- package/blueprints/jobs-background/contributions/user-stories/jobs-background-us-30109.json +25 -0
- package/blueprints/jobs-background/docs/topics.md +68 -0
- package/blueprints/jobs-background/guide/jobs-background.md +147 -0
- package/blueprints/messaging-queue-cloudflare/CHANGELOG.md +15 -0
- package/blueprints/messaging-queue-cloudflare/README.md +125 -0
- package/blueprints/messaging-queue-cloudflare/blueprint.json +67 -0
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3001-messaging-queue-cloudflare-adapter.json +30 -0
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3002-messaging-queue-cloudflare-delivery-semantics.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3003-messaging-queue-cloudflare-max-attempts-floor.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/adrs/adr-3004-messaging-queue-cloudflare-batch-defaults.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/event-secrecy.mjs +137 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/probe-utils.mjs +82 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/producer-facade-ready.mjs +35 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/publish-to-delivery.mjs +94 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/real-account-concurrency-smoke.mjs +54 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/retry-and-dlq.mjs +87 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/run-producer-facade-ready.mjs +11 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/run-publish-to-delivery.mjs +5 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/run-real-account-concurrency-smoke.mjs +5 -0
- package/blueprints/messaging-queue-cloudflare/contributions/probes/run-retry-and-dlq.mjs +5 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-001.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-002.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-003.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-004.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-005.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/requirements/messaging-queue-cloudflare-req-006.json +18 -0
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3001-messaging-queue-cloudflare-producer-facade.json +56 -0
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3002-messaging-queue-cloudflare-consumer-registration.json +40 -0
- package/blueprints/messaging-queue-cloudflare/contributions/tacs/tac-3003-messaging-queue-cloudflare-event-sink.json +39 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29101.json +34 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29102.json +34 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29103.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29104.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29105.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29106.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29107.json +25 -0
- package/blueprints/messaging-queue-cloudflare/contributions/user-stories/messaging-queue-cloudflare-us-29108.json +25 -0
- package/blueprints/messaging-queue-cloudflare/docs/topics.md +68 -0
- package/blueprints/messaging-queue-cloudflare/guide/messaging-queue-cloudflare.md +110 -0
- package/blueprints/object-storage-s3/docs/topics.md +9 -1
- package/blueprints/observability-essentials/docs/topics.md +9 -1
- package/blueprints/observability-logging/docs/topics.md +9 -1
- package/blueprints/observability-probe-endpoints/docs/topics.md +9 -1
- package/blueprints/persistence-data-d1/docs/topics.md +9 -1
- package/blueprints/persistence-data-postgres/docs/topics.md +9 -1
- package/blueprints/persistence-data-sqlite/docs/topics.md +9 -1
- package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/README.md +117 -0
- package/blueprints/platform-cloudflare-cron-triggers/blueprint.json +85 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3302-platform-cloudflare-cron-triggers-dispatcher-mode.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3303-platform-cloudflare-cron-triggers-skew-tolerance-default.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/dispatcher-routing.mjs +64 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/event-secrecy.mjs +100 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/probe-utils.mjs +70 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/real-account-scheduled-smoke.mjs +100 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-dispatcher-routing.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-real-account-scheduled-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-skew-tolerance.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-wrangler-test-scheduled.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/skew-tolerance.mjs +130 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/wrangler-test-scheduled.mjs +129 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-001.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-002.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-003.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-004.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json +21 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32101.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32102.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32103.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32104.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32105.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32106.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32107.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +71 -0
- package/blueprints/platform-cloudflare-cron-triggers/guide/platform-cloudflare-cron-triggers.md +119 -0
- package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +23 -0
- package/blueprints/platform-cloudflare-durable-objects/README.md +200 -0
- package/blueprints/platform-cloudflare-durable-objects/blueprint.json +243 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3401-platform-cloudflare-durable-objects-single-cell-contract.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3402-platform-cloudflare-durable-objects-websocket-hub-contract.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3403-platform-cloudflare-durable-objects-storage-backend.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3404-platform-cloudflare-durable-objects-migrations-shape.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3405-platform-cloudflare-durable-objects-hibernation-posture.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/alarm-fires-once.mjs +63 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/namespace-facade-ready.mjs +60 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/probe-utils.mjs +105 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/real-account-storage-smoke.mjs +58 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-alarm-fires-once.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-namespace-facade-ready.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-real-account-storage-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-single-cell-concurrent-increment.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-sole-reader-scan.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-storage-round-trip.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-websocket-hub-broadcast.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-wrangler-seam.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/single-cell-concurrent-increment.mjs +56 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/sole-reader-scan.mjs +117 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/storage-round-trip.mjs +87 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/websocket-hub-broadcast.mjs +112 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/wrangler-seam.mjs +257 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-001.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-002.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-003.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-004.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-005.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-006.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-007.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-008.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3401-platform-cloudflare-durable-objects-namespace-facade.json +31 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3402-platform-cloudflare-durable-objects-single-cell-shape.json +30 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3403-platform-cloudflare-durable-objects-alarm-handler.json +29 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3404-platform-cloudflare-durable-objects-websocket-hub.json +31 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3405-platform-cloudflare-durable-objects-event-sink.json +24 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33101.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33102.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33103.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33104.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33105.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33106.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33107.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33108.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33109.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33110.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33111.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33112.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33113.json +25 -0
- package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +73 -0
- package/blueprints/platform-cloudflare-durable-objects/guide/platform-cloudflare-durable-objects.md +237 -0
- package/blueprints/platform-cloudflare-kv/CHANGELOG.md +21 -0
- package/blueprints/platform-cloudflare-kv/README.md +159 -0
- package/blueprints/platform-cloudflare-kv/blueprint.json +87 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3201-platform-cloudflare-kv-key-value-store-contract.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3202-platform-cloudflare-kv-default-cache-ttl.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3203-platform-cloudflare-kv-key-naming-convention.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/cache-aside-hit-then-miss.mjs +82 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/event-secrecy.mjs +102 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/facade-round-trip.mjs +92 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/list-with-prefix.mjs +52 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/probe-utils.mjs +73 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/real-account-eventual-consistency-smoke.mjs +102 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-cache-aside-hit-then-miss.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-facade-round-trip.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-list-with-prefix.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-real-account-eventual-consistency-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-001.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-002.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-003.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-004.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-005.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3201-platform-cloudflare-kv-facade.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3202-platform-cloudflare-kv-cache-aside.json +26 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3203-platform-cloudflare-kv-event-sink.json +25 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31101.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31102.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31103.json +36 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31104.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31105.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31106.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31107.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31108.json +27 -0
- package/blueprints/platform-cloudflare-kv/docs/topics.md +71 -0
- package/blueprints/platform-cloudflare-kv/guide/platform-cloudflare-kv.md +138 -0
- package/blueprints/security-auth-clerk/docs/topics.md +9 -1
- package/blueprints/security-auth-keycloak/docs/topics.md +9 -1
- package/blueprints/security-auth-magic-link/docs/topics.md +9 -1
- package/blueprints/security-auth-oauth2/docs/topics.md +9 -1
- package/blueprints/security-secrets-management/docs/topics.md +9 -1
- package/fixtures/canary-manifest.json +6 -6
- package/package.json +1 -1
- package/rcf/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +13 -0
- package/rcf/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +13 -0
- package/rcf/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +13 -0
- package/rcf/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +13 -0
- package/rcf/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +13 -0
- package/rcf/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +13 -0
- package/rcf/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +13 -0
- package/rcf/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +13 -0
- package/rcf/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +13 -0
- package/rcf/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +13 -0
- package/rcf/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +13 -0
- package/rcf/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +13 -0
- package/rcf/code-nodes/cn-206.json +14 -0
- package/rcf/code-nodes/cn-207.json +13 -0
- package/rcf/code-nodes/cn-208.json +14 -0
- package/rcf/code-nodes/cn-209.json +14 -0
- package/rcf/code-nodes/cn-210.json +13 -0
- package/rcf/code-nodes/cn-211.json +12 -0
- package/rcf/code-nodes/cn-212.json +12 -0
- package/rcf/code-nodes/cn-213.json +12 -0
- package/rcf/code-nodes/cn-214.json +15 -0
- package/rcf/code-nodes/cn-215.json +13 -0
- package/rcf/code-nodes/cn-216.json +14 -0
- package/rcf/code-nodes/cn-217.json +13 -0
- package/rcf/code-nodes/cn-230.json +13 -0
- package/rcf/code-nodes/cn-231.json +14 -0
- package/rcf/code-nodes/cn-232.json +13 -0
- package/rcf/code-nodes/cn-233.json +14 -0
- package/rcf/code-nodes/cn-234.json +13 -0
- package/rcf/code-nodes/cn-260.json +21 -0
- package/rcf/code-nodes/cn-261.json +14 -0
- package/rcf/code-nodes/cn-262.json +18 -0
- package/rcf/code-nodes/cn-263.json +12 -0
- package/rcf/code-nodes/cn-264.json +13 -0
- package/rcf/code-nodes/cn-265.json +15 -0
- package/rcf/code-nodes/cn-266.json +12 -0
- package/rcf/code-nodes/cn-267.json +12 -0
- package/rcf/code-nodes/cn-290.json +21 -0
- package/rcf/code-nodes/cn-291.json +12 -0
- package/rcf/code-nodes/cn-292.json +13 -0
- package/rcf/code-nodes/cn-293.json +13 -0
- package/rcf/code-nodes/cn-294.json +13 -0
- package/rcf/code-nodes/cn-295.json +12 -0
- package/rcf/code-nodes/cn-296.json +12 -0
- package/rcf/code-nodes/cn-297.json +12 -0
- package/rcf/code-nodes/cn-298.json +12 -0
- package/rcf/code-nodes/cn-299.json +12 -0
- package/rcf/code-nodes/cn-300.json +12 -0
- package/rcf/code-nodes/cn-301.json +14 -0
- package/rcf/code-nodes/cn-302.json +12 -0
- package/rcf/code-nodes/cn-303.json +12 -0
- package/rcf/code-nodes/cn-304.json +21 -0
- package/rcf/code-nodes/cn-320.json +20 -0
- package/rcf/code-nodes/cn-321.json +14 -0
- package/rcf/code-nodes/cn-350.json +19 -0
- package/rcf/code-nodes/cn-380.json +19 -0
- package/rcf/fbs/fbs-062.json +20 -0
- package/rcf/fbs/fbs-063.json +22 -0
- package/rcf/fbs/fbs-064.json +23 -0
- package/rcf/fbs/fbs-070.json +24 -0
- package/rcf/fbs/fbs-080.json +24 -0
- package/rcf/fbs/fbs-090.json +24 -0
- package/rcf/fbs/fbs-100.json +23 -0
- package/rcf/fbs/fbs-101.json +16 -0
- package/rcf/fbs/fbs-110.json +23 -0
- package/rcf/fbs/fbs-120.json +22 -0
- package/rcf/requirements/req-029.json +57 -0
- package/rcf/requirements/req-030.json +67 -0
- package/rcf/requirements/req-042.json +59 -0
- package/rcf/requirements/req-043.json +39 -0
- package/rcf/requirements/req-050.json +18 -0
- package/rcf/requirements/req-051.json +18 -0
- package/rcf/requirements/req-052.json +18 -0
- package/rcf/requirements/req-053.json +18 -0
- package/rcf/requirements/req-054.json +18 -0
- package/rcf/requirements/req-060.json +20 -0
- package/rcf/requirements/req-061.json +18 -0
- package/rcf/requirements/req-062.json +20 -0
- package/rcf/requirements/req-063.json +20 -0
- package/rcf/requirements/req-070.json +18 -0
- package/rcf/requirements/req-071.json +18 -0
- package/rcf/requirements/req-072.json +18 -0
- package/rcf/requirements/req-073.json +18 -0
- package/rcf/requirements/req-074.json +18 -0
- package/rcf/requirements/req-075.json +18 -0
- package/rcf/requirements/req-076.json +18 -0
- package/rcf/requirements/req-077.json +18 -0
- package/rcf/requirements/req-080.json +18 -0
- package/rcf/requirements/req-081.json +18 -0
- package/rcf/requirements/req-082.json +18 -0
- package/rcf/requirements/req-083.json +18 -0
- package/rcf/requirements/req-084.json +18 -0
- package/rcf/requirements/req-085.json +18 -0
- package/rcf/requirements/req-086.json +18 -0
- package/rcf/requirements/req-090.json +44 -0
- package/rcf/requirements/req-091.json +53 -0
- package/rcf/requirements/req-092.json +32 -0
- package/rcf/requirements/req-093.json +52 -0
- package/rcf/requirements/req-094.json +32 -0
- package/rcf/requirements/req-100.json +13 -0
- package/rcf/requirements/req-101.json +13 -0
- package/rcf/requirements/req-102.json +13 -0
- package/rcf/requirements/req-103.json +13 -0
- package/rcf/requirements/req-104.json +13 -0
- package/rcf/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +15 -0
- package/rcf/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +15 -0
- package/rcf/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +15 -0
- package/rcf/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +15 -0
- package/rcf/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +15 -0
- package/rcf/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +15 -0
- package/rcf/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +15 -0
- package/rcf/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +15 -0
- package/rcf/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +16 -0
- package/rcf/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +15 -0
- package/rcf/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +16 -0
- package/rcf/test-suites/ts-052.json +58 -8
- package/rcf/test-suites/ts-072.json +62 -0
- package/rcf/test-suites/ts-073.json +38 -0
- package/rcf/test-suites/ts-074.json +30 -0
- package/rcf/test-suites/ts-075.json +38 -0
- package/rcf/test-suites/ts-076.json +70 -0
- package/rcf/test-suites/ts-080.json +22 -0
- package/rcf/test-suites/ts-081.json +22 -0
- package/rcf/test-suites/ts-082.json +30 -0
- package/rcf/test-suites/ts-083.json +22 -0
- package/rcf/test-suites/ts-084.json +30 -0
- package/rcf/test-suites/ts-085.json +22 -0
- package/rcf/test-suites/ts-086.json +22 -0
- package/rcf/test-suites/ts-087.json +22 -0
- package/rcf/test-suites/ts-090.json +22 -0
- package/rcf/test-suites/ts-091.json +22 -0
- package/rcf/test-suites/ts-092.json +22 -0
- package/rcf/test-suites/ts-093.json +30 -0
- package/rcf/test-suites/ts-094.json +30 -0
- package/rcf/test-suites/ts-095.json +30 -0
- package/rcf/test-suites/ts-096.json +22 -0
- package/rcf/test-suites/ts-100.json +22 -0
- package/rcf/test-suites/ts-101.json +22 -0
- package/rcf/test-suites/ts-102.json +22 -0
- package/rcf/test-suites/ts-103.json +22 -0
- package/rcf/test-suites/ts-104.json +22 -0
- package/rcf/test-suites/ts-105.json +22 -0
- package/rcf/test-suites/ts-106.json +22 -0
- package/rcf/test-suites/ts-107.json +22 -0
- package/rcf/test-suites/ts-108.json +22 -0
- package/rcf/test-suites/ts-109.json +22 -0
- package/rcf/test-suites/ts-110.json +22 -0
- package/rcf/test-suites/ts-111.json +22 -0
- package/rcf/test-suites/ts-112.json +22 -0
- package/rcf/test-suites/ts-113.json +22 -0
- package/rcf/test-suites/ts-114.json +22 -0
- package/rcf/test-suites/ts-115.json +22 -0
- package/rcf/test-suites/ts-116.json +22 -0
- package/rcf/test-suites/ts-117.json +22 -0
- package/rcf/test-suites/ts-118.json +22 -0
- package/rcf/test-suites/ts-119.json +30 -0
- package/rcf/test-suites/ts-120.json +22 -0
- package/rcf/test-suites/ts-121.json +22 -0
- package/rcf/test-suites/ts-122.json +22 -0
- package/rcf/test-suites/ts-123.json +22 -0
- package/rcf/test-suites/ts-124.json +22 -0
- package/rcf/test-suites/ts-125.json +22 -0
- package/rcf/test-suites/ts-126.json +22 -0
- package/rcf/test-suites/ts-127.json +22 -0
- package/rcf/test-suites/ts-130.json +22 -0
- package/rcf/test-suites/ts-131.json +22 -0
- package/rcf/test-suites/ts-132.json +22 -0
- package/rcf/test-suites/ts-133.json +22 -0
- package/rcf/test-suites/ts-134.json +22 -0
- package/rcf/test-suites/ts-135.json +22 -0
- package/rcf/test-suites/ts-136.json +22 -0
- package/rcf/test-suites/ts-137.json +22 -0
- package/rcf/user-stories/us-10001.json +23 -0
- package/rcf/user-stories/us-10101.json +23 -0
- package/rcf/user-stories/us-10201.json +23 -0
- package/rcf/user-stories/us-10301.json +23 -0
- package/rcf/user-stories/us-10401.json +23 -0
- package/rcf/user-stories/us-10601.json +23 -0
- package/rcf/user-stories/us-10701.json +23 -0
- package/rcf/user-stories/us-10801.json +23 -0
- package/rcf/user-stories/us-2901.json +45 -0
- package/rcf/user-stories/us-2902.json +36 -0
- package/rcf/user-stories/us-3001.json +45 -0
- package/rcf/user-stories/us-4201.json +69 -0
- package/rcf/user-stories/us-4301.json +78 -0
- package/rcf/user-stories/us-5001.json +27 -0
- package/rcf/user-stories/us-5002.json +27 -0
- package/rcf/user-stories/us-5101.json +36 -0
- package/rcf/user-stories/us-5102.json +27 -0
- package/rcf/user-stories/us-5201.json +36 -0
- package/rcf/user-stories/us-5301.json +27 -0
- package/rcf/user-stories/us-5302.json +27 -0
- package/rcf/user-stories/us-5401.json +27 -0
- package/rcf/user-stories/us-6001.json +27 -0
- package/rcf/user-stories/us-6002.json +27 -0
- package/rcf/user-stories/us-6003.json +27 -0
- package/rcf/user-stories/us-6101.json +36 -0
- package/rcf/user-stories/us-6201.json +36 -0
- package/rcf/user-stories/us-6301.json +36 -0
- package/rcf/user-stories/us-6302.json +27 -0
- package/rcf/user-stories/us-7001.json +27 -0
- package/rcf/user-stories/us-7002.json +27 -0
- package/rcf/user-stories/us-7101.json +27 -0
- package/rcf/user-stories/us-7201.json +27 -0
- package/rcf/user-stories/us-7301.json +27 -0
- package/rcf/user-stories/us-7401.json +27 -0
- package/rcf/user-stories/us-7402.json +27 -0
- package/rcf/user-stories/us-7501.json +27 -0
- package/rcf/user-stories/us-7601.json +27 -0
- package/rcf/user-stories/us-7701.json +27 -0
- package/rcf/user-stories/us-8001.json +24 -0
- package/rcf/user-stories/us-8002.json +24 -0
- package/rcf/user-stories/us-8003.json +24 -0
- package/rcf/user-stories/us-8101.json +24 -0
- package/rcf/user-stories/us-8201.json +24 -0
- package/rcf/user-stories/us-8301.json +24 -0
- package/rcf/user-stories/us-8401.json +24 -0
- package/rcf/user-stories/us-8501.json +24 -0
- package/rcf/user-stories/us-8502.json +24 -0
- package/rcf/user-stories/us-8601.json +24 -0
- package/rcf/user-stories/us-8602.json +24 -0
- package/rcf/user-stories/us-9001.json +27 -0
- package/rcf/user-stories/us-9002.json +27 -0
- package/rcf/user-stories/us-9101.json +27 -0
- package/rcf/user-stories/us-9102.json +27 -0
- package/rcf/user-stories/us-9201.json +27 -0
- package/rcf/user-stories/us-9301.json +27 -0
- package/rcf/user-stories/us-9302.json +27 -0
- package/rcf/user-stories/us-9401.json +27 -0
- package/releases/releases.yaml +21 -1
- package/src/blueprint/apply.js +7 -4
- package/src/blueprint/capabilities.js +25 -0
- package/src/cli/blueprint.js +8 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35102",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Server-side siteverify with the always-pass secret returns success true and the handler proceeds with 200",
|
|
8
|
+
"asA": "shelf consumer whose Worker verifies every Turnstile token server-side",
|
|
9
|
+
"iWant": "a POST to https://challenges.cloudflare.com/turnstile/v0/siteverify with the pinned always-pass secret (1x0000000000000000000000000000000AA) and any response token to return success:true and the handler to respond 200",
|
|
10
|
+
"soThat": "the verified path is exercised end-to-end against the live Cloudflare endpoint on every gate run",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35102-1",
|
|
14
|
+
"description": "A live POST to https://challenges.cloudflare.com/turnstile/v0/siteverify with secret=1x0000000000000000000000000000000AA and any response token returns success:true; the pack-fixture /api/submit handler proceeds with 200 and the shipped Node probe siteverify-fixture asserts success:true.",
|
|
15
|
+
"given": "the pack fixture running on 127.0.0.1 on a free port with the pinned always-pass secret in the environment",
|
|
16
|
+
"when": "a submit hits /api/submit with any response token",
|
|
17
|
+
"then": "the server-side POST to siteverify returns success:true and the handler responds 200",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3602-edge-cloudflare-turnstile-server-verifier"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35103",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Server-side siteverify with the always-fail secret returns success false, the handler rejects 400, refusal body carries error-codes and no sitekey",
|
|
8
|
+
"asA": "shelf consumer whose Worker fails safe on every Turnstile refusal",
|
|
9
|
+
"iWant": "a POST to siteverify with the pinned always-fail secret to return success:false, the handler to reject with 400, and the refusal body to carry the documented error-codes value and never the sitekey",
|
|
10
|
+
"soThat": "every failure branch produces a stable machine-observable outcome and never leaks the sitekey or the response token",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35103-1",
|
|
14
|
+
"description": "A live POST to siteverify with secret=2x0000000000000000000000000000000AA (always-fail secret per https://developers.cloudflare.com/turnstile/troubleshooting/testing/) returns success:false; the pack-fixture /api/submit handler rejects with 400 whose body carries the error-codes value (invalid-input-response) and no sitekey or secret substring.",
|
|
15
|
+
"given": "the pack fixture running with the pinned always-fail secret in the environment",
|
|
16
|
+
"when": "a submit hits /api/submit with any response token and the verifier calls siteverify",
|
|
17
|
+
"then": "siteverify returns success:false and the handler responds 400 with an error-codes body and no sitekey leak",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3602-edge-cloudflare-turnstile-server-verifier"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35104",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-003",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Refuse-if-token-missing guard rejects submit with 400 before any downstream handler runs",
|
|
8
|
+
"asA": "shelf consumer whose Worker rejects cheap missing-token submit attempts at the earliest possible boundary",
|
|
9
|
+
"iWant": "a source-tree scan to enumerate every elicited surface and confirm each carries a token-required guard, and a live missing-token submit to be refused with 400 with no downstream side-effect",
|
|
10
|
+
"soThat": "no downstream handler ever executes against a missing-token submit",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35104-1",
|
|
14
|
+
"description": "The Node probe guard-shape-scan enumerates every elicited surface in the pack fixture source and asserts each is registered under the token-required guard. A live POST to /api/submit without a Cf-Turnstile-Response field is rejected with 400 and refusal body carries error-code turnstile.token-missing; no downstream handler side-effect is observable.",
|
|
15
|
+
"given": "the pack fixture running with every elicited surface registered under the token-required guard",
|
|
16
|
+
"when": "a submit reaches /api/submit without a Cf-Turnstile-Response value",
|
|
17
|
+
"then": "the guard rejects with 400 with an error-code body and no downstream handler runs",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3602-edge-cloudflare-turnstile-server-verifier"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35105",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-004",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Composition with security-auth-magic-link gates the magic-link mint surface behind the Turnstile guard",
|
|
8
|
+
"asA": "shelf consumer applying both security-auth-magic-link and edge-cloudflare-turnstile",
|
|
9
|
+
"iWant": "the magic-link mint surface to be registered under the Turnstile guard so a mint submit reads through the same token check as any other elicited surface, and a mint without a valid Turnstile token to be refused with 400 before the mint fires",
|
|
10
|
+
"soThat": "magic-link mint requests are protected by the same human-check as any other public form",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35105-1",
|
|
14
|
+
"description": "The pack fixture ships a /api/magic-link mint stub route registered under the Turnstile guard. A source-tree read of the composition wire confirms the mint surface reads the Turnstile guard before invoking the magic-link mint.",
|
|
15
|
+
"given": "the pack fixture with both blueprints applied and /api/magic-link registered under the token-required guard",
|
|
16
|
+
"when": "the composition wire is walked in the source tree",
|
|
17
|
+
"then": "the magic-link mint surface reads the Turnstile guard before invoking the mint",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "AC-35105-2",
|
|
23
|
+
"description": "A live POST to /api/magic-link without a Cf-Turnstile-Response field, and a POST carrying the always-fail response token that fails siteverify, are both refused with 400 by the Turnstile guard and no magic-link mint side-effect is observable. The Playwright pack check magicLinkGuard drives this against the fixture with a real browser.",
|
|
24
|
+
"given": "the pack fixture running with both blueprints applied and a real Playwright browser driving the fixture",
|
|
25
|
+
"when": "a magic-link mint submit is issued without a Turnstile response, or with the always-fail response token",
|
|
26
|
+
"then": "the Turnstile guard refuses with 400 and no magic-link mint side-effect is observable",
|
|
27
|
+
"testable": true,
|
|
28
|
+
"scope": "runtime"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"tacIds": [
|
|
32
|
+
"TAC-3603-edge-cloudflare-turnstile-magic-link-hook"
|
|
33
|
+
],
|
|
34
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
35
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
36
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35106",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Widget mode is elicited as an enum (managed, non-interactive, invisible); default managed and each mode renders per Cloudflare documented modes",
|
|
8
|
+
"asA": "shelf consumer selecting a Turnstile widget mode for the applied surface",
|
|
9
|
+
"iWant": "to elicit one of managed, non-interactive or invisible at apply time with managed as the recommendedDefault, and to see each mode render as Cloudflare documents",
|
|
10
|
+
"soThat": "the applied widget mode matches the operational profile my site needs",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35106-1",
|
|
14
|
+
"description": "The blueprint elicit widget-mode is enum with values managed, non-interactive, invisible; recommendedDefault managed per ADR-3602. The pack fixture accepts ?mode=<managed|non-interactive|invisible> and mounts the widget with the pinned invisible-widget test sitekeys (1x00000000000000000000BB, 2x00000000000000000000BB per https://developers.cloudflare.com/turnstile/troubleshooting/testing/). Each mode renders the Turnstile iframe from https://challenges.cloudflare.com and no other origin.",
|
|
15
|
+
"given": "the pack fixture loaded with mode=managed, mode=non-interactive and mode=invisible respectively",
|
|
16
|
+
"when": "each variant renders",
|
|
17
|
+
"then": "each renders the Turnstile widget from Cloudflare Turnstile origin only and no third-party script is loaded",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3601-edge-cloudflare-turnstile-widget-mount"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35107",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "TURNSTILE_SECRET is read only via the applied secrets facade and never inlined in fixture source",
|
|
8
|
+
"asA": "reviewer auditing the applied Workers project for secret hygiene",
|
|
9
|
+
"iWant": "the TURNSTILE_SECRET to be dereferenced only via process.env or an env-shaped facade and no plain-text secret literal in the fixture source",
|
|
10
|
+
"soThat": "the Turnstile secret is never committed to the applying project source tree",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35107-1",
|
|
14
|
+
"description": "A source-tree AST scan of the pack fixture (packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile) asserts that TURNSTILE_SECRET is read only via env-shaped identifiers (process.env.TURNSTILE_SECRET or an env facade) and that no plain-string secret literal appears in the fixture source; the Node probe secret-shape-scan implements the assertion and exits 0.",
|
|
15
|
+
"given": "the shipped pack fixture with the pinned test secrets sourced from environment",
|
|
16
|
+
"when": "the source-tree AST scan runs over the fixture",
|
|
17
|
+
"then": "the scan finds only env-shaped reads for TURNSTILE_SECRET and reports no plain-string secret literal",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3602-edge-cloudflare-turnstile-server-verifier"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-turnstile-US-35108",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-turnstile-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Event records carry sitekeyHash, outcome and timestamp only; no token and no secret",
|
|
8
|
+
"asA": "reviewer auditing the applied Workers project for observability hygiene",
|
|
9
|
+
"iWant": "every event record produced by a Turnstile verification to carry sitekeyHash, outcome and timestamp only and never carry the token or the secret value",
|
|
10
|
+
"soThat": "the observability tier never sees the raw Turnstile response or the Turnstile secret",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-35108-1",
|
|
14
|
+
"description": "The Node probe event-secrecy drives siteverify against Cloudflare with the pinned test keys and asserts every event record carries {sitekeyHash, outcome, timestamp} keys only; no record carries the token, no record carries the secret, and no forbidden substring is present in the serialised record.",
|
|
15
|
+
"given": "the pack fixture running with the event-secrecy probe attached and the pinned test keys in the environment",
|
|
16
|
+
"when": "the probe drives one pass and one fail through the verifier",
|
|
17
|
+
"then": "every emitted event carries only sitekeyHash, outcome and timestamp",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3602-edge-cloudflare-turnstile-server-verifier"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# edge-cloudflare-turnstile blueprint coordination vocabulary
|
|
2
|
+
|
|
3
|
+
This file is the edge-cloudflare-turnstile half of the cross-blueprint contract. The Phase 1 conflict detector matches scope:global ADR topics by EXACT string equality, and AC ids are unnamespaced by the 0.4.4 grammar. Any blueprint intended to compose with this one must reuse these exact strings and respect these bands.
|
|
4
|
+
|
|
5
|
+
## Global ADR topics this blueprint contributes (exact strings)
|
|
6
|
+
|
|
7
|
+
| Topic string | edge-cloudflare-turnstile contribution | Origin | Composition note |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `humanVerificationGate` | ADR-3601-edge-cloudflare-turnstile-verifier-contract | Minted by this blueprint. Names the wire-shape contract for the project-wide human verification gate; the shipped answer is Cloudflare Turnstile with server-side siteverify per `https://developers.cloudflare.com/turnstile/`. | The one project-wide decision on the human verification gate at the shipped-shape boundary. A future non-Cloudflare sibling (hCaptcha, reCAPTCHA) would contribute the same topic string with a different answer, forcing a DELIBERATE conflict the operator resolves with a project-level ADR. |
|
|
10
|
+
|
|
11
|
+
The edge-cloudflare-turnstile blueprint claims one global topic (minted here, shipped as the Cloudflare Turnstile siteverify verifier). ADR-3602 widget mode and ADR-3603 refuse shape do not contribute global topics; a composing blueprint that holds an opinion on either authors its own project-level ADR.
|
|
12
|
+
|
|
13
|
+
Rules for new topics: lower camel case, one concept per topic, no version suffixes. A topic names the decision area, not the chosen answer.
|
|
14
|
+
|
|
15
|
+
## Id number bands (registry bootstrap)
|
|
16
|
+
|
|
17
|
+
This table is maintained shelf-wide across every blueprint's `docs/topics.md`. Rows are recorded at ship, never predicted.
|
|
18
|
+
|
|
19
|
+
| Blueprint | US band | ADR/TAC suffix block | Status | Global topics |
|
|
20
|
+
|---|---|---|---|---|
|
|
21
|
+
| application-spa | 1101-1899 | 2xx | shipped v1.3.0 | `clientRouting`, `theming`, `clientState`, `errorEnvelope`, `authModel` |
|
|
22
|
+
| application-api-rest | 2101-2899 | 3xx | shipped v1.0.0 | `errorEnvelope`, `authModel`, `apiVersioning`, `logging` |
|
|
23
|
+
| security-auth-magic-link | 3101-3899 | 5xx | shipped v1.2.0 | `authModel` |
|
|
24
|
+
| email-smtp-resend | 4101-4899 | 4xx | shipped v1.0.0 | none |
|
|
25
|
+
| hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
|
|
26
|
+
| persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
27
|
+
| delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
|
|
28
|
+
| observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
|
|
29
|
+
| security-secrets-management | 8101-8899 | 9xx | shipped v1.0.1 | `secretsSource` |
|
|
30
|
+
| security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
|
|
31
|
+
| security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
|
|
32
|
+
| security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
|
|
33
|
+
| deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.2.0 | `deploymentTarget` |
|
|
34
|
+
| persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
35
|
+
| observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
|
|
36
|
+
| observability-logging | 15101-15899 | 16xx | shipped v1.0.0 | `logging` |
|
|
37
|
+
| application-error-handling | 16101-16899 | 17xx | shipped v1.0.0 | `errorHandling` |
|
|
38
|
+
| application-datatable | 17101-17899 | 18xx | shipped v1.0.0 | none |
|
|
39
|
+
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
40
|
+
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
41
|
+
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
42
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
43
|
+
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
44
|
+
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
45
|
+
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
46
|
+
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
47
|
+
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
48
|
+
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
49
|
+
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
50
|
+
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
51
|
+
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
52
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
53
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
54
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
55
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
56
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
57
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
58
|
+
|
|
59
|
+
US 35101-35108 sit at the LOW end of the 35101-35899 band on purpose (watchpost run-4 lesson). ADR/TAC suffixes for this blueprint use the 3601-3699 block, continuing the shelf pattern.
|
|
60
|
+
|
|
61
|
+
## Shared expectations for future composing blueprints
|
|
62
|
+
|
|
63
|
+
- Reuse `humanVerificationGate` exactly as spelled here when your blueprint holds an opinion on the human verification gate contract; contribute your own scope:global ADR on that string and let composition surface the pairing.
|
|
64
|
+
- Consumer blueprints reading the `humanCheck` capability declared on `blueprint.json` per section 6a of `blueprint-authoring.md` obtain the Turnstile-guarded composition at apply time via the capability-declaration mechanism.
|
|
65
|
+
|
|
66
|
+
## Deliberate-conflict statement
|
|
67
|
+
|
|
68
|
+
This blueprint's ADR-3601 on `humanVerificationGate` is the first shipped answer to a topic that will conflict, by design, with future non-Cloudflare siblings. Applying `edge-cloudflare-turnstile` alongside such a sibling would raise a `globalAdrTopic` conflict the operator resolves via one of the four documented resolutions (adopt one, keep the existing one, author a project-level supersede ADR, or `--resolve <topic>=project:<ADR-id>` on the add).
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# edge-cloudflare-turnstile guide
|
|
2
|
+
|
|
3
|
+
This guide walks the operator through applying the `edge-cloudflare-turnstile` v1.0.0 blueprint to a Workers project, wiring the client widget mount, calling the server-side siteverify, refusing missing-token submits, and composing the guard with `security-auth-magic-link` on the mint surface.
|
|
4
|
+
|
|
5
|
+
## 1. Prerequisites
|
|
6
|
+
|
|
7
|
+
- A Cloudflare Turnstile widget (sitekey and paired secret). Cloudflare documents issuing at `https://developers.cloudflare.com/turnstile/`. For CI and development, the fixture pins the always-pass and always-fail public test keys documented at `https://developers.cloudflare.com/turnstile/troubleshooting/testing/`.
|
|
8
|
+
- A Cloudflare Workers project (`deploy-cloudflare-workers` applied) or the shipped pack fixture at `packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile/`.
|
|
9
|
+
|
|
10
|
+
## 2. Apply the blueprint
|
|
11
|
+
|
|
12
|
+
At apply time the blueprint elicits four values:
|
|
13
|
+
|
|
14
|
+
| Elicit | Answer |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `turnstile-sitekey` | The Cloudflare Turnstile sitekey the widget renders with. |
|
|
17
|
+
| `turnstile-secret` | The paired secret. Store through the applied `security-secrets-management` companion. |
|
|
18
|
+
| `turnstile-widget-mode` | One of `managed` (default), `non-interactive`, `invisible`. |
|
|
19
|
+
| `turnstile-guarded-surfaces` | Comma-separated list of applied route ids the guard registers on. |
|
|
20
|
+
|
|
21
|
+
## 3. Client widget mount snippet
|
|
22
|
+
|
|
23
|
+
Paste the following into the public form surface. The mount injects Cloudflare Turnstile JS from `https://challenges.cloudflare.com` and populates the `cf-turnstile-response` hidden input on submit.
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
|
|
27
|
+
<form method="post" action="/api/submit">
|
|
28
|
+
<label>Email <input type="email" name="email" required></label>
|
|
29
|
+
<div class="cf-turnstile"
|
|
30
|
+
data-sitekey="YOUR_TURNSTILE_SITEKEY"
|
|
31
|
+
data-callback="onTurnstileToken"></div>
|
|
32
|
+
<button type="submit">Submit</button>
|
|
33
|
+
</form>
|
|
34
|
+
<script>
|
|
35
|
+
window.onTurnstileToken = function (token) {
|
|
36
|
+
var f = document.querySelector('form');
|
|
37
|
+
var i = f.querySelector('input[name="cf-turnstile-response"]');
|
|
38
|
+
if (!i) {
|
|
39
|
+
i = document.createElement('input');
|
|
40
|
+
i.type = 'hidden';
|
|
41
|
+
i.name = 'cf-turnstile-response';
|
|
42
|
+
f.appendChild(i);
|
|
43
|
+
}
|
|
44
|
+
i.value = token;
|
|
45
|
+
};
|
|
46
|
+
</script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 4. Server-side siteverify
|
|
50
|
+
|
|
51
|
+
Every submit is verified server-side by POSTing to Cloudflare's siteverify endpoint per `https://developers.cloudflare.com/turnstile/`. On `success:true` the handler proceeds; on `success:false` the handler rejects with 400 and the refusal body carries the documented `error-codes` value.
|
|
52
|
+
|
|
53
|
+
`curl` example:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
curl -sS -X POST https://challenges.cloudflare.com/turnstile/v0/siteverify \
|
|
57
|
+
-d "secret=$TURNSTILE_SECRET" \
|
|
58
|
+
-d "response=$CLIENT_TOKEN"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Response on pass:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
{"success":true,"challenge_ts":"...","hostname":"..."}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Response on fail:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
{"success":false,"error-codes":["invalid-input-response"]}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 5. Refuse-if-token-missing guard
|
|
74
|
+
|
|
75
|
+
Every elicited surface is registered under the token-required guard. A submit whose payload has no `cf-turnstile-response` field is refused with `400 {"errorCode":"turnstile.token-missing"}` before any downstream handler runs. The pack fixture (`packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile/server.js`) is the reference wiring; the applied Worker mirrors the shape.
|
|
76
|
+
|
|
77
|
+
## 6. Composition with security-auth-magic-link
|
|
78
|
+
|
|
79
|
+
When `security-auth-magic-link` is also applied, the composition hook (`TAC-3603`) registers the magic-link mint route under the Turnstile guard. The mint reads the Turnstile token check before invoking the mint. Example:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
POST /api/magic-link
|
|
83
|
+
Content-Type: application/x-www-form-urlencoded
|
|
84
|
+
|
|
85
|
+
email=alice@example.com&cf-turnstile-response=<TOKEN>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Missing token: `400 {"errorCode":"turnstile.token-missing"}` with no mint side-effect.
|
|
89
|
+
- Failed siteverify: `400 {"errorCode":"turnstile.siteverify-failed","errorCodes":[...]}` with no mint side-effect.
|
|
90
|
+
- Pass: `200 {"mint":"ok"}` and the magic-link mint fires.
|
|
91
|
+
|
|
92
|
+
## 7. Widget mode
|
|
93
|
+
|
|
94
|
+
Cloudflare Turnstile documents three widget modes per `https://developers.cloudflare.com/turnstile/`: `managed` (Cloudflare decides when to render a challenge), `non-interactive` (always shows a non-interactive challenge) and `invisible` (invisible widget). The blueprint elicits the mode; the shipped default is `managed`.
|
|
95
|
+
|
|
96
|
+
The pack fixture accepts `?mode=<managed|non-interactive|invisible>` for a per-page-load override.
|
|
97
|
+
|
|
98
|
+
## 8. Test keys and CI
|
|
99
|
+
|
|
100
|
+
For CI or development the fixture pins Cloudflare's public test keys per `https://developers.cloudflare.com/turnstile/troubleshooting/testing/`. The always-pass sitekey `1x00000000000000000000AA` and always-fail sitekey `2x00000000000000000000AB` drive the deterministic branches of the shipped probes. No real Turnstile credentials are required for the pack to run.
|
|
101
|
+
|
|
102
|
+
## 9. Observability
|
|
103
|
+
|
|
104
|
+
Every event record carries `sitekeyHash`, `outcome` and `timestamp` keys only. The token and the secret are never in the record. The `event-secrecy` probe asserts this shape on every apply.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// edge-cloudflare-turnstile probe pack (v1.0.0).
|
|
2
|
+
//
|
|
3
|
+
// Four surface-observable checks per cloudflare-round-6-spec section 3.2:
|
|
4
|
+
// AC-turnstile-widgetRendered Turnstile widget mounts with the pinned always-pass sitekey and the mount injects no third-party script beyond the Cloudflare Turnstile host.
|
|
5
|
+
// AC-turnstile-serverVerified-pass Live POST to Cloudflare siteverify with always-pass secret returns success:true and the handler responds 200.
|
|
6
|
+
// AC-turnstile-serverVerified-fail Live POST to Cloudflare siteverify with always-fail secret returns success:false and the handler rejects 400.
|
|
7
|
+
// AC-turnstile-magicLinkGuard Magic-link mint route composed with the Turnstile guard refuses a mint submit without a valid Turnstile response with 400 and no mint side-effect.
|
|
8
|
+
//
|
|
9
|
+
// The pack ships no appliesTo predicate (Turnstile is not capability-gated per spec section 3.2). Every fixture
|
|
10
|
+
// that applies the blueprint fires every check. Runtime URL and browser are supplied by the pack runner; the
|
|
11
|
+
// dedicated pack fixture at packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile pins the
|
|
12
|
+
// Cloudflare public test keys documented at https://developers.cloudflare.com/turnstile/troubleshooting/testing/.
|
|
13
|
+
|
|
14
|
+
function withUrl(runtimeUrl, path) {
|
|
15
|
+
return new URL(path, runtimeUrl).toString();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const CLOUDFLARE_TURNSTILE_ORIGIN = 'https://challenges.cloudflare.com';
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
packName: 'edge-cloudflare-turnstile',
|
|
22
|
+
version: '1.0.0',
|
|
23
|
+
blueprintSlug: 'edge-cloudflare-turnstile',
|
|
24
|
+
appliesTo: () => true,
|
|
25
|
+
boot: { bootCommand: null, waitForUrl: null, waitForSelector: null },
|
|
26
|
+
checks: [
|
|
27
|
+
{
|
|
28
|
+
id: 'AC-turnstile-widgetRendered',
|
|
29
|
+
severity: 'block',
|
|
30
|
+
description: 'Turnstile client widget mounts with the pinned always-pass sitekey; the mount injects Cloudflare Turnstile JS from the Cloudflare Turnstile origin only, populates the Cf-Turnstile-Response token input, and no third-party script from any other origin is loaded on the page.',
|
|
31
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
32
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
33
|
+
await browser.goto(withUrl(runtimeUrl, '/?sitekey=pass'));
|
|
34
|
+
// Wait for the widget to inject the token. Turnstile fires the callback asynchronously and the always-pass
|
|
35
|
+
// test sitekey (1x00000000000000000000AA per Cloudflare testing docs) resolves without rendering an iframe.
|
|
36
|
+
await new Promise((r) => setTimeout(r, 6000));
|
|
37
|
+
const dom = await browser.evaluate((cfOrigin) => {
|
|
38
|
+
const widget = document.querySelector('[data-role="turnstile-widget"]');
|
|
39
|
+
const sitekeyEl = document.querySelector('[data-role="sitekey"]');
|
|
40
|
+
const scripts = Array.from(document.querySelectorAll('script[src]')).map((s) => s.src);
|
|
41
|
+
const cloudflareScripts = scripts.filter((s) => s.startsWith(cfOrigin));
|
|
42
|
+
const thirdParty = scripts.filter((s) => {
|
|
43
|
+
try { const u = new URL(s); if (u.origin === window.location.origin) return false; return u.origin !== cfOrigin; }
|
|
44
|
+
catch { return false; }
|
|
45
|
+
});
|
|
46
|
+
const tokenInputs = Array.from(document.querySelectorAll('input[name="cf-turnstile-response"]'));
|
|
47
|
+
const tokenValues = tokenInputs.map((i) => (i.value || '').slice(0, 8));
|
|
48
|
+
return {
|
|
49
|
+
widgetPresent: !!widget,
|
|
50
|
+
sitekey: sitekeyEl ? sitekeyEl.textContent.trim() : null,
|
|
51
|
+
scriptCount: scripts.length, cloudflareScriptCount: cloudflareScripts.length, thirdPartyScripts: thirdParty,
|
|
52
|
+
tokenInputCount: tokenInputs.length, tokenValueSample: tokenValues,
|
|
53
|
+
tokenPopulated: tokenInputs.some((i) => i.value && i.value.length > 0),
|
|
54
|
+
};
|
|
55
|
+
}, CLOUDFLARE_TURNSTILE_ORIGIN);
|
|
56
|
+
if (!dom.widgetPresent) return { verdict: 'fail', detail: 'Turnstile widget element [data-role="turnstile-widget"] not found on /?sitekey=pass' };
|
|
57
|
+
if (dom.cloudflareScriptCount < 1) return { verdict: 'fail', detail: `Cloudflare Turnstile JS not injected from ${cfOrigin}; scripts=${JSON.stringify(dom)}`.replace('${cfOrigin}', 'https://challenges.cloudflare.com') };
|
|
58
|
+
if (dom.thirdPartyScripts.length > 0) return { verdict: 'fail', detail: `third-party script(s) present beyond Cloudflare Turnstile: ${JSON.stringify(dom.thirdPartyScripts)}` };
|
|
59
|
+
if (dom.tokenInputCount < 1) return { verdict: 'fail', detail: `no cf-turnstile-response input in the page after widget mount; DOM=${JSON.stringify(dom)}` };
|
|
60
|
+
if (!dom.tokenPopulated) return { verdict: 'fail', detail: `cf-turnstile-response input not populated by Turnstile; token samples=${JSON.stringify(dom.tokenValueSample)}` };
|
|
61
|
+
return { verdict: 'pass', detail: `widget mounted; sitekey=${dom.sitekey}; cloudflareScripts=${dom.cloudflareScriptCount}; tokenPopulated=true tokenSample=${JSON.stringify(dom.tokenValueSample)}; thirdParty=0` };
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'AC-turnstile-serverVerified-pass',
|
|
66
|
+
severity: 'block',
|
|
67
|
+
description: 'Live POST to challenges.cloudflare.com/turnstile/v0/siteverify with the pinned always-pass secret returns success:true; the fixture /api/submit handler responds 200.',
|
|
68
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
69
|
+
// Server-side siteverify pass. Uses the browser as a driver to build a form submission then reads
|
|
70
|
+
// the server response.
|
|
71
|
+
const body = new URLSearchParams();
|
|
72
|
+
body.set('email', 'reviewer@example.com');
|
|
73
|
+
body.set('turnstile-sitekey', '1x00000000000000000000AA');
|
|
74
|
+
body.set('cf-turnstile-response', 'PACK-CHECK-PASS-TOKEN');
|
|
75
|
+
const resp = await fetch(withUrl(runtimeUrl, '/api/submit'), {
|
|
76
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body,
|
|
77
|
+
});
|
|
78
|
+
const text = await resp.text();
|
|
79
|
+
let json = null; try { json = JSON.parse(text); } catch { /* leave null */ }
|
|
80
|
+
const ok = resp.status === 200 && json && json.received === 'ok';
|
|
81
|
+
return {
|
|
82
|
+
verdict: ok ? 'pass' : 'fail',
|
|
83
|
+
detail: ok
|
|
84
|
+
? `serverVerified-pass: fixture /api/submit returned status=200 body=${text} (Cloudflare siteverify success:true with always-pass secret)`
|
|
85
|
+
: `serverVerified-pass unexpected shape status=${resp.status} body=${text}`,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'AC-turnstile-serverVerified-fail',
|
|
91
|
+
severity: 'block',
|
|
92
|
+
description: 'Live POST to Cloudflare siteverify with the pinned always-fail secret returns success:false; the fixture /api/submit handler rejects with 400 and refusal body carries errorCodes and no sitekey.',
|
|
93
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
94
|
+
const body = new URLSearchParams();
|
|
95
|
+
body.set('email', 'reviewer@example.com');
|
|
96
|
+
body.set('turnstile-sitekey', '2x00000000000000000000AB');
|
|
97
|
+
body.set('cf-turnstile-response', 'PACK-CHECK-FAIL-TOKEN');
|
|
98
|
+
const resp = await fetch(withUrl(runtimeUrl, '/api/submit?fail-secret=1'), {
|
|
99
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body,
|
|
100
|
+
});
|
|
101
|
+
const text = await resp.text();
|
|
102
|
+
let json = null; try { json = JSON.parse(text); } catch { /* leave null */ }
|
|
103
|
+
const ok = resp.status === 400 && json && json.errorCode === 'turnstile.siteverify-failed'
|
|
104
|
+
&& Array.isArray(json.errorCodes) && json.errorCodes.length > 0
|
|
105
|
+
&& !text.includes('2x00000000000000000000AB');
|
|
106
|
+
return {
|
|
107
|
+
verdict: ok ? 'pass' : 'fail',
|
|
108
|
+
detail: ok
|
|
109
|
+
? `serverVerified-fail: fixture rejected status=400 errorCode=turnstile.siteverify-failed errorCodes=${JSON.stringify(json.errorCodes)}; refusal body carries no sitekey`
|
|
110
|
+
: `serverVerified-fail unexpected shape status=${resp.status} body=${text}`,
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'AC-turnstile-magicLinkGuard',
|
|
116
|
+
severity: 'block',
|
|
117
|
+
description: 'Magic-link mint route composed with the Turnstile guard refuses a mint submit without a Turnstile response with 400 and refusal errorCode=turnstile.token-missing; no magic-link mint side-effect.',
|
|
118
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
119
|
+
// Two probes: (a) missing token refuse (400), (b) fail-secret refuse (400).
|
|
120
|
+
const missingBody = new URLSearchParams();
|
|
121
|
+
missingBody.set('email', 'reviewer@example.com');
|
|
122
|
+
missingBody.set('turnstile-sitekey', '1x00000000000000000000AA');
|
|
123
|
+
const missingResp = await fetch(withUrl(runtimeUrl, '/api/magic-link'), {
|
|
124
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: missingBody,
|
|
125
|
+
});
|
|
126
|
+
const missingText = await missingResp.text();
|
|
127
|
+
let missingJson = null; try { missingJson = JSON.parse(missingText); } catch {}
|
|
128
|
+
const missingOk = missingResp.status === 400 && missingJson && missingJson.errorCode === 'turnstile.token-missing';
|
|
129
|
+
|
|
130
|
+
const failBody = new URLSearchParams();
|
|
131
|
+
failBody.set('email', 'reviewer@example.com');
|
|
132
|
+
failBody.set('turnstile-sitekey', '2x00000000000000000000AB');
|
|
133
|
+
failBody.set('cf-turnstile-response', 'MAGIC-LINK-PACK-FAIL-TOKEN');
|
|
134
|
+
const failResp = await fetch(withUrl(runtimeUrl, '/api/magic-link?fail-secret=1'), {
|
|
135
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: failBody,
|
|
136
|
+
});
|
|
137
|
+
const failText = await failResp.text();
|
|
138
|
+
let failJson = null; try { failJson = JSON.parse(failText); } catch {}
|
|
139
|
+
const failOk = failResp.status === 400 && failJson && failJson.errorCode === 'turnstile.siteverify-failed';
|
|
140
|
+
|
|
141
|
+
if (missingOk && failOk) return { verdict: 'pass', detail: `magic-link guard: missing-token refused 400 turnstile.token-missing; fail-secret refused 400 turnstile.siteverify-failed errorCodes=${JSON.stringify(failJson.errorCodes)}` };
|
|
142
|
+
return { verdict: 'fail', detail: `magic-link guard unexpected: missing status=${missingResp.status} body=${missingText}; fail status=${failResp.status} body=${failText}` };
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
@@ -35,7 +35,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
35
35
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
36
36
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
37
37
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
38
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
38
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
39
39
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
40
40
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
41
41
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -43,6 +43,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
43
43
|
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
44
44
|
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
45
45
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
46
|
+
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
47
|
+
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
48
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
49
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
50
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
51
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
52
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
53
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
46
54
|
|
|
47
55
|
US 4101-4106 sit at the LOW end of the 4101-4899 band on purpose. A project-side story that mechanically derives from an email-smtp-resend REQ id into the number `4106` (leading `4` + sequence `106`) would collide against email-smtp-resend-US-4106 in this package; the band leaves headroom at the HIGH end (US 4181-4899) so a project's own stories anchored to email-smtp-resend REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
48
56
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# jobs-background changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0 - 2026-09-06
|
|
4
|
+
|
|
5
|
+
Initial release. Background-jobs discipline over an applied `queue` capability, with a job-definition contract, a POSIX-cron plus one-shot-delayed scheduler, a retry contract that inherits the applied queue's max-attempts ceiling, and a metadata-only run-log event stream at four moments. Composes on the T-5 capability-consumer mechanism from the visual round; refuses apply on a bare project with exit 3 and the stable message id `jobs-background-no-queue` per Baz decision 5. Landed via the infra round 5 spec (ratified 2026-09-06) as track T-4, chained after T-3 `messaging-queue-cloudflare` v1.0.0.
|
|
6
|
+
|
|
7
|
+
- 22 contributions: 6 REQs on `requiresAppliedCapabilities: [queue]` / job-definition / scheduler / retry / run-log / operator-facing surface; 9 USs at 30101-30109 (one per REQ plus three cross-cutting cases: apply-time refusal, scheduled fire on cron, retry-then-DLQ); 3 TACs (3101 job-definition module, 3102 scheduler, 3103 run-log event sink); 4 ADRs (3101 `scope: global` on new topic `backgroundJobModel` retry-and-schedule as the shipped shape, 3102 scheduler mode elicited across `inProcess` / `workerCron` / `external` with reserved v1.1.0 `workflows` slot per section 5.7 of the spec, 3103 requires `capabilities: ["queue"]` with `allowSkipFlag: "allow-no-queue-yet"` and refusal message id `jobs-background-no-queue`, 3104 default handler timeout 60 seconds floor 1 second ceiling bounded by the applied queue's consumer wall-clock which for Cloudflare Queues is 15 minutes per the fetched limits doc).
|
|
8
|
+
- Five Node-only probes under `contributions/probes/` proven against the T-3 in-memory queue-driver seam and a fake-clock scheduler seam (SDR-3-a on US-29107 accepts the in-memory realisation of the Cloudflare Queues binding shape as the shipped local seam): `apply-time-refusal`, `apply-time-override`, `fake-clock-cron`, `retry-and-fail`, `event-secrecy`. All five carry `accountBound: false`; the live `wrangler dev` cron-trigger path is documented as a per-AC mechanism-reach gap in the fixture README per round-3 checklist 6.g.
|
|
9
|
+
- T-4 slice of the shared sample-app fixture at `packages/rcf-lite/test/fixtures/infra-s3-and-queue/` adds a `jobs/` directory carrying two toy job-definition modules (`send-welcome-email.mjs` with `retryPolicy: { maxAttempts: 3, backoff: exponential }` and `timeoutMs: 60000`; `refresh-cache.mjs` with `retryPolicy: { maxAttempts: 5, backoff: constant }`, `timeoutMs: 10000`, `cron: '* * * * *'`), `src/jobs-runtime.mjs` realising the runtime, `src/scheduler.mjs` realising the `inProcess` scheduler with a fake-clock seam, and `src/job-run-log.mjs` realising the T-4-owned event sink (whitelist `event, jobId, jobName, attempts, duration, timestamp` plus optional `terminalErrorCode`). Two wired induced-failure switches (`SIMULATE_HANDLER_THROW`, `SIMULATE_PII_IN_JOB_INPUT`) drive the retry-and-fail and event-secrecy probe negative-run paths.
|
|
10
|
+
- Declares `capabilities: ["backgroundJobs"]`, `suggestedCompanions: [{role: "logging"}, {role: "errorHandling"}]`, `providesRoles` absent, `requiresAppliedCapabilities: { capabilities: ["queue"], allowSkipFlag: "allow-no-queue-yet", refusalMessageId: "jobs-background-no-queue" }`. The T-3 `messaging-queue-cloudflare` v1.0.0 is the shipped provider of the `queue` capability.
|
|
11
|
+
- Contributes ADR-3101 as `scope: global` on new topic `backgroundJobModel`. Future stateful-workflow siblings (Temporal-shape, Airflow-shape) will conflict here by design; the reserved round-6 Workflows adapter (per Baz section 5.7) lives INSIDE this blueprint as a v1.1.0 minor scheduler-mode value at ADR-3102, not as a sibling.
|
|
12
|
+
- Every ADR contribution entry on `blueprint.json` carries a `standardsTraceClause` per section 8a.2 (mandatory per HQ mid-flight ruling after PR #154 gate).
|
|
13
|
+
- Extends `packages/rcf-lite/docs/blueprint-authoring.md` section 6a capability-declaration table with one row for `backgroundJobs` naming the reserved stateful-workflow sibling posture per spec section 5.6.
|
|
14
|
+
- Extends `packages/rcf-lite/src/cli/blueprint.js` OPTION_SPEC with `--allow-no-queue-yet` boolean flag piped into `allowNoAuthYet` alongside `--allow-no-auth-yet` and `--allow-no-secrets-yet`, and `packages/rcf-lite/src/blueprint/apply.js` `buildOverrideNote` family derivation to detect `queue` from the flag name so the sidecar notes read "no queue yet: applied under --allow-no-queue-yet" instead of "no auth yet".
|
|
15
|
+
- Extends `packages/rcf-lite/test/blueprint/capabilities-apply.test.js` with four cases covering the queue-capability path end to end: bare-project refusal with tag and provider-name assertions, `--allow-no-queue-yet` override with queue-family sidecar-note assertion, happy path with `messaging-queue-cloudflare` applied producing `appliedCapabilities` including `queue`, and backward-compatible `--allow-no-auth-yet` also unblocks the override.
|
|
16
|
+
- Reserved v1.1.0 minor: adds `scheduler: "workflows"` mode under ADR-3102 wrapping the same job-definition contract with Cloudflare Workflows `step.do` orchestration per section 5.7 of the spec and the fetched Workflows documentation.
|