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,174 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "edge-cloudflare-rate-limiting",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "edge",
|
|
5
|
+
"capabilities": [
|
|
6
|
+
"edgeRateLimit"
|
|
7
|
+
],
|
|
8
|
+
"suggestedCompanions": [
|
|
9
|
+
{
|
|
10
|
+
"role": "logging",
|
|
11
|
+
"reason": "Every drift-audit report and every rate-limit event writes through the applied logger; a logging companion supplies the sink factory."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"role": "errorHandling",
|
|
15
|
+
"reason": "A drift-audit failure, a Cloudflare API error, a manifest schema violation constructs an internal error record; an error-handling companion supplies the record factory and the boundary."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"role": "secretsManagement",
|
|
19
|
+
"reason": "The Cloudflare API token that the drift-audit runner and any wrangler-based apply flow use is stored via the applied secretsManagement companion; the elicited zone id may also be projected through the vault when the operator wants a single source of truth."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"elicits": [
|
|
23
|
+
{
|
|
24
|
+
"id": "rate-limit-rules-dir",
|
|
25
|
+
"prompt": "Directory the applying project commits its rate-limit rule manifest files into. One file per rule per ADR-3703. The manifest is source-of-truth; the operator applies it via wrangler or the Cloudflare dashboard per REQ-002.",
|
|
26
|
+
"kind": "string",
|
|
27
|
+
"default": "cloudflare/rate-limits"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "rate-limit-zone-id",
|
|
31
|
+
"prompt": "Cloudflare zone id the rules apply to. Never inline in a rule manifest; store via the applied secretsManagement companion and reference at apply time. Empty string leaves the zone id unresolved (the drift audit and any wrangler flow surface the omission).",
|
|
32
|
+
"kind": "string",
|
|
33
|
+
"default": ""
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "rate-limit-management-surface",
|
|
37
|
+
"prompt": "Operator-facing management surface per REQ-002 and TAC-3702. wrangler names the command flow the guide walks through; dashboard names the Cloudflare dashboard flow; both records both flows and lets the operator pick per rule.",
|
|
38
|
+
"kind": "enum",
|
|
39
|
+
"options": [
|
|
40
|
+
"wrangler",
|
|
41
|
+
"dashboard",
|
|
42
|
+
"both"
|
|
43
|
+
],
|
|
44
|
+
"default": "both"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "rate-limit-drift-audit-cadence",
|
|
48
|
+
"prompt": "Drift-audit cadence per ADR-3704. off disables the runner; daily runs it every 24 hours; hourly runs it every hour. daily is the recommended default.",
|
|
49
|
+
"kind": "enum",
|
|
50
|
+
"options": [
|
|
51
|
+
"off",
|
|
52
|
+
"daily",
|
|
53
|
+
"hourly"
|
|
54
|
+
],
|
|
55
|
+
"default": "daily"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"contributions": [
|
|
59
|
+
{
|
|
60
|
+
"id": "edge-cloudflare-rate-limiting-REQ-001",
|
|
61
|
+
"kind": "req",
|
|
62
|
+
"path": "requirements/edge-cloudflare-rate-limiting-req-001.json"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "edge-cloudflare-rate-limiting-REQ-002",
|
|
66
|
+
"kind": "req",
|
|
67
|
+
"path": "requirements/edge-cloudflare-rate-limiting-req-002.json"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "edge-cloudflare-rate-limiting-REQ-003",
|
|
71
|
+
"kind": "req",
|
|
72
|
+
"path": "requirements/edge-cloudflare-rate-limiting-req-003.json"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "edge-cloudflare-rate-limiting-REQ-004",
|
|
76
|
+
"kind": "req",
|
|
77
|
+
"path": "requirements/edge-cloudflare-rate-limiting-req-004.json"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "edge-cloudflare-rate-limiting-REQ-005",
|
|
81
|
+
"kind": "req",
|
|
82
|
+
"path": "requirements/edge-cloudflare-rate-limiting-req-005.json"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "edge-cloudflare-rate-limiting-US-36101",
|
|
86
|
+
"kind": "us",
|
|
87
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36101.json"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "edge-cloudflare-rate-limiting-US-36102",
|
|
91
|
+
"kind": "us",
|
|
92
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36102.json"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "edge-cloudflare-rate-limiting-US-36103",
|
|
96
|
+
"kind": "us",
|
|
97
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36103.json"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "edge-cloudflare-rate-limiting-US-36104",
|
|
101
|
+
"kind": "us",
|
|
102
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36104.json"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "edge-cloudflare-rate-limiting-US-36105",
|
|
106
|
+
"kind": "us",
|
|
107
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36105.json"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "edge-cloudflare-rate-limiting-US-36106",
|
|
111
|
+
"kind": "us",
|
|
112
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36106.json"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "edge-cloudflare-rate-limiting-US-36107",
|
|
116
|
+
"kind": "us",
|
|
117
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36107.json"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "edge-cloudflare-rate-limiting-US-36108",
|
|
121
|
+
"kind": "us",
|
|
122
|
+
"path": "user-stories/edge-cloudflare-rate-limiting-us-36108.json"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "TAC-3701-edge-cloudflare-rate-limiting-manifest-schema",
|
|
126
|
+
"kind": "tac",
|
|
127
|
+
"path": "tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "TAC-3702-edge-cloudflare-rate-limiting-management-surface-doc",
|
|
131
|
+
"kind": "tac",
|
|
132
|
+
"path": "tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "TAC-3703-edge-cloudflare-rate-limiting-drift-audit-runner",
|
|
136
|
+
"kind": "tac",
|
|
137
|
+
"path": "tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "ADR-3701-edge-cloudflare-rate-limiting-throttle-contract",
|
|
141
|
+
"kind": "adr",
|
|
142
|
+
"path": "adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json",
|
|
143
|
+
"scope": "global",
|
|
144
|
+
"topic": "edgeThrottleContract",
|
|
145
|
+
"recommendedDefault": true,
|
|
146
|
+
"elicited": false,
|
|
147
|
+
"standardsTraceClause": "Cloudflare WAF rate-limiting rules documented shape"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "ADR-3702-edge-cloudflare-rate-limiting-layering",
|
|
151
|
+
"kind": "adr",
|
|
152
|
+
"path": "adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json",
|
|
153
|
+
"recommendedDefault": true,
|
|
154
|
+
"elicited": false,
|
|
155
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"id": "ADR-3703-edge-cloudflare-rate-limiting-manifest-shape",
|
|
159
|
+
"kind": "adr",
|
|
160
|
+
"path": "adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json",
|
|
161
|
+
"recommendedDefault": true,
|
|
162
|
+
"elicited": false,
|
|
163
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "ADR-3704-edge-cloudflare-rate-limiting-drift-audit-cadence",
|
|
167
|
+
"kind": "adr",
|
|
168
|
+
"path": "adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json",
|
|
169
|
+
"recommendedDefault": true,
|
|
170
|
+
"elicited": true,
|
|
171
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3701-edge-cloudflare-rate-limiting-throttle-contract",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Edge throttle contract: Cloudflare WAF rate-limiting rules as the shipped shape (scope global, new topic edgeThrottleContract)",
|
|
8
|
+
"context": "An applying Workers project that fronts a public surface needs a zone-level guard that refuses over-threshold bursts at the CF edge before they reach the origin Worker. Cloudflare's WAF rate-limiting rules provide the native answer: a set of rules on the zone, each with expression, threshold, period, characteristics, action and duration per https://developers.cloudflare.com/waf/rate-limiting-rules/. Every applied Worker needs one project-wide answer to the edgeThrottleContract topic; a future non-Cloudflare edge-throttle sibling (Fastly rate-limits, Vercel edge config throttles) would conflict on the same topic by design.",
|
|
9
|
+
"decision": "The shipped v1.0.0 default is Cloudflare WAF rate-limiting rules as the zone-level edge throttle. The rule shape (id, expression, threshold, period, characteristics, action, duration) matches the Cloudflare-documented shape per https://developers.cloudflare.com/waf/rate-limiting-rules/. The edgeThrottleContract topic scope is global on this blueprint; the topic string is edgeThrottleContract (lower camel case, one concept per topic, no version suffix). A future non-Cloudflare adapter contributes the same topic string with a different answer, forcing a DELIBERATE conflict the operator resolves with a project-level ADR. Standards trace clause: Cloudflare WAF rate-limiting rules documented shape.",
|
|
10
|
+
"consequences": "The applying project inherits Cloudflare's documented rule shape and the platform-imposed limits on rules per zone. The rule state lives on the Cloudflare account, not in the project git tree; the local manifest under cloudflare/rate-limits/ is the source of truth an operator applies via the wrangler or dashboard flow per REQ-002. Drift risk is addressed via ADR-3704 (drift-audit cadence) and TAC-3703 (drift-audit runner). Consumers deploying to a non-Cloudflare edge reach for a sibling adapter blueprint that would land as a v1.x minor on this shelf.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3702-edge-cloudflare-rate-limiting-layering",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Layering with security-auth-magic-link: zone rate rule sits OVER the per-email application rule",
|
|
8
|
+
"context": "The security-auth-magic-link blueprint ships a per-email per-minute application-level rate limiter on the mint surface. The edge-cloudflare-rate-limiting blueprint ships a zone-level rate rule characterised by IP-per-URL at the CF edge. Applying both blueprints without an explicit layering ADR would leave two rate rules whose characteristic sets an operator could easily mistake for overlapping.",
|
|
9
|
+
"decision": "When both blueprints are applied, the zone-level rate rule sits at the CF edge and refuses the (N+1)th request for the elicited duration before it reaches the origin Worker; the security-auth-magic-link per-email application limiter continues to run on requests that pass the edge gate, applying per-email per-minute limits at the mint-surface. The two rules operate on different characteristic sets (IP-per-URL at the zone, email at the application) and are additive, not overlapping. recommendedDefault: true. Standards trace clause: generic enterprise practice.",
|
|
10
|
+
"consequences": "The composition is documented in the blueprint guide with a copy-paste example (AC-36105-1). The applied recorder records both blueprints so the operator sees the two-rule shape at apply time; a subsequent change to either rule's characteristic that would drift the composition into overlap is caught in the drift-audit runner (TAC-3703).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3703-edge-cloudflare-rate-limiting-manifest-shape",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Manifest lives at cloudflare/rate-limits/, one JSON file per rule; the operator applies via wrangler or dashboard, not via a committed script",
|
|
8
|
+
"context": "The rule set could be committed as a wrangler-shape script, a bespoke apply tool, a single manifest file, or one file per rule. The single-file shape hides diff signal when one rule changes; the committed script couples the source of truth to a specific tool. The one-file-per-rule shape keeps a rule change to one file diff, makes review straightforward, and leaves the apply flow to the operator's choice of wrangler or dashboard.",
|
|
9
|
+
"decision": "The manifest lives at the elicited rate-limit-rules-dir (default cloudflare/rate-limits/), with one JSON file per rule. The blueprint ships no committed script that writes rules to the live zone; the operator applies through the documented wrangler or dashboard flow per REQ-002 and TAC-3702. recommendedDefault: true. Standards trace clause: generic enterprise practice.",
|
|
10
|
+
"consequences": "One-file-per-rule keeps each rule diff scoped; the operator can review a rule change in isolation. No committed apply script means the shipped blueprint does not couple to a specific tool version and does not require a Cloudflare API token at build time. Operator applies the manifest at a cadence they set; drift risk is addressed via ADR-3704 and TAC-3703.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3704-edge-cloudflare-rate-limiting-drift-audit-cadence",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Drift-audit cadence: off, daily or hourly (elicited; recommendedDefault daily)",
|
|
8
|
+
"context": "Rate-limit rules live on the Cloudflare account, not in the project git tree. An operator that changes a rule on the dashboard without a matching manifest update leaves the source of truth behind; a manifest edit that is not applied to the live zone leaves the live behaviour behind. Both directions of drift are runtime-observable but only if the applying project runs the drift-audit runner at a cadence.",
|
|
9
|
+
"decision": "The drift-audit cadence is elicited (rate-limit-drift-audit-cadence) with three options: off (disables the runner), daily (24-hour cadence), hourly (60-minute cadence). recommendedDefault: daily. elicited: true. Standards trace clause: generic enterprise practice.",
|
|
10
|
+
"consequences": "daily is the safe default for the typical operator (a manifest change that misses the live zone is surfaced within 24 hours through the applied logging companion's audit sink). hourly is the safe default for a high-cadence operation (the applying project makes rule changes multiple times a week and wants a same-day signal). off is safe only when the operator has an alternative drift-check discipline (a manual review after every change); the elicit prompts for the operator's choice at apply time.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T22:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T22:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Probe: drift-audit event secrecy.
|
|
2
|
+
//
|
|
3
|
+
// anchorAcId: AC-36107-1. accountBound: false.
|
|
4
|
+
//
|
|
5
|
+
// Drives the shipped drift-audit runner realisation
|
|
6
|
+
// (packages/rcf-lite/test/fixtures/cf-edge/src/drift-audit-runner.mjs)
|
|
7
|
+
// with a synthetic manifest loader and a fake fetch that returns a
|
|
8
|
+
// live-zone response with one mismatched rule. Asserts every record
|
|
9
|
+
// on the sink carries only {ruleId, clientIpHash, outcome, timestamp,
|
|
10
|
+
// diff} keys and NO full IPv4 or IPv6 address, NO body key, NO user
|
|
11
|
+
// agent key. Under SIMULATE_EVENT_LEAK_IP=true the runner injects a
|
|
12
|
+
// full client IP into the outcome so the probe surfaces the leak.
|
|
13
|
+
|
|
14
|
+
import { FIXTURE_DIR } from './probe-utils.mjs';
|
|
15
|
+
|
|
16
|
+
export const anchorAcId = 'AC-36107-1';
|
|
17
|
+
export const accountBound = false;
|
|
18
|
+
|
|
19
|
+
const IPV4 = /\b(?:25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)){3}\b/;
|
|
20
|
+
const IPV6 = /\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/;
|
|
21
|
+
const ALLOWED_KEYS = new Set(['ruleId', 'clientIpHash', 'outcome', 'timestamp', 'diff']);
|
|
22
|
+
const FORBIDDEN_KEYS = new Set(['body', 'userAgent', 'user-agent', 'clientIp', 'ip', 'sourceIp']);
|
|
23
|
+
|
|
24
|
+
function containsIp(text) {
|
|
25
|
+
if (typeof text !== 'string') return null;
|
|
26
|
+
const v4 = text.match(IPV4);
|
|
27
|
+
if (v4) return v4[0];
|
|
28
|
+
const v6 = text.match(IPV6);
|
|
29
|
+
if (v6) return v6[0];
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default async function runProbe() {
|
|
34
|
+
const runnerMod = await import(`${FIXTURE_DIR}/src/drift-audit-runner.mjs`);
|
|
35
|
+
const manifestRule = {
|
|
36
|
+
id: 'public-api-per-ip',
|
|
37
|
+
expression: '(http.request.uri.path matches "^/api/")',
|
|
38
|
+
threshold: 60,
|
|
39
|
+
period: 60,
|
|
40
|
+
characteristics: ['ip.src', 'cf.colo.id'],
|
|
41
|
+
action: 'block',
|
|
42
|
+
duration: 60,
|
|
43
|
+
};
|
|
44
|
+
const liveRule = { ...manifestRule, threshold: 90 };
|
|
45
|
+
const captured = [];
|
|
46
|
+
const eventSink = (record) => captured.push(record);
|
|
47
|
+
const fakeFetch = async () => ({
|
|
48
|
+
ok: true,
|
|
49
|
+
status: 200,
|
|
50
|
+
async json() { return { result: [liveRule] }; },
|
|
51
|
+
});
|
|
52
|
+
const runner = runnerMod.createDriftAuditRunner({
|
|
53
|
+
env: {
|
|
54
|
+
CF_ZONE_ID: 'fixture-zone-id',
|
|
55
|
+
SIMULATE_EVENT_LEAK_IP: process.env.SIMULATE_EVENT_LEAK_IP,
|
|
56
|
+
},
|
|
57
|
+
eventSink,
|
|
58
|
+
fetch: fakeFetch,
|
|
59
|
+
clock: () => '2026-09-07T22:00:00.000Z',
|
|
60
|
+
cadence: 'daily',
|
|
61
|
+
manifestLoader: async () => [manifestRule],
|
|
62
|
+
});
|
|
63
|
+
const report = await runner.runOnce();
|
|
64
|
+
const results = [];
|
|
65
|
+
if (captured.length === 0) {
|
|
66
|
+
results.push({ anchorAcId: 'AC-36107-1', verdict: 'fail', detail: 'drift-audit runner produced zero records; expected one for the threshold drift.' });
|
|
67
|
+
return { results };
|
|
68
|
+
}
|
|
69
|
+
let ipLeak = null;
|
|
70
|
+
let keyLeak = null;
|
|
71
|
+
for (const rec of captured) {
|
|
72
|
+
for (const k of Object.keys(rec)) {
|
|
73
|
+
if (FORBIDDEN_KEYS.has(k)) keyLeak = k;
|
|
74
|
+
if (!ALLOWED_KEYS.has(k)) keyLeak = keyLeak || `unexpected-key:${k}`;
|
|
75
|
+
}
|
|
76
|
+
for (const v of Object.values(rec)) {
|
|
77
|
+
if (typeof v === 'string') {
|
|
78
|
+
const hit = containsIp(v);
|
|
79
|
+
if (hit) ipLeak = hit;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (keyLeak) {
|
|
84
|
+
results.push({ anchorAcId: 'AC-36107-1', verdict: 'fail', detail: `drift-audit record carries a forbidden or unexpected key: ${keyLeak}` });
|
|
85
|
+
}
|
|
86
|
+
if (ipLeak) {
|
|
87
|
+
results.push({ anchorAcId: 'AC-36107-1', verdict: 'fail', detail: `drift-audit record leaked a full IP address in a string field: ${ipLeak}` });
|
|
88
|
+
}
|
|
89
|
+
if (results.length === 0) {
|
|
90
|
+
results.push({
|
|
91
|
+
anchorAcId: 'AC-36107-1',
|
|
92
|
+
verdict: 'pass',
|
|
93
|
+
detail: `drift-audit runner produced ${captured.length} record(s); every record carries only ${[...ALLOWED_KEYS].join(', ')} and no full IP, body or user-agent field appears.`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
results,
|
|
98
|
+
extra: {
|
|
99
|
+
recordCount: captured.length,
|
|
100
|
+
driftCount: report.driftCount,
|
|
101
|
+
allowedKeys: [...ALLOWED_KEYS],
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Probe: rate-limit manifest presence.
|
|
2
|
+
//
|
|
3
|
+
// anchorAcId: AC-36101-1 (also surfaces AC-36108-1's missing-file
|
|
4
|
+
// negative through SIMULATE_MANIFEST_MISSING). accountBound: false.
|
|
5
|
+
//
|
|
6
|
+
// Reads the cf-edge fixture manifest directory (cloudflare/rate-limits/),
|
|
7
|
+
// asserts:
|
|
8
|
+
// - at least one JSON file is present under the directory.
|
|
9
|
+
// - every file parses as JSON.
|
|
10
|
+
// - every file carries the seven required Cloudflare WAF rate-limiting
|
|
11
|
+
// rules fields (id, expression, threshold, period, characteristics,
|
|
12
|
+
// action, duration).
|
|
13
|
+
// - no file body carries a plaintext bearer token, private key or
|
|
14
|
+
// inline CF_API_TOKEN reference.
|
|
15
|
+
//
|
|
16
|
+
// Under SIMULATE_MANIFEST_MISSING=true the probe treats the first
|
|
17
|
+
// manifest file as absent and returns aggregateVerdict: fail with
|
|
18
|
+
// the missing basename named in the detail (AC-36108-1).
|
|
19
|
+
|
|
20
|
+
import { readManifestFiles, scanForPlaintextSecrets, REQUIRED_FIELDS } from './probe-utils.mjs';
|
|
21
|
+
|
|
22
|
+
export const anchorAcId = 'AC-36101-1';
|
|
23
|
+
export const accountBound = false;
|
|
24
|
+
|
|
25
|
+
export default async function runProbe() {
|
|
26
|
+
const { present, entries, files = [], hiddenBySimulate = [] } = await readManifestFiles();
|
|
27
|
+
const results = [];
|
|
28
|
+
if (!present) {
|
|
29
|
+
results.push({
|
|
30
|
+
anchorAcId: 'AC-36101-1',
|
|
31
|
+
verdict: 'fail',
|
|
32
|
+
detail: 'manifest directory holds zero JSON files; cf-edge fixture must ship at least one rule file under cloudflare/rate-limits/.',
|
|
33
|
+
});
|
|
34
|
+
return { results };
|
|
35
|
+
}
|
|
36
|
+
if (hiddenBySimulate.length > 0) {
|
|
37
|
+
results.push({
|
|
38
|
+
anchorAcId: 'AC-36108-1',
|
|
39
|
+
verdict: 'fail',
|
|
40
|
+
detail: `manifest file missing: ${hiddenBySimulate.join(', ')} (SIMULATE_MANIFEST_MISSING=true).`,
|
|
41
|
+
});
|
|
42
|
+
return { results };
|
|
43
|
+
}
|
|
44
|
+
let missingFieldCount = 0;
|
|
45
|
+
let plaintextCount = 0;
|
|
46
|
+
const fileFindings = [];
|
|
47
|
+
for (const f of files) {
|
|
48
|
+
let doc;
|
|
49
|
+
try {
|
|
50
|
+
doc = JSON.parse(f.text);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
results.push({
|
|
53
|
+
anchorAcId: 'AC-36101-1',
|
|
54
|
+
verdict: 'fail',
|
|
55
|
+
detail: `manifest file ${f.name} does not parse as JSON: ${err.message}`,
|
|
56
|
+
});
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const missing = REQUIRED_FIELDS.filter((k) => !(k in doc));
|
|
60
|
+
if (missing.length > 0) {
|
|
61
|
+
missingFieldCount += 1;
|
|
62
|
+
results.push({
|
|
63
|
+
anchorAcId: 'AC-36101-1',
|
|
64
|
+
verdict: 'fail',
|
|
65
|
+
detail: `manifest file ${f.name} missing required fields: ${missing.join(', ')}`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const hits = scanForPlaintextSecrets(f.text);
|
|
69
|
+
if (hits.length > 0) {
|
|
70
|
+
plaintextCount += 1;
|
|
71
|
+
results.push({
|
|
72
|
+
anchorAcId: 'AC-36101-1',
|
|
73
|
+
verdict: 'fail',
|
|
74
|
+
detail: `manifest file ${f.name} carries plaintext secret pattern(s): ${hits.join(', ')}`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
fileFindings.push({ name: f.name, ruleId: doc.id ?? null });
|
|
78
|
+
}
|
|
79
|
+
if (results.length === 0) {
|
|
80
|
+
results.push({
|
|
81
|
+
anchorAcId: 'AC-36101-1',
|
|
82
|
+
verdict: 'pass',
|
|
83
|
+
detail: `${files.length} manifest file(s) inspected; every file carries the ${REQUIRED_FIELDS.length} required fields and no plaintext secret pattern was found.`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
results,
|
|
88
|
+
extra: {
|
|
89
|
+
manifestFileCount: files.length,
|
|
90
|
+
manifestFiles: fileFindings,
|
|
91
|
+
missingFieldFileCount: missingFieldCount,
|
|
92
|
+
plaintextHitFileCount: plaintextCount,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-schema-validate.mjs
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Probe: rate-limit manifest schema-validate.
|
|
2
|
+
//
|
|
3
|
+
// anchorAcId: AC-36106-1. accountBound: false.
|
|
4
|
+
//
|
|
5
|
+
// Reads the cf-edge fixture manifest directory, loads the shipped
|
|
6
|
+
// JSON Schema (contributions/schemas/rate-limit-rule.schema.json,
|
|
7
|
+
// draft-07) and validates every manifest file against it. A minimal
|
|
8
|
+
// dependency-free validator covers the shape the schema commits to:
|
|
9
|
+
// required-fields, type-per-field, integer-minimum, string-min-length,
|
|
10
|
+
// non-empty-array and additionalProperties: false.
|
|
11
|
+
//
|
|
12
|
+
// Under SIMULATE_SCHEMA_INVALID=true the probe writes a scratch
|
|
13
|
+
// manifest file that omits the threshold field so validation fails
|
|
14
|
+
// with the offending field named in the detail.
|
|
15
|
+
|
|
16
|
+
import { readdir, readFile, writeFile, unlink, mkdir } from 'node:fs/promises';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { MANIFEST_DIR, REQUIRED_FIELDS, ACTION_ENUM, loadSchema } from './probe-utils.mjs';
|
|
19
|
+
|
|
20
|
+
export const anchorAcId = 'AC-36106-1';
|
|
21
|
+
export const accountBound = false;
|
|
22
|
+
|
|
23
|
+
function validateDoc(doc, schema, filename) {
|
|
24
|
+
const failures = [];
|
|
25
|
+
if (typeof doc !== 'object' || doc === null || Array.isArray(doc)) {
|
|
26
|
+
failures.push(`${filename}: root is not a JSON object`);
|
|
27
|
+
return failures;
|
|
28
|
+
}
|
|
29
|
+
for (const required of schema.required) {
|
|
30
|
+
if (!(required in doc)) failures.push(`${filename}: missing required field ${required}`);
|
|
31
|
+
}
|
|
32
|
+
const props = schema.properties || {};
|
|
33
|
+
const allowed = new Set(Object.keys(props));
|
|
34
|
+
if (schema.additionalProperties === false) {
|
|
35
|
+
for (const key of Object.keys(doc)) {
|
|
36
|
+
if (!allowed.has(key)) failures.push(`${filename}: additional property not permitted: ${key}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for (const [key, def] of Object.entries(props)) {
|
|
40
|
+
if (!(key in doc)) continue;
|
|
41
|
+
const v = doc[key];
|
|
42
|
+
if (def.type === 'string') {
|
|
43
|
+
if (typeof v !== 'string') { failures.push(`${filename}: ${key} is not a string`); continue; }
|
|
44
|
+
if (typeof def.minLength === 'number' && v.length < def.minLength) failures.push(`${filename}: ${key} shorter than minLength ${def.minLength}`);
|
|
45
|
+
if (Array.isArray(def.enum) && !def.enum.includes(v)) failures.push(`${filename}: ${key} value ${JSON.stringify(v)} not in enum ${JSON.stringify(def.enum)}`);
|
|
46
|
+
} else if (def.type === 'integer') {
|
|
47
|
+
if (!Number.isInteger(v)) { failures.push(`${filename}: ${key} is not an integer`); continue; }
|
|
48
|
+
if (typeof def.minimum === 'number' && v < def.minimum) failures.push(`${filename}: ${key} value ${v} below minimum ${def.minimum}`);
|
|
49
|
+
} else if (def.type === 'array') {
|
|
50
|
+
if (!Array.isArray(v)) { failures.push(`${filename}: ${key} is not an array`); continue; }
|
|
51
|
+
if (typeof def.minItems === 'number' && v.length < def.minItems) failures.push(`${filename}: ${key} array shorter than minItems ${def.minItems}`);
|
|
52
|
+
if (def.items && def.items.type === 'string') {
|
|
53
|
+
v.forEach((item, i) => {
|
|
54
|
+
if (typeof item !== 'string') failures.push(`${filename}: ${key}[${i}] is not a string`);
|
|
55
|
+
else if (typeof def.items.minLength === 'number' && item.length < def.items.minLength) failures.push(`${filename}: ${key}[${i}] shorter than minLength ${def.items.minLength}`);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return failures;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default async function runProbe() {
|
|
64
|
+
const schema = await loadSchema();
|
|
65
|
+
const simulateInvalid = process.env.SIMULATE_SCHEMA_INVALID === 'true';
|
|
66
|
+
const results = [];
|
|
67
|
+
const fileFindings = [];
|
|
68
|
+
let scratchPath = null;
|
|
69
|
+
try {
|
|
70
|
+
if (simulateInvalid) {
|
|
71
|
+
await mkdir(MANIFEST_DIR, { recursive: true });
|
|
72
|
+
scratchPath = join(MANIFEST_DIR, '__simulate-schema-invalid.json');
|
|
73
|
+
const invalidDoc = {
|
|
74
|
+
id: 'simulate-schema-invalid',
|
|
75
|
+
expression: '(http.request.uri.path matches "^/api/")',
|
|
76
|
+
period: 60,
|
|
77
|
+
characteristics: ['ip.src'],
|
|
78
|
+
action: 'block',
|
|
79
|
+
duration: 60,
|
|
80
|
+
};
|
|
81
|
+
await writeFile(scratchPath, JSON.stringify(invalidDoc, null, 2) + '\n', 'utf8');
|
|
82
|
+
}
|
|
83
|
+
const entries = (await readdir(MANIFEST_DIR)).filter((f) => f.endsWith('.json')).sort();
|
|
84
|
+
for (const name of entries) {
|
|
85
|
+
const text = await readFile(join(MANIFEST_DIR, name), 'utf8');
|
|
86
|
+
let doc;
|
|
87
|
+
try {
|
|
88
|
+
doc = JSON.parse(text);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
results.push({
|
|
91
|
+
anchorAcId: 'AC-36106-1',
|
|
92
|
+
verdict: 'fail',
|
|
93
|
+
detail: `manifest file ${name} does not parse: ${err.message}`,
|
|
94
|
+
});
|
|
95
|
+
fileFindings.push({ name, valid: false, errors: [err.message] });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const failures = validateDoc(doc, schema, name);
|
|
99
|
+
if (failures.length > 0) {
|
|
100
|
+
results.push({
|
|
101
|
+
anchorAcId: 'AC-36106-1',
|
|
102
|
+
verdict: 'fail',
|
|
103
|
+
detail: failures.join('; '),
|
|
104
|
+
});
|
|
105
|
+
fileFindings.push({ name, valid: false, errors: failures });
|
|
106
|
+
} else {
|
|
107
|
+
fileFindings.push({ name, valid: true });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} finally {
|
|
111
|
+
if (scratchPath) {
|
|
112
|
+
try { await unlink(scratchPath); } catch {}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (results.length === 0) {
|
|
116
|
+
results.push({
|
|
117
|
+
anchorAcId: 'AC-36106-1',
|
|
118
|
+
verdict: 'pass',
|
|
119
|
+
detail: `every manifest file validates against the shipped draft-07 schema (${fileFindings.length} file(s) inspected; required fields ${REQUIRED_FIELDS.join(', ')}; action enum ${ACTION_ENUM.join('/')}).`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
results,
|
|
124
|
+
extra: {
|
|
125
|
+
schemaId: schema.$id,
|
|
126
|
+
manifestFileCount: fileFindings.length,
|
|
127
|
+
manifestFiles: fileFindings,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|