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-rate-limiting-US-36105",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-rate-limiting-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Composition with security-auth-magic-link: zone rate rule layers over the per-email application rule",
|
|
8
|
+
"asA": "operator applying both edge-cloudflare-rate-limiting and security-auth-magic-link on the same project",
|
|
9
|
+
"iWant": "the guide to name the ADR-3702 layering explicitly, showing that the zone rule refuses IP-per-URL bursts at the CF edge before they reach the origin and the security-auth-magic-link per-email application rule continues to run on requests that pass the edge gate",
|
|
10
|
+
"soThat": "I understand the composition at apply time rather than discovering that both blueprints operate on separate characteristic sets by trial and error",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-36105-1",
|
|
14
|
+
"description": "The guide contains a section titled Composition with security-auth-magic-link that names ADR-3702 explicitly, states the zone rule characteristic (IP-per-URL) and the application rule characteristic (per-email per-minute) verbatim, and shows a copy-paste example of both blueprints applied on the same project.",
|
|
15
|
+
"given": "the shipped guide at blueprints/edge-cloudflare-rate-limiting/guide/edge-cloudflare-rate-limiting.md",
|
|
16
|
+
"when": "the anatomy test scans the guide for the composition section and ADR-3702 reference",
|
|
17
|
+
"then": "the section heading, ADR-3702 reference, both characteristic strings and the copy-paste example are present",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "documentation"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3702-edge-cloudflare-rate-limiting-management-surface-doc"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-rate-limiting-US-36106",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-rate-limiting-REQ-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Manifest schema validates every rule file against the shipped JSON Schema and refuses invalid shapes",
|
|
8
|
+
"asA": "operator on the applying project committing new rate-limit rule files under the elicited manifest directory",
|
|
9
|
+
"iWant": "the shipped JSON Schema to validate every rule file's shape (the seven required fields with the correct types) and the manifest-schema-validate probe to surface any file that violates the shape",
|
|
10
|
+
"soThat": "invalid manifest changes are caught in the fixture probe rather than at operator apply time against a live zone",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-36106-1",
|
|
14
|
+
"description": "Given the shipped rate-limit-rule JSON Schema (blueprints/edge-cloudflare-rate-limiting/contributions/schemas/rate-limit-rule.schema.json, draft-07), the manifest-schema-validate probe reads every manifest file in the fixture manifest directory and validates each against the schema; every valid file passes; a manifest file with a missing threshold field (simulated via SIMULATE_SCHEMA_INVALID=true) fails validation and the probe returns aggregateVerdict: fail with the offending field named in the detail.",
|
|
15
|
+
"given": "the cf-edge fixture with the two committed manifest files and the shipped JSON Schema",
|
|
16
|
+
"when": "the manifest-schema-validate probe validates every manifest file",
|
|
17
|
+
"then": "every valid file passes; the SIMULATE_SCHEMA_INVALID=true switch surfaces the missing threshold field and the aggregate verdict is fail",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3701-edge-cloudflare-rate-limiting-manifest-schema"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-rate-limiting-US-36107",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-rate-limiting-REQ-004",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Drift-audit records carry metadata-only fields (ruleId, clientIpHash, outcome, timestamp) with no full IP, no body, no user agent",
|
|
8
|
+
"asA": "operator on the applying project reading drift-audit reports and rate-limit event records through the applied logging companion",
|
|
9
|
+
"iWant": "every drift-audit record and every rate-limit event record to carry only metadata-safe fields (ruleId, clientIpHash, outcome, timestamp, plus the drift diff fields where applicable), never a full client IP, never a request body, never a user agent string",
|
|
10
|
+
"soThat": "the audit trail is safe to store, forward and read without additional PII scrubbing at the audit sink",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-36107-1",
|
|
14
|
+
"description": "The event-secrecy probe drives a synthetic drift-audit payload constructed from a fixture rule and a fake live-zone response; every record on the sink carries only {ruleId, clientIpHash, outcome, timestamp} plus (for drift records) a diff array with the schema-safe fields; the probe asserts NO full IP (regex 4-octet dotted quad or v6 group), NO request body key, NO user-agent key; the SIMULATE_EVENT_LEAK_IP=true switch injects a full IP into the drift record and the probe returns aggregateVerdict: fail with the leaked key named in the detail.",
|
|
15
|
+
"given": "the shipped drift-audit runner and a synthetic input pair",
|
|
16
|
+
"when": "the event-secrecy probe drives the runner and inspects the resulting records",
|
|
17
|
+
"then": "every record carries only the metadata-safe fields; SIMULATE_EVENT_LEAK_IP=true surfaces a leaked key and the aggregate verdict is fail",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3703-edge-cloudflare-rate-limiting-drift-audit-runner"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "edge-cloudflare-rate-limiting-US-36108",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "edge-cloudflare-rate-limiting-REQ-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Manifest-presence probe refuses a missing manifest file and names the missing file in the detail",
|
|
8
|
+
"asA": "operator on the applying project accidentally deleting or moving a manifest file under the elicited manifest directory",
|
|
9
|
+
"iWant": "the manifest-presence probe to surface the missing file at fixture probe time rather than at operator apply time against a live zone",
|
|
10
|
+
"soThat": "a manifest under-population defect is caught in the CI probe rather than lingering until an operator notices a missing rule at the dashboard",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-36108-1",
|
|
14
|
+
"description": "Given the cf-edge fixture with the SIMULATE_MANIFEST_MISSING=true switch, one committed manifest file is treated as absent by the probe; the manifest-presence probe returns aggregateVerdict: fail with the missing file's basename named in the detail; without the switch the probe passes and both manifest files are inspected.",
|
|
15
|
+
"given": "the cf-edge fixture with two committed manifest files and the SIMULATE_MANIFEST_MISSING=true switch",
|
|
16
|
+
"when": "the manifest-presence probe scans the fixture manifest directory",
|
|
17
|
+
"then": "the probe returns aggregateVerdict: fail and the missing file basename is present in the detail",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": [
|
|
23
|
+
"TAC-3701-edge-cloudflare-rate-limiting-manifest-schema"
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# edge-cloudflare-rate-limiting blueprint coordination vocabulary
|
|
2
|
+
|
|
3
|
+
This file is the edge-cloudflare-rate-limiting 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-rate-limiting contribution | Origin | Composition note |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `edgeThrottleContract` | ADR-3701-edge-cloudflare-rate-limiting-throttle-contract | Minted by this blueprint. Names the wire-shape contract for the project-wide edge throttle; the shipped answer is Cloudflare WAF rate-limiting rules per `https://developers.cloudflare.com/waf/rate-limiting-rules/`. | The one project-wide decision on the edge throttle at the shipped-shape boundary. A future non-Cloudflare sibling (Fastly rate-limits, Vercel Edge Config throttles) 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-rate-limiting blueprint claims one global topic (minted here, shipped as the Cloudflare WAF rate-limiting rules manifest and drift-audit). ADR-3702 layering, ADR-3703 manifest shape and ADR-3704 drift-audit cadence 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 36101-36108 sit at the LOW end of the 36101-36899 band on purpose (watchpost run-4 lesson). ADR/TAC suffixes for this blueprint use the 3701-3799 block, continuing the shelf pattern.
|
|
60
|
+
|
|
61
|
+
## Shared expectations for future composing blueprints
|
|
62
|
+
|
|
63
|
+
- Reuse `edgeThrottleContract` exactly as spelled here when your blueprint holds an opinion on the edge throttle contract; contribute your own scope:global ADR on that string and let composition surface the pairing.
|
|
64
|
+
- Consumer blueprints reading the `edgeRateLimit` capability declared on `blueprint.json` per section 6a of `blueprint-authoring.md` obtain the shipped rate-limit surface at apply time via the capability-declaration mechanism.
|
|
65
|
+
|
|
66
|
+
## Deliberate-conflict statement
|
|
67
|
+
|
|
68
|
+
This blueprint's ADR-3701 on `edgeThrottleContract` is the first shipped answer to a topic that will conflict, by design, with future non-Cloudflare siblings. Applying `edge-cloudflare-rate-limiting` 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,88 @@
|
|
|
1
|
+
# edge-cloudflare-rate-limiting guide
|
|
2
|
+
|
|
3
|
+
Round 6 T-6 of the Cloudflare-first blueprint line. Ships zone-level rate limiting as an edge gate in front of Worker handlers. The rule set is a local manifest the applying project commits, and an operator applies it to the live Cloudflare zone through either a wrangler command flow or the Cloudflare dashboard flow, both walked below.
|
|
4
|
+
|
|
5
|
+
## Manifest
|
|
6
|
+
|
|
7
|
+
The applying project holds its rate-limit rule set as one JSON file per rule under the elicited `rate-limit-rules-dir` (default `cloudflare/rate-limits/`) per ADR-3703. Every file matches the shipped JSON Schema (`contributions/schemas/rate-limit-rule.schema.json`, draft-07) and carries the seven Cloudflare WAF rate-limiting rules documented fields per `https://developers.cloudflare.com/waf/rate-limiting-rules/`.
|
|
8
|
+
|
|
9
|
+
Example (`cloudflare/rate-limits/public-api-per-ip.json`):
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
{
|
|
13
|
+
"id": "public-api-per-ip",
|
|
14
|
+
"expression": "(http.request.uri.path matches \"^/api/\")",
|
|
15
|
+
"threshold": 60,
|
|
16
|
+
"period": 60,
|
|
17
|
+
"characteristics": ["ip.src", "cf.colo.id"],
|
|
18
|
+
"action": "block",
|
|
19
|
+
"duration": 60,
|
|
20
|
+
"description": "Per-IP-per-colo throttle on /api/*; the (N+1)th request in 60s is blocked for 60s."
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The zone id is elicited (`rate-limit-zone-id`) and stored through the applied `secretsManagement` companion; a manifest file never inlines a zone id or an API token.
|
|
25
|
+
|
|
26
|
+
## Management surface
|
|
27
|
+
|
|
28
|
+
The blueprint ships no committed script that writes rules to the live zone. The operator applies each rule through one of two documented flows, or both. The elicited `rate-limit-management-surface` value records the choice.
|
|
29
|
+
|
|
30
|
+
### wrangler flow
|
|
31
|
+
|
|
32
|
+
The wrangler flow uses the Cloudflare API through a hand-run command sequence. The steps for one rule are:
|
|
33
|
+
|
|
34
|
+
1. Set `CLOUDFLARE_API_TOKEN` (and `CLOUDFLARE_ACCOUNT_ID` for the account scope) in the operator's environment. Store both through the applied `secretsManagement` companion; never commit them to the git tree.
|
|
35
|
+
2. Load the elicited zone id: `export CF_ZONE_ID=$(cat rcf/blueprints/edge-cloudflare-rate-limiting.applied.json | jq -r .elicits.rateLimitZoneId)` or read it from the applied vault seam.
|
|
36
|
+
3. Fetch the existing rate-limiting ruleset id for the zone via the wrangler-installed API-fetch helper: `wrangler api curl "/zones/${CF_ZONE_ID}/rulesets?phase=http_ratelimit" --method GET` and note the `id` on the returned ruleset (create one if none exists per the vendor doc).
|
|
37
|
+
4. For each rule file, `POST` the rule shape to the ruleset's `/rules` endpoint. The rule body is built from the manifest file by mapping each field one-to-one: `expression`, `action`, and a `ratelimit` object carrying `characteristics`, `period`, `requests_per_period` (from `threshold`), and `mitigation_timeout` (from `duration`).
|
|
38
|
+
5. Verify by listing the ruleset again and confirming every manifest rule appears with the expected fields.
|
|
39
|
+
|
|
40
|
+
The vendor doc `https://developers.cloudflare.com/waf/rate-limiting-rules/` names the endpoint shape verbatim; the wrangler flow is a hand-run reproduction of that shape.
|
|
41
|
+
|
|
42
|
+
### Cloudflare dashboard flow
|
|
43
|
+
|
|
44
|
+
The dashboard flow applies each rule through the Cloudflare zone dashboard. The steps for one rule are:
|
|
45
|
+
|
|
46
|
+
1. Open the target zone in the Cloudflare dashboard.
|
|
47
|
+
2. Navigate to Security -> WAF -> Rate limiting rules.
|
|
48
|
+
3. Click Create rule; give the rule the manifest file's `id` as the operator-facing name.
|
|
49
|
+
4. In When incoming requests match, set the Custom filter expression to the manifest `expression` (Edit expression toggle to paste raw).
|
|
50
|
+
5. In Then take action, set the action to the manifest `action` (Block, Managed challenge, JS challenge or Log). Set the Duration to the manifest `duration` in seconds.
|
|
51
|
+
6. In With the following properties, set the counting period to the manifest `period` seconds, the requests per period to the manifest `threshold`, and the characteristics to the manifest `characteristics` array (each string mapped to the dashboard's Same request property selectors).
|
|
52
|
+
7. Save the rule. Repeat for every file in the manifest directory.
|
|
53
|
+
|
|
54
|
+
Both flows produce the same shape on the live zone; the operator picks the flow that fits the project's operating discipline. The elicited `rate-limit-management-surface` records which flow the operator committed to at apply time.
|
|
55
|
+
|
|
56
|
+
## Composition with security-auth-magic-link
|
|
57
|
+
|
|
58
|
+
Per ADR-3702, when both `edge-cloudflare-rate-limiting` and `security-auth-magic-link` apply on the same project, the zone-level rate rule layers OVER the per-email application rule. The two rules operate on different characteristic sets and are additive:
|
|
59
|
+
|
|
60
|
+
| Rule | Characteristic set | Where it runs |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| Zone rule (this blueprint) | IP-per-URL (e.g. `ip.src` + `http.request.uri.path`) | Cloudflare edge, before any origin Worker code |
|
|
63
|
+
| Application rule (magic-link) | per-email per-minute | Origin Worker mint-surface handler |
|
|
64
|
+
|
|
65
|
+
Copy-paste example (applying both blueprints in the same project):
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
rcf define blueprint add ./blueprints/edge-cloudflare-rate-limiting \
|
|
69
|
+
--answer rate-limit-rules-dir=cloudflare/rate-limits \
|
|
70
|
+
--answer rate-limit-zone-id=<vault-ref> \
|
|
71
|
+
--answer rate-limit-management-surface=both \
|
|
72
|
+
--answer rate-limit-drift-audit-cadence=daily
|
|
73
|
+
|
|
74
|
+
rcf define blueprint add ./blueprints/security-auth-magic-link \
|
|
75
|
+
--answer magic-link-mint-rate-limit=5perMinute
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The applied recorder records both blueprints so the operator sees the two-rule shape at apply time.
|
|
79
|
+
|
|
80
|
+
## Drift audit
|
|
81
|
+
|
|
82
|
+
The blueprint ships a scheduled drift-audit runner realisation in the `cf-edge` fixture at `packages/rcf-lite/test/fixtures/cf-edge/src/drift-audit-runner.mjs`. The runner exports `createDriftAuditRunner({env, eventSink, fetch, clock, cadence, manifestLoader})` per TAC-3703 and fetches the live rules on the elicited zone via `https://api.cloudflare.com/client/v4/zones/{zone_id}/rulesets`, diffs field-by-field against the local manifest, and constructs one drift-audit record per mismatched rule with the metadata-only shape `{ruleId, clientIpHash, outcome, timestamp, diff}`. No record carries a full client IP, a request body or a user agent (event-secrecy discipline per REQ-005 and AC-36107-1).
|
|
83
|
+
|
|
84
|
+
The elicited `rate-limit-drift-audit-cadence` per ADR-3704 picks `off` (runner not wired), `daily` (24-hour cadence, `recommendedDefault`), or `hourly`.
|
|
85
|
+
|
|
86
|
+
## Runtime observable and CI
|
|
87
|
+
|
|
88
|
+
Per spec section 3.1 and ruling 6, the runtime observable for `AC-rateLimiting-overThresholdBlocks` (US-36103/AC-36103-1) is the real-account burst probe. In CI without `CI_HAS_CLOUDFLARE_ACCOUNT` and `CF_RATE_LIMIT_URL`, the probe records `accountBoundSkipped: true` and aggregates to `pass`; this IS the accepted CI verdict. The three local probes (manifest presence, manifest schema validate, event secrecy) always run and always gate the ship.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `edge-cloudflare-turnstile` are recorded here. The shape follows Keep a Changelog and Semantic Versioning per the blueprint authoring standard.
|
|
4
|
+
|
|
5
|
+
## 1.0.0 (2026-09-07)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- v1.0.0 mint of the `edge-cloudflare-turnstile` blueprint, category `edge`, capabilities `["humanCheck"]`. Ships a client widget mount, a server-side siteverify verifier that POSTs to `https://challenges.cloudflare.com/turnstile/v0/siteverify` with the elicited secret, a refuse-if-token-missing guard on every elicited surface, and a composition hook into `security-auth-magic-link` mint surface.
|
|
10
|
+
- 5 REQs (`edge-cloudflare-turnstile-REQ-001..005`), 8 USs (`edge-cloudflare-turnstile-US-35101..35108`), 3 TACs (`TAC-3601` widget mount, `TAC-3602` server verifier plus token-required guard, `TAC-3603` magic-link hook), 3 ADRs (`ADR-3601` scope-global on new topic `humanVerificationGate` with `standardsTraceClause: Cloudflare Turnstile siteverify endpoint documented shape`; `ADR-3602` widget mode enum elicit with `recommendedDefault: managed`; `ADR-3603` refuse shape 400 with error-code body and no sitekey leak).
|
|
11
|
+
- 4 Node-only probes under `contributions/probes/`: `secret-shape-scan` (source-tree AST scan asserts `TURNSTILE_SECRET` is only read through the env facade and refuses non-test secret literals), `siteverify-fixture` (drives the LIVE `challenges.cloudflare.com/turnstile/v0/siteverify` endpoint with the pinned always-pass and always-fail Cloudflare test secrets and asserts `success:true` and `success:false` respectively), `guard-shape-scan` (source scan plus live missing-token POST against every guarded surface), `event-secrecy` (asserts every event record carries `{sitekeyHash, outcome, timestamp}` keys only; no token, no secret leak).
|
|
12
|
+
- 1 Playwright probe pack (`probe-packs/edge-cloudflare-turnstile.pack.mjs`) with 4 surface-observable checks per spec section 3.2: `AC-turnstile-widgetRendered` (widget mounts, iframe/script from the Cloudflare Turnstile origin only, `cf-turnstile-response` token populated, no third-party script), `AC-turnstile-serverVerified-pass` (`/api/submit` 200 on always-pass secret), `AC-turnstile-serverVerified-fail` (`/api/submit` 400 on always-fail secret with `errorCodes` and no sitekey leak), `AC-turnstile-magicLinkGuard` (mint refuses missing-token and always-fail-secret with 400 and no mint side-effect).
|
|
13
|
+
- 4 elicited parameters on `blueprint.json`: `turnstile-sitekey`, `turnstile-secret` (routed through `security-secrets-management` when applied), `turnstile-widget-mode` (enum default `managed`), `turnstile-guarded-surfaces`.
|
|
14
|
+
- `suggestedCompanions`: `logging` (for the metadata-only event sink retention), `errorHandling` (for the verifier failure boundary), `secretsManagement` (for the paired sitekey and secret).
|
|
15
|
+
- Ships the dedicated pack fixture at `packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile/` per spec section 3.3. The fixture pins the Cloudflare public test keys documented at `https://developers.cloudflare.com/turnstile/troubleshooting/testing/` as environment defaults so the pack runs without real Turnstile credentials.
|
|
16
|
+
- Anatomy test at `packages/rcf-lite/test/blueprint/edge-cloudflare-turnstile-anatomy.test.js` covers TS-120..127 on the T-5 repo-chain slice.
|
|
17
|
+
|
|
18
|
+
### Known limitations
|
|
19
|
+
|
|
20
|
+
- No account-bound probe. Cloudflare Turnstile documents its endpoint and test keys as public; the live siteverify calls in the shipped probes route through Cloudflare with no operator account required. A real-account variant would gate on a specific applying-project sitekey and secret pair; the shipped test-key runs cover the wire-shape contract.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# edge-cloudflare-turnstile
|
|
2
|
+
|
|
3
|
+
Cloudflare Turnstile as a CAPTCHA-alternative on public-facing forms. Ships the client widget mount, the server-side siteverify verifier (POST to `https://challenges.cloudflare.com/turnstile/v0/siteverify` with the elicited secret), a refuse-if-token-missing guard on every elicited surface, and a composition hook into the `security-auth-magic-link` mint surface.
|
|
4
|
+
|
|
5
|
+
- Slug: `edge-cloudflare-turnstile`
|
|
6
|
+
- Category: `edge`
|
|
7
|
+
- Version: `1.0.0`
|
|
8
|
+
- Capabilities: `["humanCheck"]`
|
|
9
|
+
- Standards: Cloudflare Turnstile (`https://developers.cloudflare.com/turnstile/`), Cloudflare Turnstile testing (`https://developers.cloudflare.com/turnstile/troubleshooting/testing/`)
|
|
10
|
+
|
|
11
|
+
## What this blueprint commits
|
|
12
|
+
|
|
13
|
+
| REQ | Commits |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `edge-cloudflare-turnstile-REQ-001` | Client widget mount: the elicited sitekey renders the Turnstile widget; the mount injects no third-party script beyond the Cloudflare Turnstile JS host. |
|
|
16
|
+
| `edge-cloudflare-turnstile-REQ-002` | Server-side siteverify: POST to `https://challenges.cloudflare.com/turnstile/v0/siteverify` with the elicited secret; on `success:true` the handler proceeds; on `success:false` the handler rejects with 400. |
|
|
17
|
+
| `edge-cloudflare-turnstile-REQ-003` | Refuse-if-token-missing guard on elicited surfaces: a submit without a token rejects with 400 before hitting downstream logic. |
|
|
18
|
+
| `edge-cloudflare-turnstile-REQ-004` | Composition with `security-auth-magic-link`: when both are applied, the magic-link mint surface refuses a submit without a valid Turnstile token. |
|
|
19
|
+
| `edge-cloudflare-turnstile-REQ-005` | Widget mode is an elicited enum: `managed`, `non-interactive`, `invisible` per Cloudflare's documented modes. `recommendedDefault: managed`. |
|
|
20
|
+
|
|
21
|
+
## Contract at a glance
|
|
22
|
+
|
|
23
|
+
- **Client widget mount** (TAC-3601) injects Cloudflare Turnstile JS from `https://challenges.cloudflare.com` and no other origin; renders the widget for the elicited sitekey; populates the hidden `Cf-Turnstile-Response` token field on submit.
|
|
24
|
+
- **Server-side siteverify verifier** (TAC-3602) POSTs `{secret, response}` to `https://challenges.cloudflare.com/turnstile/v0/siteverify`. On `success:true` the handler proceeds. On `success:false` the handler rejects with 400 and the refusal body carries the documented `error-codes` value; the sitekey is never in the refusal body.
|
|
25
|
+
- **Refuse-if-token-missing guard** (TAC-3602) is the sole reader of the `Cf-Turnstile-Response` payload field; a submit without a token rejects with `400 {"errorCode":"turnstile.token-missing"}` before any downstream handler runs.
|
|
26
|
+
- **Composition with security-auth-magic-link** (TAC-3603) registers the magic-link mint route under the Turnstile guard so a mint submit reads through the same token check.
|
|
27
|
+
- **Widget mode** (ADR-3602) is an elicited enum: `managed`, `non-interactive`, `invisible`. Default: `managed`.
|
|
28
|
+
|
|
29
|
+
## Elicited parameters
|
|
30
|
+
|
|
31
|
+
| Id | Purpose |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `turnstile-sitekey` | Cloudflare Turnstile sitekey the widget renders with. Public per Cloudflare's testing docs when a test sitekey is applied. |
|
|
34
|
+
| `turnstile-secret` | Cloudflare Turnstile secret the server-side verifier POSTs with. Delegated to `security-secrets-management` when applied. |
|
|
35
|
+
| `turnstile-widget-mode` | Enum `managed` \| `non-interactive` \| `invisible`. `recommendedDefault: managed`. |
|
|
36
|
+
| `turnstile-guarded-surfaces` | List of applied route ids the token-required guard registers on. |
|
|
37
|
+
|
|
38
|
+
## Companions
|
|
39
|
+
|
|
40
|
+
- **`suggestedCompanions[logging]`**: every siteverify call and every refuse-if-token-missing rejection writes through the applied logger.
|
|
41
|
+
- **`suggestedCompanions[errorHandling]`**: siteverify network failure, malformed token, missing sitekey/secret build an internal error record.
|
|
42
|
+
- **`suggestedCompanions[secretsManagement]`**: the paired sitekey and secret are stored in the operator's applied `secretsManagement` companion.
|
|
43
|
+
|
|
44
|
+
## Composition
|
|
45
|
+
|
|
46
|
+
- Consumes `security-secrets-management` for the sitekey/secret pair when applied.
|
|
47
|
+
- Composes with `security-auth-magic-link` at the mint surface via `TAC-3603`.
|
|
48
|
+
- Provides capability `humanCheck` per section 6a of `blueprint-authoring.md`.
|
|
49
|
+
- One scope-global ADR (`ADR-3601`) on new topic `humanVerificationGate`. A future hCaptcha or reCAPTCHA sibling contributes the same topic string with a different answer and forces a deliberate operator-resolved conflict.
|
|
50
|
+
|
|
51
|
+
## Probes and pack
|
|
52
|
+
|
|
53
|
+
Four Node-only probes under `contributions/probes/`:
|
|
54
|
+
|
|
55
|
+
| Probe | Anchors | Engine |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `secret-shape-scan` | `AC-35107-1` | Source-tree AST scan over the pack fixture. |
|
|
58
|
+
| `siteverify-fixture` | `AC-35102-1` | Live POST to `https://challenges.cloudflare.com/turnstile/v0/siteverify` with pinned Cloudflare public test secrets. |
|
|
59
|
+
| `guard-shape-scan` | `AC-35104-1` | Source-tree scan plus a live missing-token POST against every guarded surface. |
|
|
60
|
+
| `event-secrecy` | `AC-35108-1` | Live pass + fail runs through the verifier; asserts every event carries `sitekeyHash`, `outcome`, `timestamp` and no token or secret substring. |
|
|
61
|
+
|
|
62
|
+
One Playwright pack at `probe-packs/edge-cloudflare-turnstile.pack.mjs` with four surface-observable checks: `AC-turnstile-widgetRendered`, `AC-turnstile-serverVerified-pass`, `AC-turnstile-serverVerified-fail`, `AC-turnstile-magicLinkGuard`. The pack ships no `appliesTo` gate; every fixture that applies the blueprint fires every check.
|
|
63
|
+
|
|
64
|
+
The dedicated pack fixture at `packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile/` pins the Cloudflare public test keys (documented at `https://developers.cloudflare.com/turnstile/troubleshooting/testing/`) as environment defaults so the pack runs without real Turnstile credentials.
|
|
65
|
+
|
|
66
|
+
## Pinned Cloudflare public test keys
|
|
67
|
+
|
|
68
|
+
Per Cloudflare's testing page (`https://developers.cloudflare.com/turnstile/troubleshooting/testing/`):
|
|
69
|
+
|
|
70
|
+
| Sitekey | Behaviour |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `1x00000000000000000000AA` | Always passes |
|
|
73
|
+
| `2x00000000000000000000AB` | Always blocks |
|
|
74
|
+
| `3x00000000000000000000FF` | Forces an interactive challenge |
|
|
75
|
+
| `1x00000000000000000000BB` | Invisible widget, always passes |
|
|
76
|
+
| `2x00000000000000000000BB` | Invisible widget, always blocks |
|
|
77
|
+
|
|
78
|
+
| Secret | Behaviour |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `1x0000000000000000000000000000000AA` | Always passes on siteverify |
|
|
81
|
+
| `2x0000000000000000000000000000000AA` | Always fails on siteverify |
|
|
82
|
+
| `3x0000000000000000000000000000000AA` | Token already spent |
|
|
83
|
+
|
|
84
|
+
These keys are public per Cloudflare's documentation; they are safe to pin as fixture defaults and are not operational secrets.
|
|
85
|
+
|
|
86
|
+
## Risks
|
|
87
|
+
|
|
88
|
+
1. Client-side widget mounts a third-party script. The `AC-turnstile-widgetRendered` pack check pins the mount to `https://challenges.cloudflare.com` only and fails if any other origin is contacted (see the `?break=other-origin` negative proof in the fixture `proof/` directory).
|
|
89
|
+
2. Test sitekeys are the only always-green option for CI. The guide names the pass, block and forced-interactive modes per Cloudflare's testing page so an operator can pick a mode for staging.
|
|
90
|
+
|
|
91
|
+
## Standards trace
|
|
92
|
+
|
|
93
|
+
- Cloudflare Turnstile: `https://developers.cloudflare.com/turnstile/`
|
|
94
|
+
- Cloudflare Turnstile testing: `https://developers.cloudflare.com/turnstile/troubleshooting/testing/`
|
|
95
|
+
- Cloudflare Turnstile siteverify endpoint: `https://challenges.cloudflare.com/turnstile/v0/siteverify`
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "edge-cloudflare-turnstile",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "edge",
|
|
5
|
+
"capabilities": [
|
|
6
|
+
"humanCheck"
|
|
7
|
+
],
|
|
8
|
+
"suggestedCompanions": [
|
|
9
|
+
{
|
|
10
|
+
"role": "logging",
|
|
11
|
+
"reason": "Every siteverify call and every refuse-if-token-missing rejection writes through the applied logger; a logging companion supplies the sink factory."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"role": "errorHandling",
|
|
15
|
+
"reason": "A siteverify network failure, a malformed token or a missing sitekey and secret constructs an internal error record; an error-handling companion supplies the record factory and the boundary."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"role": "secretsManagement",
|
|
19
|
+
"reason": "The paired TURNSTILE_SITEKEY and TURNSTILE_SECRET are stored in the operator applied secretsManagement companion; the applied vault seam receives the elicited values at apply time and injects them at deploy."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"elicits": [
|
|
23
|
+
{
|
|
24
|
+
"id": "turnstile-sitekey",
|
|
25
|
+
"prompt": "Cloudflare Turnstile sitekey the widget renders with. See https://developers.cloudflare.com/turnstile/ for issuing. Test sitekeys are pinned in the shipped fixture per https://developers.cloudflare.com/turnstile/troubleshooting/testing/.",
|
|
26
|
+
"kind": "string",
|
|
27
|
+
"default": ""
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "turnstile-secret",
|
|
31
|
+
"prompt": "Cloudflare Turnstile secret the server-side verifier posts to siteverify with. Never inline; stored via the applied secretsManagement companion or your environment.",
|
|
32
|
+
"kind": "string",
|
|
33
|
+
"default": ""
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "turnstile-widget-mode",
|
|
37
|
+
"prompt": "Cloudflare Turnstile widget mode per ADR-3602 and https://developers.cloudflare.com/turnstile/. managed (recommendedDefault; Cloudflare decides when to show the challenge); non-interactive (always shows a non-interactive challenge); invisible (mounts an invisible widget).",
|
|
38
|
+
"kind": "enum",
|
|
39
|
+
"options": [
|
|
40
|
+
"managed",
|
|
41
|
+
"non-interactive",
|
|
42
|
+
"invisible"
|
|
43
|
+
],
|
|
44
|
+
"default": "managed"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "turnstile-guarded-surfaces",
|
|
48
|
+
"prompt": "List of applied route ids the token-required guard registers on. Every guarded surface refuses missing-token submits with 400 before any downstream handler runs.",
|
|
49
|
+
"kind": "string",
|
|
50
|
+
"default": ""
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"contributions": [
|
|
54
|
+
{
|
|
55
|
+
"id": "edge-cloudflare-turnstile-REQ-001",
|
|
56
|
+
"kind": "req",
|
|
57
|
+
"path": "requirements/edge-cloudflare-turnstile-req-001.json"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "edge-cloudflare-turnstile-REQ-002",
|
|
61
|
+
"kind": "req",
|
|
62
|
+
"path": "requirements/edge-cloudflare-turnstile-req-002.json"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "edge-cloudflare-turnstile-REQ-003",
|
|
66
|
+
"kind": "req",
|
|
67
|
+
"path": "requirements/edge-cloudflare-turnstile-req-003.json"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "edge-cloudflare-turnstile-REQ-004",
|
|
71
|
+
"kind": "req",
|
|
72
|
+
"path": "requirements/edge-cloudflare-turnstile-req-004.json"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "edge-cloudflare-turnstile-REQ-005",
|
|
76
|
+
"kind": "req",
|
|
77
|
+
"path": "requirements/edge-cloudflare-turnstile-req-005.json"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "edge-cloudflare-turnstile-US-35101",
|
|
81
|
+
"kind": "us",
|
|
82
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35101.json"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "edge-cloudflare-turnstile-US-35102",
|
|
86
|
+
"kind": "us",
|
|
87
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35102.json"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "edge-cloudflare-turnstile-US-35103",
|
|
91
|
+
"kind": "us",
|
|
92
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35103.json"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "edge-cloudflare-turnstile-US-35104",
|
|
96
|
+
"kind": "us",
|
|
97
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35104.json"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "edge-cloudflare-turnstile-US-35105",
|
|
101
|
+
"kind": "us",
|
|
102
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35105.json"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "edge-cloudflare-turnstile-US-35106",
|
|
106
|
+
"kind": "us",
|
|
107
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35106.json"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "edge-cloudflare-turnstile-US-35107",
|
|
111
|
+
"kind": "us",
|
|
112
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35107.json"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "edge-cloudflare-turnstile-US-35108",
|
|
116
|
+
"kind": "us",
|
|
117
|
+
"path": "user-stories/edge-cloudflare-turnstile-us-35108.json"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "TAC-3601-edge-cloudflare-turnstile-widget-mount",
|
|
121
|
+
"kind": "tac",
|
|
122
|
+
"path": "tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "TAC-3602-edge-cloudflare-turnstile-server-verifier",
|
|
126
|
+
"kind": "tac",
|
|
127
|
+
"path": "tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "TAC-3603-edge-cloudflare-turnstile-magic-link-hook",
|
|
131
|
+
"kind": "tac",
|
|
132
|
+
"path": "tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "ADR-3601-edge-cloudflare-turnstile-verifier-contract",
|
|
136
|
+
"kind": "adr",
|
|
137
|
+
"path": "adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json",
|
|
138
|
+
"scope": "global",
|
|
139
|
+
"topic": "humanVerificationGate",
|
|
140
|
+
"recommendedDefault": true,
|
|
141
|
+
"elicited": false,
|
|
142
|
+
"standardsTraceClause": "Cloudflare Turnstile siteverify endpoint documented shape"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "ADR-3602-edge-cloudflare-turnstile-widget-mode",
|
|
146
|
+
"kind": "adr",
|
|
147
|
+
"path": "adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json",
|
|
148
|
+
"recommendedDefault": true,
|
|
149
|
+
"elicited": true,
|
|
150
|
+
"standardsTraceClause": "Cloudflare Turnstile documented widget modes"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "ADR-3603-edge-cloudflare-turnstile-refuse-shape",
|
|
154
|
+
"kind": "adr",
|
|
155
|
+
"path": "adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json",
|
|
156
|
+
"recommendedDefault": true,
|
|
157
|
+
"elicited": false,
|
|
158
|
+
"standardsTraceClause": "Cloudflare Turnstile documented error codes"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3601-edge-cloudflare-turnstile-verifier-contract",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Human verification gate: Cloudflare Turnstile with server-side siteverify (scope global, new topic humanVerificationGate)",
|
|
8
|
+
"context": "An applying project that mounts a public-facing form (contact, subscribe, magic-link mint, low-cost-per-request public API) needs a human verification gate that keeps unattended bots off the form. Cloudflare Turnstile is the CF-native answer: a client widget that emits a response token and a server-side siteverify endpoint (https://challenges.cloudflare.com/turnstile/v0/siteverify) that returns success:true or success:false with error-codes per https://developers.cloudflare.com/turnstile/. Every applied Worker needs one project-wide answer to the humanVerificationGate topic; a future non-Cloudflare sibling (hCaptcha, reCAPTCHA) would conflict on the same topic by design.",
|
|
9
|
+
"decision": "The shipped v1.0.0 default is Cloudflare Turnstile with server-side siteverify. The verifier POSTs {secret, response} to https://challenges.cloudflare.com/turnstile/v0/siteverify per the Cloudflare Turnstile documented endpoint shape. On success:true the handler proceeds; on success:false the handler rejects 400 with the error-codes value in the refusal body. The humanVerificationGate topic scope is global on this blueprint; the topic string is humanVerificationGate (lower camel case, one concept per topic, no version suffix). Standards trace clause: Cloudflare Turnstile siteverify endpoint documented shape.",
|
|
10
|
+
"consequences": "The applying project inherits Cloudflare Turnstile documented widget-and-siteverify contract per https://developers.cloudflare.com/turnstile/. A future hCaptcha or reCAPTCHA sibling contributes the same humanVerificationGate topic with a different answer, forcing a DELIBERATE operator-resolved conflict at the project ADR level. The pack fixture pins Cloudflare public test keys per https://developers.cloudflare.com/turnstile/troubleshooting/testing/ so the pack does not need real Turnstile credentials to run.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3602-edge-cloudflare-turnstile-widget-mode",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Widget mode is elicited as an enum (managed, non-interactive, invisible); recommendedDefault managed",
|
|
8
|
+
"context": "Cloudflare Turnstile documents three widget modes per https://developers.cloudflare.com/turnstile/: managed (Cloudflare decides when to show a challenge, minimising user friction), non-interactive (always renders a non-interactive challenge for uniform behaviour) and invisible (mounts an invisible widget). Each mode is a per-surface operational profile; the elicit forces the operator to name the intent.",
|
|
9
|
+
"decision": "Widget mode is elicited (elicited: true). Values: managed, non-interactive, invisible per Cloudflare Turnstile documented modes. recommendedDefault: managed. The applied-sidecar records the operator answer per applying surface. Standards trace clause: Cloudflare Turnstile documented widget modes.",
|
|
10
|
+
"consequences": "The elicitation forces an explicit answer on every apply. The pack fixture accepts ?mode=<managed|non-interactive|invisible> and pins the invisible-widget test sitekeys (1x00000000000000000000BB and 2x00000000000000000000BB per https://developers.cloudflare.com/turnstile/troubleshooting/testing/) alongside the managed pass/fail sitekeys so every mode is exercised on the gate.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3603-edge-cloudflare-turnstile-refuse-shape",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Refuse-if-token-missing status is 400 with an error-code body (no sitekey leak); siteverify failure carries the documented error-codes value",
|
|
8
|
+
"context": "Cloudflare Turnstile siteverify returns {success: false, error-codes: [...]} on failure per https://developers.cloudflare.com/turnstile/. The applying project needs a stable refusal shape that never leaks the sitekey, the secret or the response token into an error body or event record.",
|
|
9
|
+
"decision": "Refuse-if-token-missing status is 400. Refusal body carries a stable error-code: turnstile.token-missing for the guard branch, or the Cloudflare error-codes[0] for the siteverify-failure branch. Refusal body never carries the sitekey, the secret or the response token value. Standards trace clause: Cloudflare Turnstile documented error codes.",
|
|
10
|
+
"consequences": "The 400 status is machine-observable at every applied surface; downstream observability records the outcome by error-code, not by sitekey. Event records ship {sitekeyHash, outcome, timestamp} only; the event-secrecy probe asserts this shape (AC-35108-1).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T20:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T20:00:00.000Z"
|
|
14
|
+
}
|