rcf-lite 0.23.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 +18 -0
- package/blueprints/application-account-settings/docs/topics.md +7 -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 +7 -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 +7 -1
- package/blueprints/application-charts/docs/topics.md +7 -1
- package/blueprints/application-dashboard/docs/topics.md +7 -1
- package/blueprints/application-datatable/docs/topics.md +7 -1
- package/blueprints/application-empty-error-states/docs/topics.md +7 -1
- package/blueprints/application-error-handling/docs/topics.md +7 -1
- package/blueprints/application-file-upload/docs/topics.md +7 -1
- package/blueprints/application-forms-wizard/docs/topics.md +7 -1
- package/blueprints/application-notifications-in-app/docs/topics.md +7 -1
- package/blueprints/application-onboarding-tour/docs/topics.md +7 -1
- package/blueprints/application-spa/docs/topics.md +7 -1
- package/blueprints/delivery-ci-workflows/docs/topics.md +7 -1
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +7 -1
- 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 +7 -1
- package/blueprints/jobs-background/docs/topics.md +7 -1
- package/blueprints/messaging-queue-cloudflare/docs/topics.md +7 -1
- package/blueprints/object-storage-s3/docs/topics.md +7 -1
- package/blueprints/observability-essentials/docs/topics.md +7 -1
- package/blueprints/observability-logging/docs/topics.md +7 -1
- package/blueprints/observability-probe-endpoints/docs/topics.md +7 -1
- package/blueprints/persistence-data-d1/docs/topics.md +7 -1
- package/blueprints/persistence-data-postgres/docs/topics.md +7 -1
- package/blueprints/persistence-data-sqlite/docs/topics.md +7 -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 +7 -1
- package/blueprints/security-auth-keycloak/docs/topics.md +7 -1
- package/blueprints/security-auth-magic-link/docs/topics.md +7 -1
- package/blueprints/security-auth-oauth2/docs/topics.md +7 -1
- package/blueprints/security-secrets-management/docs/topics.md +7 -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-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-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-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-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-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 +11 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// edge-cloudflare-turnstile probe pack (v1.0.0).
|
|
2
|
+
//
|
|
3
|
+
// Four surface-observable checks per cloudflare-round-6-spec section 3.2:
|
|
4
|
+
// AC-turnstile-widgetRendered Turnstile widget mounts with the pinned always-pass sitekey and the mount injects no third-party script beyond the Cloudflare Turnstile host.
|
|
5
|
+
// AC-turnstile-serverVerified-pass Live POST to Cloudflare siteverify with always-pass secret returns success:true and the handler responds 200.
|
|
6
|
+
// AC-turnstile-serverVerified-fail Live POST to Cloudflare siteverify with always-fail secret returns success:false and the handler rejects 400.
|
|
7
|
+
// AC-turnstile-magicLinkGuard Magic-link mint route composed with the Turnstile guard refuses a mint submit without a valid Turnstile response with 400 and no mint side-effect.
|
|
8
|
+
//
|
|
9
|
+
// The pack ships no appliesTo predicate (Turnstile is not capability-gated per spec section 3.2). Every fixture
|
|
10
|
+
// that applies the blueprint fires every check. Runtime URL and browser are supplied by the pack runner; the
|
|
11
|
+
// dedicated pack fixture at packages/rcf-lite/test/fixtures/probe-pack-edge-cloudflare-turnstile pins the
|
|
12
|
+
// Cloudflare public test keys documented at https://developers.cloudflare.com/turnstile/troubleshooting/testing/.
|
|
13
|
+
|
|
14
|
+
function withUrl(runtimeUrl, path) {
|
|
15
|
+
return new URL(path, runtimeUrl).toString();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const CLOUDFLARE_TURNSTILE_ORIGIN = 'https://challenges.cloudflare.com';
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
packName: 'edge-cloudflare-turnstile',
|
|
22
|
+
version: '1.0.0',
|
|
23
|
+
blueprintSlug: 'edge-cloudflare-turnstile',
|
|
24
|
+
appliesTo: () => true,
|
|
25
|
+
boot: { bootCommand: null, waitForUrl: null, waitForSelector: null },
|
|
26
|
+
checks: [
|
|
27
|
+
{
|
|
28
|
+
id: 'AC-turnstile-widgetRendered',
|
|
29
|
+
severity: 'block',
|
|
30
|
+
description: 'Turnstile client widget mounts with the pinned always-pass sitekey; the mount injects Cloudflare Turnstile JS from the Cloudflare Turnstile origin only, populates the Cf-Turnstile-Response token input, and no third-party script from any other origin is loaded on the page.',
|
|
31
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
32
|
+
if (!browser) return { verdict: 'fail', detail: 'no packBrowser wired' };
|
|
33
|
+
await browser.goto(withUrl(runtimeUrl, '/?sitekey=pass'));
|
|
34
|
+
// Wait for the widget to inject the token. Turnstile fires the callback asynchronously and the always-pass
|
|
35
|
+
// test sitekey (1x00000000000000000000AA per Cloudflare testing docs) resolves without rendering an iframe.
|
|
36
|
+
await new Promise((r) => setTimeout(r, 6000));
|
|
37
|
+
const dom = await browser.evaluate((cfOrigin) => {
|
|
38
|
+
const widget = document.querySelector('[data-role="turnstile-widget"]');
|
|
39
|
+
const sitekeyEl = document.querySelector('[data-role="sitekey"]');
|
|
40
|
+
const scripts = Array.from(document.querySelectorAll('script[src]')).map((s) => s.src);
|
|
41
|
+
const cloudflareScripts = scripts.filter((s) => s.startsWith(cfOrigin));
|
|
42
|
+
const thirdParty = scripts.filter((s) => {
|
|
43
|
+
try { const u = new URL(s); if (u.origin === window.location.origin) return false; return u.origin !== cfOrigin; }
|
|
44
|
+
catch { return false; }
|
|
45
|
+
});
|
|
46
|
+
const tokenInputs = Array.from(document.querySelectorAll('input[name="cf-turnstile-response"]'));
|
|
47
|
+
const tokenValues = tokenInputs.map((i) => (i.value || '').slice(0, 8));
|
|
48
|
+
return {
|
|
49
|
+
widgetPresent: !!widget,
|
|
50
|
+
sitekey: sitekeyEl ? sitekeyEl.textContent.trim() : null,
|
|
51
|
+
scriptCount: scripts.length, cloudflareScriptCount: cloudflareScripts.length, thirdPartyScripts: thirdParty,
|
|
52
|
+
tokenInputCount: tokenInputs.length, tokenValueSample: tokenValues,
|
|
53
|
+
tokenPopulated: tokenInputs.some((i) => i.value && i.value.length > 0),
|
|
54
|
+
};
|
|
55
|
+
}, CLOUDFLARE_TURNSTILE_ORIGIN);
|
|
56
|
+
if (!dom.widgetPresent) return { verdict: 'fail', detail: 'Turnstile widget element [data-role="turnstile-widget"] not found on /?sitekey=pass' };
|
|
57
|
+
if (dom.cloudflareScriptCount < 1) return { verdict: 'fail', detail: `Cloudflare Turnstile JS not injected from ${cfOrigin}; scripts=${JSON.stringify(dom)}`.replace('${cfOrigin}', 'https://challenges.cloudflare.com') };
|
|
58
|
+
if (dom.thirdPartyScripts.length > 0) return { verdict: 'fail', detail: `third-party script(s) present beyond Cloudflare Turnstile: ${JSON.stringify(dom.thirdPartyScripts)}` };
|
|
59
|
+
if (dom.tokenInputCount < 1) return { verdict: 'fail', detail: `no cf-turnstile-response input in the page after widget mount; DOM=${JSON.stringify(dom)}` };
|
|
60
|
+
if (!dom.tokenPopulated) return { verdict: 'fail', detail: `cf-turnstile-response input not populated by Turnstile; token samples=${JSON.stringify(dom.tokenValueSample)}` };
|
|
61
|
+
return { verdict: 'pass', detail: `widget mounted; sitekey=${dom.sitekey}; cloudflareScripts=${dom.cloudflareScriptCount}; tokenPopulated=true tokenSample=${JSON.stringify(dom.tokenValueSample)}; thirdParty=0` };
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'AC-turnstile-serverVerified-pass',
|
|
66
|
+
severity: 'block',
|
|
67
|
+
description: 'Live POST to challenges.cloudflare.com/turnstile/v0/siteverify with the pinned always-pass secret returns success:true; the fixture /api/submit handler responds 200.',
|
|
68
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
69
|
+
// Server-side siteverify pass. Uses the browser as a driver to build a form submission then reads
|
|
70
|
+
// the server response.
|
|
71
|
+
const body = new URLSearchParams();
|
|
72
|
+
body.set('email', 'reviewer@example.com');
|
|
73
|
+
body.set('turnstile-sitekey', '1x00000000000000000000AA');
|
|
74
|
+
body.set('cf-turnstile-response', 'PACK-CHECK-PASS-TOKEN');
|
|
75
|
+
const resp = await fetch(withUrl(runtimeUrl, '/api/submit'), {
|
|
76
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body,
|
|
77
|
+
});
|
|
78
|
+
const text = await resp.text();
|
|
79
|
+
let json = null; try { json = JSON.parse(text); } catch { /* leave null */ }
|
|
80
|
+
const ok = resp.status === 200 && json && json.received === 'ok';
|
|
81
|
+
return {
|
|
82
|
+
verdict: ok ? 'pass' : 'fail',
|
|
83
|
+
detail: ok
|
|
84
|
+
? `serverVerified-pass: fixture /api/submit returned status=200 body=${text} (Cloudflare siteverify success:true with always-pass secret)`
|
|
85
|
+
: `serverVerified-pass unexpected shape status=${resp.status} body=${text}`,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'AC-turnstile-serverVerified-fail',
|
|
91
|
+
severity: 'block',
|
|
92
|
+
description: 'Live POST to Cloudflare siteverify with the pinned always-fail secret returns success:false; the fixture /api/submit handler rejects with 400 and refusal body carries errorCodes and no sitekey.',
|
|
93
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
94
|
+
const body = new URLSearchParams();
|
|
95
|
+
body.set('email', 'reviewer@example.com');
|
|
96
|
+
body.set('turnstile-sitekey', '2x00000000000000000000AB');
|
|
97
|
+
body.set('cf-turnstile-response', 'PACK-CHECK-FAIL-TOKEN');
|
|
98
|
+
const resp = await fetch(withUrl(runtimeUrl, '/api/submit?fail-secret=1'), {
|
|
99
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body,
|
|
100
|
+
});
|
|
101
|
+
const text = await resp.text();
|
|
102
|
+
let json = null; try { json = JSON.parse(text); } catch { /* leave null */ }
|
|
103
|
+
const ok = resp.status === 400 && json && json.errorCode === 'turnstile.siteverify-failed'
|
|
104
|
+
&& Array.isArray(json.errorCodes) && json.errorCodes.length > 0
|
|
105
|
+
&& !text.includes('2x00000000000000000000AB');
|
|
106
|
+
return {
|
|
107
|
+
verdict: ok ? 'pass' : 'fail',
|
|
108
|
+
detail: ok
|
|
109
|
+
? `serverVerified-fail: fixture rejected status=400 errorCode=turnstile.siteverify-failed errorCodes=${JSON.stringify(json.errorCodes)}; refusal body carries no sitekey`
|
|
110
|
+
: `serverVerified-fail unexpected shape status=${resp.status} body=${text}`,
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'AC-turnstile-magicLinkGuard',
|
|
116
|
+
severity: 'block',
|
|
117
|
+
description: 'Magic-link mint route composed with the Turnstile guard refuses a mint submit without a Turnstile response with 400 and refusal errorCode=turnstile.token-missing; no magic-link mint side-effect.',
|
|
118
|
+
run: async ({ browser, runtimeUrl }) => {
|
|
119
|
+
// Two probes: (a) missing token refuse (400), (b) fail-secret refuse (400).
|
|
120
|
+
const missingBody = new URLSearchParams();
|
|
121
|
+
missingBody.set('email', 'reviewer@example.com');
|
|
122
|
+
missingBody.set('turnstile-sitekey', '1x00000000000000000000AA');
|
|
123
|
+
const missingResp = await fetch(withUrl(runtimeUrl, '/api/magic-link'), {
|
|
124
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: missingBody,
|
|
125
|
+
});
|
|
126
|
+
const missingText = await missingResp.text();
|
|
127
|
+
let missingJson = null; try { missingJson = JSON.parse(missingText); } catch {}
|
|
128
|
+
const missingOk = missingResp.status === 400 && missingJson && missingJson.errorCode === 'turnstile.token-missing';
|
|
129
|
+
|
|
130
|
+
const failBody = new URLSearchParams();
|
|
131
|
+
failBody.set('email', 'reviewer@example.com');
|
|
132
|
+
failBody.set('turnstile-sitekey', '2x00000000000000000000AB');
|
|
133
|
+
failBody.set('cf-turnstile-response', 'MAGIC-LINK-PACK-FAIL-TOKEN');
|
|
134
|
+
const failResp = await fetch(withUrl(runtimeUrl, '/api/magic-link?fail-secret=1'), {
|
|
135
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: failBody,
|
|
136
|
+
});
|
|
137
|
+
const failText = await failResp.text();
|
|
138
|
+
let failJson = null; try { failJson = JSON.parse(failText); } catch {}
|
|
139
|
+
const failOk = failResp.status === 400 && failJson && failJson.errorCode === 'turnstile.siteverify-failed';
|
|
140
|
+
|
|
141
|
+
if (missingOk && failOk) return { verdict: 'pass', detail: `magic-link guard: missing-token refused 400 turnstile.token-missing; fail-secret refused 400 turnstile.siteverify-failed errorCodes=${JSON.stringify(failJson.errorCodes)}` };
|
|
142
|
+
return { verdict: 'fail', detail: `magic-link guard unexpected: missing status=${missingResp.status} body=${missingText}; fail status=${failResp.status} body=${failText}` };
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
@@ -35,7 +35,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
35
35
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
36
36
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
37
37
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
38
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
38
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
39
39
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
40
40
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
41
41
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -45,6 +45,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
45
45
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
46
46
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
47
47
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
48
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
49
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
50
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
51
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
52
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
53
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
48
54
|
|
|
49
55
|
US 4101-4106 sit at the LOW end of the 4101-4899 band on purpose. A project-side story that mechanically derives from an email-smtp-resend REQ id into the number `4106` (leading `4` + sequence `106`) would collide against email-smtp-resend-US-4106 in this package; the band leaves headroom at the HIGH end (US 4181-4899) so a project's own stories anchored to email-smtp-resend REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
50
56
|
|
|
@@ -39,13 +39,19 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
39
39
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
40
40
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
41
41
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
42
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
42
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
43
43
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
45
45
|
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
46
46
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
47
47
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
48
48
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
49
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
50
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
51
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
52
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
53
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
54
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
49
55
|
|
|
50
56
|
US 30101-30109 sit at the LOW end of the 30101-30899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a jobs-background REQ id into the number 30110 would collide against a shipped US-30110; band headroom (30110-30899) leaves that space.
|
|
51
57
|
|
|
@@ -39,13 +39,19 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
39
39
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
40
40
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
41
41
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
42
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
42
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
43
43
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
45
45
|
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
46
46
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
47
47
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
48
48
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
49
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
50
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
51
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
52
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
53
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
54
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
49
55
|
|
|
50
56
|
US 29101-29108 sit at the LOW end of the 29101-29899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a messaging-queue-cloudflare REQ id into the number 29110 would collide against a shipped US-29110; band headroom (29109-29899) leaves that space.
|
|
51
57
|
|
|
@@ -39,7 +39,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
39
39
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
40
40
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
41
41
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
42
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
42
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
43
43
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
45
45
|
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
@@ -48,6 +48,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
48
48
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
49
49
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
50
50
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
51
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
52
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
53
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
54
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
55
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
56
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
51
57
|
|
|
52
58
|
US 28101-28108 sit at the LOW end of the 28101-28899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from an object-storage-s3 REQ id into the number 28110 would collide against a shipped US-28110; band headroom (28109-28899) leaves that space.
|
|
53
59
|
|
|
@@ -54,7 +54,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
54
54
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
55
55
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
56
56
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
57
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
57
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
58
58
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
59
59
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
60
60
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -64,6 +64,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
64
64
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
65
65
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
66
66
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
67
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
68
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
69
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
70
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
71
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
72
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
67
73
|
|
|
68
74
|
US 7101-7110 sit at the LOW end of the 7101-7899 band on purpose. A project-side story that mechanically derives from an observability-essentials REQs id into the number `7110` would collide against observability-essentials-US-7110 in this package; the band leaves headroom at the HIGH end (US 7181-7899) so a project's own stories anchored to observability-essentials REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
69
75
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
22
22
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
23
23
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
24
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
24
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
25
25
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
26
26
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
27
27
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -31,5 +31,11 @@
|
|
|
31
31
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
32
32
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
33
33
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
34
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
35
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
36
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
37
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
38
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
39
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
34
40
|
|
|
35
41
|
The shelf-wide band registry lives in `packages/rcf-lite/docs/blueprint-authoring.md` section 5.
|
|
@@ -44,7 +44,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
44
44
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
45
45
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
46
46
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
47
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
47
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
48
48
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
49
49
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
50
50
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -54,6 +54,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
54
54
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
55
55
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
56
56
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
57
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
58
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
59
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
60
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
61
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
62
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
57
63
|
|
|
58
64
|
US 14101-14108 sit at the LOW end of the 14101-14899 band on purpose. A project-side story that mechanically derives from an observability-probe-endpoints REQ id into the number `14108` would collide against observability-probe-endpoints-US-14108 in this package; the band leaves headroom at the HIGH end (US 14181-14899) so a project's own stories anchored to observability-probe-endpoints REQs can allocate without conflict. The watchpost run4 lesson applies here too. Band spacing between the previous HQ-lane row (persistence-data-d1, 13101-13899, 14xx) and this one (14101-14899, 15xx) reflects the four-digit widening pattern opened by security-auth-clerk at 10xx and continued through the round-2 HQ lane.
|
|
59
65
|
|
|
@@ -42,7 +42,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
42
42
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
43
43
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
45
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
45
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
46
46
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
47
47
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
48
48
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -52,6 +52,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
52
52
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
53
53
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
54
54
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
55
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
56
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
57
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
58
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
59
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
60
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
55
61
|
|
|
56
62
|
US 13101-13107 sit at the LOW end of the 13101-13899 band on purpose. A project-side story that mechanically derives from a persistence-data-d1 REQ id into the number `13107` would collide against persistence-data-d1-US-13107 in this package; the band leaves headroom at the HIGH end (US 13181-13899) so a project's own stories anchored to persistence-data-d1 REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
57
63
|
|
|
@@ -42,7 +42,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
42
42
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
43
43
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
45
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
45
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
46
46
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
47
47
|
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
48
48
|
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
@@ -50,6 +50,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
50
50
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
51
51
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
52
52
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
53
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
54
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
55
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
56
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
57
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
58
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
53
59
|
|
|
54
60
|
US 27101-27110 sit at the LOW end of the 27101-27899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a persistence-data-postgres REQ id into the number 27110 would collide against the shipped US-27110; band headroom (27111-27899) leaves that space.
|
|
55
61
|
|
|
@@ -42,7 +42,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
42
42
|
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
43
43
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
45
|
-
| application-admin-console | 21101-21899 | 22xx | shipped v1.
|
|
45
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
46
46
|
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
47
47
|
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
48
48
|
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
@@ -52,6 +52,12 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
52
52
|
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
53
53
|
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
54
54
|
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
55
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
56
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
57
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
58
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
59
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
60
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
55
61
|
|
|
56
62
|
US 5101-5111 sit at the LOW end of the 5101-5899 band on purpose. A project-side story that mechanically derives from `persistence-data-sqlite-REQ-011` into the number `5111` would collide against persistence-data-sqlite-US-5111 in this package; the band leaves headroom at the HIGH end (US 5181-5899) so a project's own stories anchored to persistence-data-sqlite REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
57
63
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `platform-cloudflare-cron-triggers` are recorded here. The shape follows Keep a Changelog and Semantic Versioning per the blueprint authoring standard.
|
|
4
|
+
|
|
5
|
+
## 1.0.0 (2026-09-07)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- v1.0.0 mint of the `platform-cloudflare-cron-triggers` blueprint, category `platform`, capabilities `["scheduledTrigger"]`. Ships a scheduled() handler over the Cloudflare Workers Cron Trigger event, an expression-routed dispatcher over multiple cron expressions, a skew-tolerance classifier, a soft-budget observer, and five metadata-only lifecycle events (`cronReady`, `cronFired`, `cronSkewed`, `cronStalled`, `cronUnmatched`).
|
|
10
|
+
- 4 REQs (`platform-cloudflare-cron-triggers-REQ-001..004`), 7 USs (`platform-cloudflare-cron-triggers-US-32101..32107`), 3 TACs (`TAC-3301` scheduled handler, `TAC-3302` expression-router dispatcher, `TAC-3303` lifecycle-event sink), 3 ADRs (`ADR-3301` scope-global on new topic `scheduledTriggerContract` with `standardsTraceClause: Cloudflare Workers Cron Triggers documented shape`; `ADR-3302` dispatcher mode `elicited: true` `recommendedDefault: expression-routed` when more than one cron expression is elicited; `ADR-3303` default skew tolerance 30 seconds floor 5 ceiling 300 `elicited: true`).
|
|
11
|
+
- 5 Node-only probes under `contributions/probes/`: `wrangler-test-scheduled` (drives `wrangler dev --test-scheduled` on the shared cf-platform fixture, `warn` on CLI regression per spec section 3.1), `dispatcher-routing`, `skew-tolerance` (also folds AC-32104 soft-budget as additional results), `event-secrecy` (SIMULATE_PII_LEAK=true mutation surfaces the leaked fields), and `real-account-scheduled-smoke` (`accountBound: true`; skipped in CI without `CI_HAS_CLOUDFLARE_ACCOUNT`).
|
|
12
|
+
- Elicited parameters on `blueprint.json`: `cron-expressions` (default `* * * * *`), `cron-dispatcher-mode` (default `expression-routed`), `cron-skew-tolerance-seconds` (default `30`, floor `5`, ceiling `300`), `cron-soft-budget-seconds` (default `30`).
|
|
13
|
+
- `suggestedCompanions`: `logging` (for the event-sink boundary) and `errorHandling` (for the handler-failure boundary).
|
|
14
|
+
- Extends the shared `cf-platform` sample-app fixture with the `[triggers] crons` block on `wrangler.toml`, the sole-reader scheduled handler (`src/scheduled.mjs`), and the expression-routed dispatcher (`src/dispatcher.mjs`). The T-0 `[assets]` block and the T-1 `[[kv_namespaces]]` block are preserved verbatim; the scheduled handler does NOT dereference `env.CACHE` (KV stays owned by the T-1 facade).
|
|
15
|
+
- Anatomy test at `packages/rcf-lite/test/blueprint/platform-cloudflare-cron-triggers-anatomy.test.js` covers `TS-090..096` on the T-2 chain slice (blueprint shape, contributions cross-check, probe module contracts, fixture files, ADR bodies and clauses, guide sections and URLs, three-state probed verdicts).
|
|
16
|
+
|
|
17
|
+
### Known limitations
|
|
18
|
+
|
|
19
|
+
- The `real-account-scheduled-smoke` probe records `accountBoundSkipped: true` and aggregates to `pass` when `CI_HAS_CLOUDFLARE_ACCOUNT` is unset (spec section 3.5 pass-with-skip). Full mechanism reach requires a CI environment with the paired `CF_ACCOUNT_ID`, `CF_WORKER_NAME` and `CF_API_TOKEN` env vars plus a deployed Worker running a per-minute cron.
|
|
20
|
+
- The `wrangler-test-scheduled` probe returns `warn` (never `fail`) on a CLI regression that prevents `wrangler dev --test-scheduled` from binding within 30 seconds; the in-process `dispatcher-routing` and `skew-tolerance` probes carry the runtime evidence for the shipped handler regardless.
|
|
21
|
+
- The dispatcher does NOT terminate a handler on soft-budget breach; termination is Cloudflare's platform-level concern. A project that needs hard termination on a stalled fire builds it inside the handler code path against `AbortController`.
|
|
22
|
+
- The loader's supported `when` block on `elicits[]` only accepts `requiresCapability` arrays, so `cron-dispatcher-mode` cannot yet gate its `expression-routed` default on `elicitedNonEmpty` over `cron-expressions`. A future loader minor extending `validateElicits` would close that gap; the elicit fires unconditionally today and the guide teaches the pattern.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# platform-cloudflare-cron-triggers
|
|
2
|
+
|
|
3
|
+
A rcf-lite blueprint that ships a small, opinionated wiring over
|
|
4
|
+
Cloudflare Workers Cron Triggers. One module holds the scheduled
|
|
5
|
+
handler; a dispatcher routes multiple cron expressions to distinct
|
|
6
|
+
handlers; every fire emits a metadata-only lifecycle event a
|
|
7
|
+
logging companion can render without ever writing a body byte.
|
|
8
|
+
|
|
9
|
+
- Version: `1.0.0`
|
|
10
|
+
- Category: `platform`
|
|
11
|
+
- Capabilities: `["scheduledTrigger"]`
|
|
12
|
+
- Suggested companions: `logging`, `errorHandling`
|
|
13
|
+
|
|
14
|
+
## What it gives you
|
|
15
|
+
|
|
16
|
+
- One place that dereferences the Cloudflare Workers Cron Trigger
|
|
17
|
+
event (`src/scheduled.mjs`), wires the dispatcher and the event
|
|
18
|
+
sink at boot, and emits `cronReady` on the first ready-check.
|
|
19
|
+
- An expression-routed dispatcher (`src/dispatcher.mjs`) that maps
|
|
20
|
+
cron expressions to distinct handlers, records `cronUnmatched`
|
|
21
|
+
on an unknown expression, and observes each fire against a
|
|
22
|
+
skew-tolerance window and a soft budget.
|
|
23
|
+
- Five metadata-only lifecycle events (`cronReady`, `cronFired`,
|
|
24
|
+
`cronSkewed`, `cronStalled`, `cronUnmatched`) with a bounded
|
|
25
|
+
payload shape `{event, expression, scheduledTime, outcome,
|
|
26
|
+
duration}` plus optional numeric fields (`softBudgetMs`,
|
|
27
|
+
`deltaMs`). Two-layer secrecy assertion in the event-secrecy
|
|
28
|
+
probe.
|
|
29
|
+
- A decision-tree cross-reference in the guide to `jobs-background`
|
|
30
|
+
(round 5) and to the follow-up Workflows adapter (round 6 jobs-
|
|
31
|
+
background 1.1.0 minor bump per spec section 5.7) for cases that
|
|
32
|
+
need durable, retried, workflow-shaped scheduled work.
|
|
33
|
+
|
|
34
|
+
## The four REQs
|
|
35
|
+
|
|
36
|
+
| REQ | What |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `platform-cloudflare-cron-triggers-REQ-001` | The scheduled() handler is the sole reader of the Cron Trigger event and opens on boot with `cronReady`. |
|
|
39
|
+
| `platform-cloudflare-cron-triggers-REQ-002` | Multiple cron expressions route to distinct handlers via the expression-router dispatcher. |
|
|
40
|
+
| `platform-cloudflare-cron-triggers-REQ-003` | Skew tolerance: fires observed inside the elicited window are `onTime`; outside record `cronSkewed` with the delta. |
|
|
41
|
+
| `platform-cloudflare-cron-triggers-REQ-004` | Soft budget: a handler running past the elicited budget fires `cronStalled` but the dispatcher does not terminate; every event record is metadata-only. |
|
|
42
|
+
|
|
43
|
+
## The wired shape
|
|
44
|
+
|
|
45
|
+
The scheduled handler is the ONE place the Cron Trigger event lives.
|
|
46
|
+
The dispatcher factors the routing, skew and soft-budget concerns
|
|
47
|
+
into one seam. The public surface is:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
createScheduledHandler({ routes, eventSink, skewToleranceMs, softBudgetMs, clock? })
|
|
51
|
+
-> { ready, scheduled }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The dispatcher underneath:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
createDispatcher({ routes, eventSink, skewToleranceMs, softBudgetMs, clock? })
|
|
58
|
+
-> { dispatch }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Elicited parameters
|
|
62
|
+
|
|
63
|
+
- `cron-expressions` (default `* * * * *`): the cron expressions
|
|
64
|
+
to schedule; the operator's comma-separated list is written into
|
|
65
|
+
`wrangler.toml` under `[triggers] crons`.
|
|
66
|
+
- `cron-dispatcher-mode` (default `expression-routed` when the
|
|
67
|
+
elicited list has more than one entry, else `single-handler`):
|
|
68
|
+
the dispatcher mode per `ADR-3302`.
|
|
69
|
+
- `cron-skew-tolerance-seconds` (default `30`, floor `5`, ceiling
|
|
70
|
+
`300`): the skew tolerance window per `ADR-3303`.
|
|
71
|
+
- `cron-soft-budget-seconds` (default `30`, no floor): the
|
|
72
|
+
per-handler soft budget.
|
|
73
|
+
|
|
74
|
+
## The five probes
|
|
75
|
+
|
|
76
|
+
The five probes live under `contributions/probes/`. Each has a
|
|
77
|
+
matching `run-<probe-name>.mjs` shim that writes a per-blueprint
|
|
78
|
+
report to `.rcf/reports/blueprints/platform-cloudflare-cron-triggers/<probe-name>.json`
|
|
79
|
+
under the fixture root.
|
|
80
|
+
|
|
81
|
+
| Probe | Anchor AC | Account-bound | What it drives |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| `wrangler-test-scheduled.mjs` | `AC-32105-1` | no | Spawns `wrangler dev --test-scheduled` on the cf-platform fixture, waits bounded 30 seconds for it to bind, drives `/__scheduled?cron=<expr>`, asserts status 200 and kills wrangler cleanly. Returns `warn` on a CLI regression per spec section 3.1 pass-with-skip. |
|
|
84
|
+
| `dispatcher-routing.mjs` | `AC-32102-1` | no | Wires two spy handlers on two expressions, drives the matched expression (asserting only the routed spy fires with the bounded context), then an unmatched expression (asserting `cronUnmatched` fires and no spy runs). Also covers `AC-32102-2`. |
|
|
85
|
+
| `skew-tolerance.mjs` | `AC-32103-1` | no | Drives the dispatcher against a fake clock aligned to `scheduledTime` (asserting `cronFired` outcome `onTime`) then advanced 60s past (asserting `cronSkewed` with `deltaMs: 60000` and the handler still runs). Also folds soft-budget as additional results: a spy handler resolving after 250ms with `softBudgetMs=100` fires exactly one `cronStalled` at the crossing and a final `cronFired` follows (covers `AC-32103-2`, `AC-32104-1`, `AC-32104-2`). |
|
|
86
|
+
| `event-secrecy.mjs` | `AC-32106-1` | no | Drives the dispatcher with a spy handler that closes over a PII fixture (`{userId, ssn}`); layer-1 asserts every event record's keys are a subset of the allow-list `{event, expression, scheduledTime, outcome, duration, softBudgetMs, deltaMs}`; layer-2 asserts no PII substring in the JSON serialisation. `SIMULATE_PII_LEAK=true` wraps the sink to forward the closure so the mutation-run surfaces the leaked fields and returns `fail`. |
|
|
87
|
+
| `real-account-scheduled-smoke.mjs` | `AC-32107-1` | yes | Polls the Cloudflare Workers analytics API for the named Worker every 5s, waits bounded 90s for a scheduled event to appear. Without `CI_HAS_CLOUDFLARE_ACCOUNT` the probe records `accountBoundSkipped: true` and aggregates to `pass` per spec section 3.5. |
|
|
88
|
+
|
|
89
|
+
## Known limitations (per-AC mechanism reach)
|
|
90
|
+
|
|
91
|
+
- **`AC-32105-1` (wrangler dev --test-scheduled)** requires the
|
|
92
|
+
fixture's `wrangler` devDependency to be installed
|
|
93
|
+
(`pnpm install --ignore-workspace` in
|
|
94
|
+
`packages/rcf-lite/test/fixtures/cf-platform`). Without it the
|
|
95
|
+
probe returns `warn` with a documented gap; the shipped
|
|
96
|
+
`src/scheduled.mjs` is still exercised end to end by the
|
|
97
|
+
in-process dispatcher probes.
|
|
98
|
+
- **`AC-32107-1` (real-account live-cron smoke)** requires a live
|
|
99
|
+
Cloudflare account with a deployed Worker running a per-minute
|
|
100
|
+
cron plus the paired `CI_HAS_CLOUDFLARE_ACCOUNT=true`,
|
|
101
|
+
`CF_ACCOUNT_ID`, `CF_WORKER_NAME` and `CF_API_TOKEN` env vars.
|
|
102
|
+
Without them the probe records `accountBoundSkipped: true` and
|
|
103
|
+
aggregates to `pass` per spec section 3.5. Full mechanism reach
|
|
104
|
+
requires a CI environment with those env vars set and a Worker
|
|
105
|
+
already deployed.
|
|
106
|
+
- **The dispatcher does NOT terminate a handler on soft-budget
|
|
107
|
+
breach.** Termination is Cloudflare's platform-level concern
|
|
108
|
+
per https://developers.cloudflare.com/workers/platform/limits/.
|
|
109
|
+
A project that needs hard termination on a stalled fire builds
|
|
110
|
+
it inside the handler code path against `AbortController`; the
|
|
111
|
+
dispatcher's role stops at the `cronStalled` event.
|
|
112
|
+
- **The dispatcher matches by exact string equality on the cron
|
|
113
|
+
expression.** Wildcarded expression sets or expression-family
|
|
114
|
+
routing (a single handler for every `*/5 * * * *`-like schedule)
|
|
115
|
+
are not shipped. A follow-up minor could add a matcher-shape
|
|
116
|
+
dispatch mode; today the elicited expression list is a
|
|
117
|
+
one-to-one mapping.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "platform-cloudflare-cron-triggers",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "platform",
|
|
5
|
+
"capabilities": ["scheduledTrigger"],
|
|
6
|
+
"suggestedCompanions": [
|
|
7
|
+
{
|
|
8
|
+
"role": "logging",
|
|
9
|
+
"reason": "Every scheduled fire emits a metadata-only lifecycle event through the applied logger; a logging companion supplies the sink factory."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"role": "errorHandling",
|
|
13
|
+
"reason": "A handler failure inside a scheduled invocation constructs an internal error record; an error-handling companion supplies the record factory and the boundary."
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"elicits": [
|
|
17
|
+
{
|
|
18
|
+
"id": "cron-expressions",
|
|
19
|
+
"prompt": "Cron expressions to schedule (comma-separated list of POSIX cron strings; each expression pairs with one handler under the dispatcher; recommended shape at least one).",
|
|
20
|
+
"kind": "string",
|
|
21
|
+
"default": "* * * * *"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "cron-dispatcher-mode",
|
|
25
|
+
"prompt": "Dispatcher mode: single-handler routes every fire to one handler; expression-routed maps each expression to a distinct handler (per ADR-3302; recommended default expression-routed when more than one cron expression is elicited).",
|
|
26
|
+
"kind": "enum",
|
|
27
|
+
"options": ["single-handler", "expression-routed"],
|
|
28
|
+
"default": "expression-routed"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "cron-skew-tolerance-seconds",
|
|
32
|
+
"prompt": "Skew tolerance in seconds; fires observed within the window are onTime, fires outside record cronSkewed with the delta (per ADR-3303; floor 5 seconds, ceiling 300 seconds).",
|
|
33
|
+
"kind": "string",
|
|
34
|
+
"default": "30"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "cron-soft-budget-seconds",
|
|
38
|
+
"prompt": "Soft budget per handler in seconds; a handler running past this budget logs cronStalled but is not terminated by the dispatcher (Cloudflare's platform concern retains termination). Recommended default 30.",
|
|
39
|
+
"kind": "string",
|
|
40
|
+
"default": "30"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"contributions": [
|
|
44
|
+
{ "id": "platform-cloudflare-cron-triggers-REQ-001", "kind": "req", "path": "requirements/platform-cloudflare-cron-triggers-req-001.json" },
|
|
45
|
+
{ "id": "platform-cloudflare-cron-triggers-REQ-002", "kind": "req", "path": "requirements/platform-cloudflare-cron-triggers-req-002.json" },
|
|
46
|
+
{ "id": "platform-cloudflare-cron-triggers-REQ-003", "kind": "req", "path": "requirements/platform-cloudflare-cron-triggers-req-003.json" },
|
|
47
|
+
{ "id": "platform-cloudflare-cron-triggers-REQ-004", "kind": "req", "path": "requirements/platform-cloudflare-cron-triggers-req-004.json" },
|
|
48
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32101", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32101.json" },
|
|
49
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32102", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32102.json" },
|
|
50
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32103", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32103.json" },
|
|
51
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32104", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32104.json" },
|
|
52
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32105", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32105.json" },
|
|
53
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32106", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32106.json" },
|
|
54
|
+
{ "id": "platform-cloudflare-cron-triggers-US-32107", "kind": "us", "path": "user-stories/platform-cloudflare-cron-triggers-us-32107.json" },
|
|
55
|
+
{ "id": "TAC-3301-platform-cloudflare-cron-triggers-scheduled-handler", "kind": "tac", "path": "tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json" },
|
|
56
|
+
{ "id": "TAC-3302-platform-cloudflare-cron-triggers-expression-router", "kind": "tac", "path": "tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json" },
|
|
57
|
+
{ "id": "TAC-3303-platform-cloudflare-cron-triggers-event-sink", "kind": "tac", "path": "tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json" },
|
|
58
|
+
{
|
|
59
|
+
"id": "ADR-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract",
|
|
60
|
+
"kind": "adr",
|
|
61
|
+
"path": "adrs/adr-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract.json",
|
|
62
|
+
"scope": "global",
|
|
63
|
+
"topic": "scheduledTriggerContract",
|
|
64
|
+
"recommendedDefault": true,
|
|
65
|
+
"elicited": false,
|
|
66
|
+
"standardsTraceClause": "Cloudflare Workers Cron Triggers documented shape"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "ADR-3302-platform-cloudflare-cron-triggers-dispatcher-mode",
|
|
70
|
+
"kind": "adr",
|
|
71
|
+
"path": "adrs/adr-3302-platform-cloudflare-cron-triggers-dispatcher-mode.json",
|
|
72
|
+
"recommendedDefault": true,
|
|
73
|
+
"elicited": true,
|
|
74
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "ADR-3303-platform-cloudflare-cron-triggers-skew-tolerance-default",
|
|
78
|
+
"kind": "adr",
|
|
79
|
+
"path": "adrs/adr-3303-platform-cloudflare-cron-triggers-skew-tolerance-default.json",
|
|
80
|
+
"recommendedDefault": true,
|
|
81
|
+
"elicited": true,
|
|
82
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|