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,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Scheduled trigger contract: Cloudflare Workers Cron Triggers as the shipped shape (scope global, new topic scheduledTriggerContract)",
|
|
8
|
+
"context": "An applying Workers project has one native scheduled-trigger answer today: Cloudflare Workers Cron Triggers. Cron expressions are declared in wrangler.toml under [triggers] crons per https://developers.cloudflare.com/workers/configuration/cron-triggers/; the shipped runtime invokes a scheduled(event, env, ctx) handler on each fire per https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/. Cron Triggers fire on a best-effort basis; wrangler dev exposes a --test-scheduled CLI seam that lets a reviewer drive a scheduled fire deterministically per https://developers.cloudflare.com/workers/wrangler/commands/#dev. The v1.0.0 dispatcher holds the routing reference opaque at the handler boundary so a future non-Cloudflare adapter or an in-process adapter for tests slots in without a handler re-shape, and so the round-6 T-3 Durable Objects sibling and the follow-up Workflows adapter on jobs-background land as separate concerns.",
|
|
9
|
+
"decision": "The shipped v1.0.0 default is Cloudflare Workers Cron Triggers, wired through wrangler config ([triggers] crons per https://developers.cloudflare.com/workers/configuration/cron-triggers/) with the scheduled(event, env, ctx) handler shape as the sole reader of the Cron Trigger event per REQ-001. The scheduledTriggerContract topic scope is global on this blueprint; the topic string is scheduledTriggerContract (lower camelCase, one concept per topic, no version suffix, per the round-2 rules-for-new-topics clause on the shelf registry). A future non-Cron-Triggers scheduler (a cross-region cron on a different platform, a durable-workflow scheduler on the round-6 T-3 Durable Objects sibling) would contribute the same topic string with a different answer, forcing a DELIBERATE conflict the operator resolves with a project-level ADR per the round-2 conflict pattern.",
|
|
10
|
+
"consequences": "The applying project inherits the Cron Triggers wire format, the platform-assigned per-Worker cron limits (https://developers.cloudflare.com/workers/platform/limits/), and the documented best-effort schedule. Standards trace clause: Cloudflare Workers Cron Triggers documented shape (per https://developers.cloudflare.com/workers/configuration/cron-triggers/). Consumer code needing strong-scheduled semantics (a durable workflow with retries and state across fires) reaches for the follow-up Workflows adapter on the round-6 jobs-background v1.1.0 minor bump (per spec section 5.7); the guide carries the decision-tree cross-reference between platform-cloudflare-cron-triggers (recurring cadence, statelessness) and jobs-background (durable, retried, workflow-shaped).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T12:35:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T12:35:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3302-platform-cloudflare-cron-triggers-dispatcher-mode",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Dispatcher mode: single-handler or expression-routed; recommended default expression-routed when more than one cron expression is elicited",
|
|
8
|
+
"context": "The scheduled() handler must route every Cron Trigger event to some handler. The trivial single-cron project has one expression and one handler; the multi-cron project has two or more expressions and expects distinct handlers. Hand-rolled conditionals inside the scheduled handler are brittle and spread the routing concern across the applying project. The dispatcher factors this concern into one seam.",
|
|
9
|
+
"decision": "Ship two dispatcher modes as an elicited answer. single-handler routes every fire to one handler (used when the elicited cron-expressions list has one entry). expression-routed maps each expression string-equal to a distinct handler (used when the list has more than one entry). The recommended default is expression-routed when the elicited cron-expressions list has more than one entry, otherwise single-handler. The elicit records the operator's answer in rcf/blueprints/platform-cloudflare-cron-triggers.applied.json under cron-dispatcher-mode; the createDispatcher factory reads that answer at apply time and constructs the routes accordingly.",
|
|
10
|
+
"consequences": "The applied project observes a bounded dispatch shape: exactly one handler per fire in single-handler mode; exactly one handler per matched expression in expression-routed mode; a cronUnmatched event on any other input. A future third dispatch mode (matching on wildcarded expression sets, dispatching to a handler pool) would extend the enum with a new value and a new dispatcher variant; the applied answer's value stays the operator's choice.",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T12:35:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T12:35:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3303-platform-cloudflare-cron-triggers-skew-tolerance-default",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Default skew tolerance: 30 seconds shipped, floor 5 seconds, ceiling 5 minutes",
|
|
8
|
+
"context": "Cloudflare Cron Triggers are documented as scheduling on a best-effort basis; the observed handler start time can drift from the event's scheduledTime. The applied project needs a bounded classification lever so the applied logging companion surfaces cronSkewed for drift the operator cares about and stays quiet within a tolerable window. A per-project fixed default is a starting point the operator elicits away from for tighter or looser needs.",
|
|
9
|
+
"decision": "Ship 30 seconds as the elicited default skew tolerance. Enforce a 5-second floor (a sub-5s window flags on normal scheduling jitter and the logging stream fills with cronSkewed noise) and a 300-second (5 minute) ceiling (a longer window turns the signal into an alerting no-op). The elicited answer is written into the applied project as the skewToleranceMs argument on the createDispatcher factory (converted to milliseconds).",
|
|
10
|
+
"consequences": "The applied project observes cronSkewed for drift beyond 30 seconds by default; a project needing tighter observability re-elicits closer to the floor; a project running loose crons re-elicits closer to the ceiling. Standards trace clause: generic enterprise practice (no vendor-documented skew-tolerance default for Cron Triggers; the value is an applied-project observability lever, not a vendor guarantee).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T12:35:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T12:35:00.000Z"
|
|
14
|
+
}
|
package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/dispatcher-routing.mjs
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Dispatcher-routing probe for platform-cloudflare-cron-triggers v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Wires two cron expressions to two spy handlers in-process (no
|
|
4
|
+
// wrangler). Drives each expression separately through the shipped
|
|
5
|
+
// dispatcher module and asserts only the routed spy fires. Then
|
|
6
|
+
// drives an unmatched expression and asserts cronUnmatched with no
|
|
7
|
+
// spy invocation.
|
|
8
|
+
//
|
|
9
|
+
// anchorAcId: AC-32102-1 (primary; AC-32102-2 covered as an
|
|
10
|
+
// additional result).
|
|
11
|
+
// accountBound: false.
|
|
12
|
+
|
|
13
|
+
export const anchorAcId = 'AC-32102-1';
|
|
14
|
+
export const accountBound = false;
|
|
15
|
+
|
|
16
|
+
export default async function runProbe() {
|
|
17
|
+
const { createDispatcher } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/dispatcher.mjs');
|
|
18
|
+
|
|
19
|
+
const events = [];
|
|
20
|
+
const eventSink = (rec) => events.push(rec);
|
|
21
|
+
|
|
22
|
+
const results = [];
|
|
23
|
+
|
|
24
|
+
// AC-32102-1: two routes, dispatch to route A, only spy A fires.
|
|
25
|
+
const spyA = { calls: 0, lastCtx: null };
|
|
26
|
+
const spyB = { calls: 0, lastCtx: null };
|
|
27
|
+
const dispatcher = createDispatcher({
|
|
28
|
+
routes: [
|
|
29
|
+
{ expression: '* * * * *', handler: async (ctx) => { spyA.calls += 1; spyA.lastCtx = ctx; } },
|
|
30
|
+
{ expression: '*/5 * * * *', handler: async (ctx) => { spyB.calls += 1; spyB.lastCtx = ctx; } },
|
|
31
|
+
],
|
|
32
|
+
eventSink,
|
|
33
|
+
skewToleranceMs: 60000,
|
|
34
|
+
softBudgetMs: 60000,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const scheduledMs = Date.now();
|
|
38
|
+
await dispatcher.dispatch({ cron: '* * * * *', scheduledTime: scheduledMs });
|
|
39
|
+
const matchedOnly = spyA.calls === 1 && spyB.calls === 0 && spyA.lastCtx && spyA.lastCtx.expression === '* * * * *' && spyA.lastCtx.scheduledTime === scheduledMs && typeof spyA.lastCtx.sink === 'function';
|
|
40
|
+
results.push({
|
|
41
|
+
anchorAcId: 'AC-32102-1',
|
|
42
|
+
verdict: matchedOnly ? 'pass' : 'fail',
|
|
43
|
+
detail: matchedOnly
|
|
44
|
+
? `dispatch({cron: "* * * * *"}) invoked spyA=${spyA.calls} spyB=${spyB.calls}; bounded context {expression, scheduledTime, sink} present`
|
|
45
|
+
: `matched-only fault: spyA=${spyA.calls} spyB=${spyB.calls} ctx=${JSON.stringify(spyA.lastCtx ? { hasExpression: !!spyA.lastCtx.expression, hasScheduledTime: !!spyA.lastCtx.scheduledTime, hasSink: typeof spyA.lastCtx.sink === 'function' } : null)}`,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// AC-32102-2: unmatched expression fires cronUnmatched, no spy invocation.
|
|
49
|
+
const priorAB = spyA.calls + spyB.calls;
|
|
50
|
+
events.length = 0;
|
|
51
|
+
await dispatcher.dispatch({ cron: '@yearly', scheduledTime: scheduledMs });
|
|
52
|
+
const unmatched = events.filter((e) => e.event === 'cronUnmatched');
|
|
53
|
+
const noSpyDelta = spyA.calls + spyB.calls === priorAB;
|
|
54
|
+
const unmatchedOk = unmatched.length === 1 && noSpyDelta && unmatched[0].expression === '@yearly' && unmatched[0].outcome === 'unmatched' && unmatched[0].duration === 0;
|
|
55
|
+
results.push({
|
|
56
|
+
anchorAcId: 'AC-32102-2',
|
|
57
|
+
verdict: unmatchedOk ? 'pass' : 'fail',
|
|
58
|
+
detail: unmatchedOk
|
|
59
|
+
? `dispatch({cron: "@yearly"}) fired cronUnmatched once with outcome=unmatched duration=0; no spy invocation delta observed`
|
|
60
|
+
: `unmatched fault: cronUnmatched=${unmatched.length} spyDelta=${(spyA.calls + spyB.calls) - priorAB} record=${JSON.stringify(unmatched[0] ?? null)}`,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return { results };
|
|
64
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Event-secrecy probe for platform-cloudflare-cron-triggers v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Two layers of assertion so the whitelist is exercised at the
|
|
4
|
+
// actual boundary AC-32106-1 claims, and the shipped code path is
|
|
5
|
+
// exercised end-to-end with a PII fixture closure:
|
|
6
|
+
//
|
|
7
|
+
// (1) Direct-boundary assertion: every event record's keys are
|
|
8
|
+
// a subset of the allow-list {event, expression, scheduledTime,
|
|
9
|
+
// outcome, duration, softBudgetMs, deltaMs}.
|
|
10
|
+
//
|
|
11
|
+
// (2) Substring assertion: no PII substring in the JSON
|
|
12
|
+
// serialisation of any record OUTSIDE its expression field
|
|
13
|
+
// (the expression is a legitimate literal from wrangler.toml).
|
|
14
|
+
//
|
|
15
|
+
// Induced-failure switch SIMULATE_PII_LEAK=true wraps the sink so
|
|
16
|
+
// it forwards the closure onto every record; the probe surfaces
|
|
17
|
+
// the leaked fields and returns aggregateVerdict: fail. A reviewer
|
|
18
|
+
// running with the switch off gets pass; on gets fail with the
|
|
19
|
+
// leaked substrings named.
|
|
20
|
+
//
|
|
21
|
+
// anchorAcId: AC-32106-1.
|
|
22
|
+
// accountBound: false.
|
|
23
|
+
|
|
24
|
+
export const anchorAcId = 'AC-32106-1';
|
|
25
|
+
export const accountBound = false;
|
|
26
|
+
|
|
27
|
+
const PII_STRINGS = ['REDACTED-fixture', '4242', 'ssn'];
|
|
28
|
+
const ALLOWED_KEYS = new Set(['event', 'expression', 'scheduledTime', 'outcome', 'duration', 'softBudgetMs', 'deltaMs']);
|
|
29
|
+
const SIMULATE_PII_LEAK = process.env.SIMULATE_PII_LEAK === 'true';
|
|
30
|
+
|
|
31
|
+
export default async function runProbe() {
|
|
32
|
+
const { createDispatcher } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/dispatcher.mjs');
|
|
33
|
+
|
|
34
|
+
const results = [];
|
|
35
|
+
const captured = [];
|
|
36
|
+
|
|
37
|
+
const baseSink = (rec) => captured.push(rec);
|
|
38
|
+
const leakySink = (rec) => captured.push({ ...rec, body: rec.body ?? { ssn: 'REDACTED-fixture', userId: 4242 }, ssn: 'REDACTED-fixture', userId: 4242 });
|
|
39
|
+
const sink = SIMULATE_PII_LEAK ? leakySink : baseSink;
|
|
40
|
+
|
|
41
|
+
// Closure over PII fixture; the handler sees it, the dispatcher never does.
|
|
42
|
+
const piiClosure = { userId: 4242, ssn: 'REDACTED-fixture' };
|
|
43
|
+
|
|
44
|
+
const dispatcher = createDispatcher({
|
|
45
|
+
routes: [
|
|
46
|
+
{
|
|
47
|
+
expression: '* * * * *',
|
|
48
|
+
handler: async () => {
|
|
49
|
+
// Handler reads the closure but the dispatcher constructs
|
|
50
|
+
// event records from event metadata only. The closure never
|
|
51
|
+
// reaches the sink on the shipped code path.
|
|
52
|
+
void piiClosure.userId;
|
|
53
|
+
void piiClosure.ssn;
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
eventSink: sink,
|
|
58
|
+
skewToleranceMs: 60000,
|
|
59
|
+
softBudgetMs: 60000,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const scheduledMs = Date.now();
|
|
63
|
+
await dispatcher.dispatch({ cron: '* * * * *', scheduledTime: scheduledMs });
|
|
64
|
+
// Also drive an unmatched fire to cover the cronUnmatched event shape.
|
|
65
|
+
await dispatcher.dispatch({ cron: '@daily', scheduledTime: scheduledMs });
|
|
66
|
+
|
|
67
|
+
// Layer (1): every record's keys are a subset of the allow-list.
|
|
68
|
+
const forbiddenKeys = new Set();
|
|
69
|
+
for (const rec of captured) {
|
|
70
|
+
for (const k of Object.keys(rec)) {
|
|
71
|
+
if (!ALLOWED_KEYS.has(k)) forbiddenKeys.add(k);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Layer (2): substring scan over the JSON serialisation, EXCLUDING
|
|
76
|
+
// the expression field (which is a legitimate literal from
|
|
77
|
+
// wrangler.toml; excluding it prevents a false positive where the
|
|
78
|
+
// expression itself contains a PII substring by accident).
|
|
79
|
+
const withoutExpression = captured.map((r) => {
|
|
80
|
+
const { expression: _omit, ...rest } = r;
|
|
81
|
+
return rest;
|
|
82
|
+
});
|
|
83
|
+
const serialised = JSON.stringify(withoutExpression);
|
|
84
|
+
const piiHits = PII_STRINGS.filter((s) => serialised.includes(s));
|
|
85
|
+
|
|
86
|
+
const whitelistPass = forbiddenKeys.size === 0 && piiHits.length === 0;
|
|
87
|
+
results.push({
|
|
88
|
+
anchorAcId: 'AC-32106-1',
|
|
89
|
+
verdict: SIMULATE_PII_LEAK
|
|
90
|
+
? (whitelistPass ? 'fail' : 'fail')
|
|
91
|
+
: (whitelistPass ? 'pass' : 'fail'),
|
|
92
|
+
detail: SIMULATE_PII_LEAK
|
|
93
|
+
? `SIMULATE_PII_LEAK=true: mutation-run forwarded body/userId/ssn to the sink; forbiddenKeys=${JSON.stringify([...forbiddenKeys])} piiHits=${JSON.stringify(piiHits)} (expected empty on the shipped code path)`
|
|
94
|
+
: (whitelistPass
|
|
95
|
+
? `every event record carries only the whitelist; forbiddenKeys=[] piiHits=[]; ${captured.length} records observed for one matched fire and one unmatched fire`
|
|
96
|
+
: `whitelist breach: forbiddenKeys=${JSON.stringify([...forbiddenKeys])} piiHits=${JSON.stringify(piiHits)}`),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return { results };
|
|
100
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Shared helpers for platform-cloudflare-cron-triggers probes.
|
|
2
|
+
//
|
|
3
|
+
// Runtime-dependency posture: probes import the fixture's scheduled
|
|
4
|
+
// handler and dispatcher from the cf-platform fixture src/ tree so
|
|
5
|
+
// rcf-lite itself gains no new runtime dependency. The
|
|
6
|
+
// wrangler-test-scheduled probe drives the vendor's CLI seam via a
|
|
7
|
+
// child process; the dispatcher-routing, skew-tolerance and
|
|
8
|
+
// event-secrecy probes drive the dispatcher in-process against
|
|
9
|
+
// spy handlers.
|
|
10
|
+
//
|
|
11
|
+
// The real-account-scheduled-smoke probe opens the Cloudflare
|
|
12
|
+
// Workers API when CI_HAS_CLOUDFLARE_ACCOUNT is set; without the
|
|
13
|
+
// env var it records accountBoundSkipped and aggregates to pass
|
|
14
|
+
// per spec section 3.5.
|
|
15
|
+
|
|
16
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
17
|
+
import { dirname, resolve } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
|
|
20
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
|
|
22
|
+
export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
23
|
+
export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/cf-platform');
|
|
24
|
+
export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/platform-cloudflare-cron-triggers');
|
|
25
|
+
|
|
26
|
+
export function aggregate(results) {
|
|
27
|
+
if (results.some((r) => r.verdict === 'fail')) return 'fail';
|
|
28
|
+
if (results.some((r) => r.verdict === 'warn')) return 'warn';
|
|
29
|
+
return 'pass';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function writeReport({ probeName, engine, results, extra }) {
|
|
33
|
+
await mkdir(REPORT_DIR, { recursive: true });
|
|
34
|
+
const report = {
|
|
35
|
+
slug: 'platform-cloudflare-cron-triggers',
|
|
36
|
+
probeName,
|
|
37
|
+
runAt: new Date().toISOString(),
|
|
38
|
+
engine,
|
|
39
|
+
results,
|
|
40
|
+
aggregateVerdict: aggregate(results),
|
|
41
|
+
...(extra ?? {}),
|
|
42
|
+
};
|
|
43
|
+
const path = resolve(REPORT_DIR, `${probeName}.json`);
|
|
44
|
+
await writeFile(path, JSON.stringify(report, null, 2) + '\n', 'utf8');
|
|
45
|
+
return { report, path };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Wraps a probe's async main body and reports. Never calls
|
|
49
|
+
// process.exit after the large report write: sets process.exitCode
|
|
50
|
+
// and lets Node drain stdout naturally.
|
|
51
|
+
export async function runShim(probeName, engine, mainFn) {
|
|
52
|
+
try {
|
|
53
|
+
const { results, extra } = await mainFn();
|
|
54
|
+
const { report, path } = await writeReport({ probeName, engine, results, extra });
|
|
55
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
56
|
+
process.stdout.write(`report written to ${path}\n`);
|
|
57
|
+
if (report.aggregateVerdict === 'fail') process.exitCode = 1;
|
|
58
|
+
} catch (err) {
|
|
59
|
+
const results = [{
|
|
60
|
+
anchorAcId: 'unknown',
|
|
61
|
+
verdict: 'fail',
|
|
62
|
+
detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
|
|
63
|
+
}];
|
|
64
|
+
const { report, path } = await writeReport({ probeName, engine, results });
|
|
65
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
66
|
+
process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
|
|
67
|
+
process.stderr.write(`report written to ${path}\n`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Real-account live-cron smoke for platform-cloudflare-cron-triggers
|
|
2
|
+
// v1.0.0.
|
|
3
|
+
//
|
|
4
|
+
// When CI_HAS_CLOUDFLARE_ACCOUNT=true and the paired CF_ACCOUNT_ID,
|
|
5
|
+
// CF_WORKER_NAME and CF_API_TOKEN env vars are set, the probe polls
|
|
6
|
+
// the Cloudflare Workers analytics endpoint for the named Worker
|
|
7
|
+
// every 5 seconds, waits bounded 90 seconds for a scheduled event
|
|
8
|
+
// to appear at least once, and returns aggregateVerdict: pass.
|
|
9
|
+
//
|
|
10
|
+
// The probe does NOT deploy a Worker; it assumes an operator has
|
|
11
|
+
// already deployed one with a per-minute cron. This keeps CI safe
|
|
12
|
+
// and lets a reviewer point the probe at their own real Worker.
|
|
13
|
+
//
|
|
14
|
+
// Without CI_HAS_CLOUDFLARE_ACCOUNT the probe records
|
|
15
|
+
// accountBoundSkipped: true and aggregates to pass per spec
|
|
16
|
+
// section 3.5.
|
|
17
|
+
//
|
|
18
|
+
// anchorAcId: AC-32107-1.
|
|
19
|
+
// accountBound: true.
|
|
20
|
+
|
|
21
|
+
export const anchorAcId = 'AC-32107-1';
|
|
22
|
+
export const accountBound = true;
|
|
23
|
+
|
|
24
|
+
const CAP_MS = 90_000;
|
|
25
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
26
|
+
const API_BASE = 'https://api.cloudflare.com/client/v4';
|
|
27
|
+
|
|
28
|
+
export default async function runProbe() {
|
|
29
|
+
if (process.env.CI_HAS_CLOUDFLARE_ACCOUNT !== 'true') {
|
|
30
|
+
return {
|
|
31
|
+
results: [{
|
|
32
|
+
anchorAcId: 'AC-32107-1',
|
|
33
|
+
verdict: 'pass',
|
|
34
|
+
detail: 'accountBoundSkipped: CI_HAS_CLOUDFLARE_ACCOUNT is not set to true; spec section 3.5 pass-with-skip.',
|
|
35
|
+
}],
|
|
36
|
+
extra: { accountBoundSkipped: true },
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const accountId = process.env.CF_ACCOUNT_ID;
|
|
41
|
+
const workerName = process.env.CF_WORKER_NAME;
|
|
42
|
+
const token = process.env.CF_API_TOKEN;
|
|
43
|
+
if (!accountId || !workerName || !token) {
|
|
44
|
+
return {
|
|
45
|
+
results: [{
|
|
46
|
+
anchorAcId: 'AC-32107-1',
|
|
47
|
+
verdict: 'fail',
|
|
48
|
+
detail: `CI_HAS_CLOUDFLARE_ACCOUNT=true but one of CF_ACCOUNT_ID/CF_WORKER_NAME/CF_API_TOKEN is missing: accountIdPresent=${!!accountId} workerNamePresent=${!!workerName} tokenPresent=${!!token}`,
|
|
49
|
+
}],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const analyticsUrl = `${API_BASE}/accounts/${accountId}/workers/scripts/${encodeURIComponent(workerName)}/analytics`;
|
|
54
|
+
const authHeaders = { authorization: `Bearer ${token}`, 'content-type': 'application/json' };
|
|
55
|
+
|
|
56
|
+
const start = Date.now();
|
|
57
|
+
let observedCount = 0;
|
|
58
|
+
|
|
59
|
+
while (Date.now() - start < CAP_MS) {
|
|
60
|
+
try {
|
|
61
|
+
const resp = await fetch(analyticsUrl, { method: 'GET', headers: authHeaders });
|
|
62
|
+
if (resp.ok) {
|
|
63
|
+
const body = await resp.json();
|
|
64
|
+
// Cloudflare analytics shapes vary; the probe treats ANY
|
|
65
|
+
// scheduled-event count > 0 in the last minute as evidence.
|
|
66
|
+
const scheduledCount = extractScheduledCount(body);
|
|
67
|
+
if (scheduledCount > observedCount) {
|
|
68
|
+
observedCount = scheduledCount;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} catch (_err) {
|
|
73
|
+
// Transient network fault; poll again.
|
|
74
|
+
}
|
|
75
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const elapsed = Date.now() - start;
|
|
79
|
+
const pass = observedCount > 0;
|
|
80
|
+
return {
|
|
81
|
+
results: [{
|
|
82
|
+
anchorAcId: 'AC-32107-1',
|
|
83
|
+
verdict: pass ? 'pass' : 'fail',
|
|
84
|
+
detail: pass
|
|
85
|
+
? `observed >=1 scheduled event on ${workerName} within elapsed=${elapsed}ms (CAP=${CAP_MS}ms)`
|
|
86
|
+
: `no scheduled event observed on ${workerName} within CAP=${CAP_MS}ms; elapsed=${elapsed}ms. Confirm a per-minute cron is deployed on the Worker.`,
|
|
87
|
+
}],
|
|
88
|
+
extra: { elapsedMs: elapsed, cap: CAP_MS, observedCount },
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function extractScheduledCount(body) {
|
|
93
|
+
if (!body || typeof body !== 'object') return 0;
|
|
94
|
+
// Best-effort: look for common shapes across analytics endpoints.
|
|
95
|
+
const paths = [body.result?.scheduled_count, body.result?.scheduledCount, body.scheduled_count];
|
|
96
|
+
for (const v of paths) {
|
|
97
|
+
if (typeof v === 'number') return v;
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './real-account-scheduled-smoke.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'real-account', image: 'Cloudflare Workers analytics REST API', healthy: true };
|
|
5
|
+
runShim('real-account-scheduled-smoke', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './wrangler-test-scheduled.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'wrangler', image: 'wrangler dev --test-scheduled on cf-platform fixture', healthy: true };
|
|
5
|
+
runShim('wrangler-test-scheduled', engine, runProbe);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Skew-tolerance probe for platform-cloudflare-cron-triggers v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Drives the shipped dispatcher in-process against a fake clock and
|
|
4
|
+
// asserts:
|
|
5
|
+
//
|
|
6
|
+
// (a) an aligned clock fires cronFired with outcome onTime and no
|
|
7
|
+
// cronSkewed record (AC-32103-1).
|
|
8
|
+
// (b) a 60-second-shifted clock fires cronSkewed with the observed
|
|
9
|
+
// delta and the routed handler still runs (AC-32103-2).
|
|
10
|
+
//
|
|
11
|
+
// Also folds the soft-budget contract in as additional results
|
|
12
|
+
// (AC-32104-1 and AC-32104-2) so the shipped skew-tolerance probe
|
|
13
|
+
// is the one place the T-2 spec's time-based dispatcher behaviour is
|
|
14
|
+
// exercised end-to-end. SIMULATE_SLOW_HANDLER=true forces the spy
|
|
15
|
+
// handler past the soft budget on every dispatch so a reviewer can
|
|
16
|
+
// see cronStalled fires without editing the probe.
|
|
17
|
+
//
|
|
18
|
+
// anchorAcId: AC-32103-1 (primary; AC-32103-2, AC-32104-1 and
|
|
19
|
+
// AC-32104-2 covered as additional results).
|
|
20
|
+
// accountBound: false.
|
|
21
|
+
|
|
22
|
+
export const anchorAcId = 'AC-32103-1';
|
|
23
|
+
export const accountBound = false;
|
|
24
|
+
|
|
25
|
+
const SIMULATE_SLOW_HANDLER = process.env.SIMULATE_SLOW_HANDLER === 'true';
|
|
26
|
+
|
|
27
|
+
export default async function runProbe() {
|
|
28
|
+
const { createDispatcher } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/dispatcher.mjs');
|
|
29
|
+
|
|
30
|
+
const results = [];
|
|
31
|
+
|
|
32
|
+
// AC-32103-1: aligned clock. Clock returns scheduledMs + tiny elapsed on each call.
|
|
33
|
+
{
|
|
34
|
+
const events = [];
|
|
35
|
+
const sink = (rec) => events.push(rec);
|
|
36
|
+
const scheduledMs = 1_700_000_000_000;
|
|
37
|
+
let tick = 0;
|
|
38
|
+
const clock = () => scheduledMs + tick++;
|
|
39
|
+
const dispatcher = createDispatcher({
|
|
40
|
+
routes: [{ expression: '* * * * *', handler: async () => { /* no-op */ } }],
|
|
41
|
+
eventSink: sink,
|
|
42
|
+
skewToleranceMs: 30000,
|
|
43
|
+
softBudgetMs: 60000,
|
|
44
|
+
clock,
|
|
45
|
+
});
|
|
46
|
+
await dispatcher.dispatch({ cron: '* * * * *', scheduledTime: scheduledMs });
|
|
47
|
+
const fired = events.filter((e) => e.event === 'cronFired');
|
|
48
|
+
const skewed = events.filter((e) => e.event === 'cronSkewed');
|
|
49
|
+
const alignedOk = fired.length === 1 && fired[0].outcome === 'onTime' && skewed.length === 0;
|
|
50
|
+
results.push({
|
|
51
|
+
anchorAcId: 'AC-32103-1',
|
|
52
|
+
verdict: alignedOk ? 'pass' : 'fail',
|
|
53
|
+
detail: alignedOk
|
|
54
|
+
? `aligned clock fired cronFired outcome=onTime; no cronSkewed; duration=${fired[0].duration}`
|
|
55
|
+
: `aligned-clock fault: cronFired=${fired.length} outcome=${fired[0]?.outcome} cronSkewed=${skewed.length}`,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// AC-32103-2: shifted clock 60s past scheduledMs; cronSkewed fires with deltaMs=60000; handler still runs.
|
|
60
|
+
{
|
|
61
|
+
const events = [];
|
|
62
|
+
const sink = (rec) => events.push(rec);
|
|
63
|
+
const scheduledMs = 1_700_000_000_000;
|
|
64
|
+
const shifted = scheduledMs + 60000;
|
|
65
|
+
let tick = 0;
|
|
66
|
+
const clock = () => shifted + tick++;
|
|
67
|
+
let handlerCalls = 0;
|
|
68
|
+
const dispatcher = createDispatcher({
|
|
69
|
+
routes: [{ expression: '* * * * *', handler: async () => { handlerCalls += 1; } }],
|
|
70
|
+
eventSink: sink,
|
|
71
|
+
skewToleranceMs: 30000,
|
|
72
|
+
softBudgetMs: 60000,
|
|
73
|
+
clock,
|
|
74
|
+
});
|
|
75
|
+
await dispatcher.dispatch({ cron: '* * * * *', scheduledTime: scheduledMs });
|
|
76
|
+
const skewed = events.filter((e) => e.event === 'cronSkewed');
|
|
77
|
+
const fired = events.filter((e) => e.event === 'cronFired');
|
|
78
|
+
const shiftedOk = skewed.length === 1 && skewed[0].deltaMs === 60000 && skewed[0].outcome === 'skewed' && handlerCalls === 1 && fired.length === 1;
|
|
79
|
+
results.push({
|
|
80
|
+
anchorAcId: 'AC-32103-2',
|
|
81
|
+
verdict: shiftedOk ? 'pass' : 'fail',
|
|
82
|
+
detail: shiftedOk
|
|
83
|
+
? `shifted-clock fired cronSkewed deltaMs=${skewed[0].deltaMs}; handler ran (${handlerCalls}); cronFired followed`
|
|
84
|
+
: `shifted-clock fault: cronSkewed=${skewed.length} deltaMs=${skewed[0]?.deltaMs} handlerCalls=${handlerCalls} cronFired=${fired.length}`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// AC-32104-1 / AC-32104-2: soft budget. Use a REAL clock and a REAL setTimeout so the dispatcher's
|
|
89
|
+
// internal soft-budget setTimeout fires deterministically. Handler resolves after 250ms; budget 100ms.
|
|
90
|
+
{
|
|
91
|
+
const events = [];
|
|
92
|
+
const sink = (rec) => events.push(rec);
|
|
93
|
+
const dispatcher = createDispatcher({
|
|
94
|
+
routes: [
|
|
95
|
+
{
|
|
96
|
+
expression: '* * * * *',
|
|
97
|
+
handler: async () => {
|
|
98
|
+
const wait = SIMULATE_SLOW_HANDLER ? 350 : 250;
|
|
99
|
+
await new Promise((r) => setTimeout(r, wait));
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
eventSink: sink,
|
|
104
|
+
skewToleranceMs: 60000,
|
|
105
|
+
softBudgetMs: 100,
|
|
106
|
+
});
|
|
107
|
+
const beforeMs = Date.now();
|
|
108
|
+
await dispatcher.dispatch({ cron: '* * * * *', scheduledTime: beforeMs });
|
|
109
|
+
const stalled = events.filter((e) => e.event === 'cronStalled');
|
|
110
|
+
const fired = events.filter((e) => e.event === 'cronFired');
|
|
111
|
+
const stalledOk = stalled.length === 1 && stalled[0].duration >= 100 && stalled[0].softBudgetMs === 100;
|
|
112
|
+
results.push({
|
|
113
|
+
anchorAcId: 'AC-32104-1',
|
|
114
|
+
verdict: stalledOk ? 'pass' : 'fail',
|
|
115
|
+
detail: stalledOk
|
|
116
|
+
? `softBudget breach: cronStalled fired once with duration=${stalled[0].duration}ms softBudgetMs=${stalled[0].softBudgetMs}`
|
|
117
|
+
: `soft-budget fault: cronStalled=${stalled.length} record=${JSON.stringify(stalled[0] ?? null)}`,
|
|
118
|
+
});
|
|
119
|
+
const continuedOk = fired.length === 1 && fired[0].duration >= 200;
|
|
120
|
+
results.push({
|
|
121
|
+
anchorAcId: 'AC-32104-2',
|
|
122
|
+
verdict: continuedOk ? 'pass' : 'fail',
|
|
123
|
+
detail: continuedOk
|
|
124
|
+
? `handler ran to completion after soft-budget breach; final cronFired duration=${fired[0].duration}ms`
|
|
125
|
+
: `continue fault: cronFired=${fired.length} record=${JSON.stringify(fired[0] ?? null)}`,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return { results };
|
|
130
|
+
}
|