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-3404-platform-cloudflare-durable-objects-migrations-shape",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Migration-safe class exports: stable class names and a wrangler migrations table",
|
|
8
|
+
"context": "A Cloudflare Durable Object class is identified by its name string in wrangler.toml. A rename that is not paired with a wrangler [[migrations]] block reads the runtime as a brand-new class over the existing objects' storage, which is a data-loss shape. The DO migration documentation (https://developers.cloudflare.com/durable-objects/) requires the migrations list to record every class name change on a tag boundary.",
|
|
9
|
+
"decision": "The applying project commits the DO class names (SingleCellObject, HubObject on the fixture; elicited names in a real project) as stable strings under [[durable_objects.bindings]] blocks with a paired [[migrations]] block at the v1 mint tag. A future rename or deprecation ships as a subsequent migrations tag on the same list; the shipped anatomy assertion greps the toml for each name and the migrations pair so a self-review catches an accidental rename.",
|
|
10
|
+
"consequences": "The applying project inherits Cloudflare's migration contract; a rename with a matching migration is safe, a rename without one is a runtime error the anatomy assertion catches at self-review. Standards trace clause: Cloudflare Durable Objects migration documentation (per https://developers.cloudflare.com/durable-objects/).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3405-platform-cloudflare-durable-objects-hibernation-posture",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Hibernation posture on the hub shape: elicited hibernate-after-idle window and idempotent wake handler (elicited)",
|
|
8
|
+
"context": "The hub shape hibernates when idle; the wake handler runs from cold on the next message. The hibernate-after-idle window trades a cold-start hit on the first wake against the memory footprint of an always-warm object. The window is a per-project answer; the shipped default (Cloudflare's platform-default) is fine for most projects but a coordinated-multiplayer workload with tight latency budgets picks a longer window.",
|
|
9
|
+
"decision": "The applied blueprint elicits do-hub-hibernate-after-idle-ms at apply time (a bounded millis integer). The wake handler MUST be idempotent-by-contract: repeated wakes on the same last-persisted message do not double-emit downstream state. The shipped HubObject class realises the idempotent-wake contract via a boolean _woke gate paired with the persisted lastBroadcast key; the anatomy assertion covers the once-per-wake doWakeUp event under AC-33110-1.",
|
|
10
|
+
"consequences": "Projects with tight latency budgets pick a longer window; projects with tight memory budgets pick a shorter one. Standards trace clause: generic enterprise practice (the hibernate-after-idle trade is a general enterprise-tier state-hosting choice, not a Cloudflare-specific claim; Cloudflare's platform-default is the shipped fallback).",
|
|
11
|
+
"alternativesConsidered": [],
|
|
12
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
13
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
14
|
+
}
|
package/blueprints/platform-cloudflare-durable-objects/contributions/probes/alarm-fires-once.mjs
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Alarm-fires-once probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Sets an alarm on a SingleCellObject for the current clock time,
|
|
4
|
+
// drives alarm() once, asserts the doAlarmFired event fires with
|
|
5
|
+
// {objectName, scheduledTime}, and asserts a second alarm() call
|
|
6
|
+
// on the drained storage records scheduledTime null (the alarm was
|
|
7
|
+
// consumed by the first fire, matching the once-per-schedule
|
|
8
|
+
// contract). The clock is fixed to a fresh integer so the assertion
|
|
9
|
+
// is deterministic.
|
|
10
|
+
//
|
|
11
|
+
// anchorAcId: AC-33104-1.
|
|
12
|
+
// accountBound: false.
|
|
13
|
+
|
|
14
|
+
export const anchorAcId = 'AC-33104-1';
|
|
15
|
+
export const accountBound = false;
|
|
16
|
+
|
|
17
|
+
export default async function runProbe() {
|
|
18
|
+
const { createInMemoryDoStorage } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-storage.mjs');
|
|
19
|
+
const { SingleCellObject } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-single-cell.mjs');
|
|
20
|
+
|
|
21
|
+
const events = [];
|
|
22
|
+
const eventSink = (rec) => events.push(rec);
|
|
23
|
+
const fixedNow = 1_800_000_000_000; // 2027-01 fixed instant, deterministic
|
|
24
|
+
const clock = () => fixedNow;
|
|
25
|
+
const storage = createInMemoryDoStorage({ backend: 'sql' });
|
|
26
|
+
const cell = new SingleCellObject({ storage, eventSink, name: 'alarm-1', clock });
|
|
27
|
+
|
|
28
|
+
const results = [];
|
|
29
|
+
|
|
30
|
+
const { scheduledTime } = await cell.setAlarm(100);
|
|
31
|
+
await cell.alarm();
|
|
32
|
+
const firstFires = events.filter((e) => e.event === 'doAlarmFired');
|
|
33
|
+
const stillPersisted = await storage.getAlarm();
|
|
34
|
+
const firstOk =
|
|
35
|
+
firstFires.length === 1 &&
|
|
36
|
+
firstFires[0].objectName === 'alarm-1' &&
|
|
37
|
+
firstFires[0].scheduledTime === scheduledTime &&
|
|
38
|
+
stillPersisted === null;
|
|
39
|
+
results.push({
|
|
40
|
+
anchorAcId: 'AC-33104-1',
|
|
41
|
+
verdict: firstOk ? 'pass' : 'fail',
|
|
42
|
+
detail: firstOk
|
|
43
|
+
? `alarm() fired once; doAlarmFired carried objectName=alarm-1 scheduledTime=${scheduledTime}; storage.getAlarm() drained to null`
|
|
44
|
+
: `alarm-fires-once fault: fires=${firstFires.length} record=${JSON.stringify(firstFires[0] ?? null)} storageAlarm=${stillPersisted}`,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Second alarm() on the drained storage records scheduledTime null.
|
|
48
|
+
events.length = 0;
|
|
49
|
+
await cell.alarm();
|
|
50
|
+
const secondFires = events.filter((e) => e.event === 'doAlarmFired');
|
|
51
|
+
const secondOk =
|
|
52
|
+
secondFires.length === 1 &&
|
|
53
|
+
secondFires[0].scheduledTime === null;
|
|
54
|
+
results.push({
|
|
55
|
+
anchorAcId: 'AC-33104-1',
|
|
56
|
+
verdict: secondOk ? 'pass' : 'fail',
|
|
57
|
+
detail: secondOk
|
|
58
|
+
? `second alarm() on drained storage recorded scheduledTime null (no re-fire for the same schedule)`
|
|
59
|
+
: `second-alarm behaviour mismatch: fires=${secondFires.length} record=${JSON.stringify(secondFires[0] ?? null)}`,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return { results };
|
|
63
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Namespace-facade-ready probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Opens the DO facade against an in-process pair of DO instances
|
|
4
|
+
// (a SingleCellObject wired to the in-memory storage driver and a
|
|
5
|
+
// HubObject wired to a fake state), calls ready(), asserts
|
|
6
|
+
// namespaceReady fires on the injected sink with a metadata-only
|
|
7
|
+
// payload {event, key, size, ttl, timestamp} and asserts the
|
|
8
|
+
// facade exposes cell(name) and hub(name) handles that return the
|
|
9
|
+
// registered instances.
|
|
10
|
+
//
|
|
11
|
+
// anchorAcId: AC-33101-1.
|
|
12
|
+
// accountBound: false.
|
|
13
|
+
|
|
14
|
+
export const anchorAcId = 'AC-33101-1';
|
|
15
|
+
export const accountBound = false;
|
|
16
|
+
|
|
17
|
+
export default async function runProbe() {
|
|
18
|
+
const { createInMemoryDoStorage } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-storage.mjs');
|
|
19
|
+
const { SingleCellObject } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-single-cell.mjs');
|
|
20
|
+
const { HubObject } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-hub.mjs');
|
|
21
|
+
const { createDoFacadeInProcess } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-facade.mjs');
|
|
22
|
+
const { createFakeState } = await import('./probe-utils.mjs');
|
|
23
|
+
|
|
24
|
+
const events = [];
|
|
25
|
+
const eventSink = (rec) => events.push(rec);
|
|
26
|
+
|
|
27
|
+
const cellStorage = createInMemoryDoStorage({ backend: 'sql' });
|
|
28
|
+
const hubStorage = createInMemoryDoStorage({ backend: 'sql' });
|
|
29
|
+
const singleCell = new SingleCellObject({ storage: cellStorage, eventSink, name: 'main' });
|
|
30
|
+
const hub = new HubObject({ state: createFakeState(), storage: hubStorage, eventSink, name: 'lobby' });
|
|
31
|
+
const facade = createDoFacadeInProcess({ singleCell, hub, eventSink });
|
|
32
|
+
|
|
33
|
+
const results = [];
|
|
34
|
+
|
|
35
|
+
await facade.ready();
|
|
36
|
+
const ready = events.filter((e) => e.event === 'namespaceReady');
|
|
37
|
+
const allowed = new Set(['event', 'key', 'size', 'ttl', 'timestamp']);
|
|
38
|
+
const extra = ready[0] ? Object.keys(ready[0]).filter((k) => !allowed.has(k)) : ['(no record)'];
|
|
39
|
+
const readyOk = ready.length === 1 && ready[0].key === null && ready[0].size === 0 && ready[0].ttl === null && extra.length === 0;
|
|
40
|
+
results.push({
|
|
41
|
+
anchorAcId: 'AC-33101-1',
|
|
42
|
+
verdict: readyOk ? 'pass' : 'fail',
|
|
43
|
+
detail: readyOk
|
|
44
|
+
? `namespaceReady fired once; payload keys drawn from allowed set {event,key,size,ttl,timestamp}; key=null size=0 ttl=null timestamp=${ready[0].timestamp}`
|
|
45
|
+
: `namespaceReady expected once with allowed keys only; observed count=${ready.length} extraKeys=${JSON.stringify(extra)} record=${JSON.stringify(ready[0] ?? null)}`,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const cellBack = facade.cell('main');
|
|
49
|
+
const hubBack = facade.hub('lobby');
|
|
50
|
+
const handlesOk = cellBack === singleCell && hubBack === hub;
|
|
51
|
+
results.push({
|
|
52
|
+
anchorAcId: 'AC-33101-1',
|
|
53
|
+
verdict: handlesOk ? 'pass' : 'fail',
|
|
54
|
+
detail: handlesOk
|
|
55
|
+
? `facade.cell("main") returned the registered SingleCellObject and facade.hub("lobby") returned the registered HubObject`
|
|
56
|
+
: `facade handle lookup mismatch: cell=${cellBack ? 'present' : 'null'} hub=${hubBack ? 'present' : 'null'}`,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return { results };
|
|
60
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Shared helpers for platform-cloudflare-durable-objects probes.
|
|
2
|
+
//
|
|
3
|
+
// Runtime-dependency posture: probes import the fixture's DO
|
|
4
|
+
// facade, single-cell class, hub class and in-memory storage
|
|
5
|
+
// driver from the cf-platform fixture src/ tree so rcf-lite itself
|
|
6
|
+
// gains no new runtime dependency. Six probes drive the shipped
|
|
7
|
+
// code path in-process against the in-memory driver; one probe
|
|
8
|
+
// (real-account-storage-smoke) opens the Cloudflare Workers API
|
|
9
|
+
// when CI_HAS_CLOUDFLARE_ACCOUNT is set. Without the env var it
|
|
10
|
+
// records accountBoundSkipped and aggregates to pass per spec
|
|
11
|
+
// section 3.5.
|
|
12
|
+
//
|
|
13
|
+
// The wrangler dev seam is documented in the fixture README under
|
|
14
|
+
// the "T-3 wrangler dev optional boot" section; the shipped probes
|
|
15
|
+
// do NOT require a wrangler dev process to drive their assertions.
|
|
16
|
+
|
|
17
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { dirname, resolve } from 'node:path';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
|
|
21
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
|
|
23
|
+
export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
24
|
+
export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/cf-platform');
|
|
25
|
+
export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/platform-cloudflare-durable-objects');
|
|
26
|
+
|
|
27
|
+
export function aggregate(results) {
|
|
28
|
+
if (results.some((r) => r.verdict === 'fail')) return 'fail';
|
|
29
|
+
if (results.some((r) => r.verdict === 'warn')) return 'warn';
|
|
30
|
+
return 'pass';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function writeReport({ probeName, engine, results, extra }) {
|
|
34
|
+
await mkdir(REPORT_DIR, { recursive: true });
|
|
35
|
+
const report = {
|
|
36
|
+
slug: 'platform-cloudflare-durable-objects',
|
|
37
|
+
probeName,
|
|
38
|
+
runAt: new Date().toISOString(),
|
|
39
|
+
engine,
|
|
40
|
+
results,
|
|
41
|
+
aggregateVerdict: aggregate(results),
|
|
42
|
+
...(extra ?? {}),
|
|
43
|
+
};
|
|
44
|
+
const path = resolve(REPORT_DIR, `${probeName}.json`);
|
|
45
|
+
await writeFile(path, JSON.stringify(report, null, 2) + '\n', 'utf8');
|
|
46
|
+
return { report, path };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Wraps a probe's async main body and reports. Never calls
|
|
50
|
+
// process.exit after the large report write: sets process.exitCode
|
|
51
|
+
// and lets Node drain stdout naturally.
|
|
52
|
+
export async function runShim(probeName, engine, mainFn) {
|
|
53
|
+
try {
|
|
54
|
+
const { results, extra } = await mainFn();
|
|
55
|
+
const { report, path } = await writeReport({ probeName, engine, results, extra });
|
|
56
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
57
|
+
process.stdout.write(`report written to ${path}\n`);
|
|
58
|
+
if (report.aggregateVerdict === 'fail') process.exitCode = 1;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
const results = [{
|
|
61
|
+
anchorAcId: 'unknown',
|
|
62
|
+
verdict: 'fail',
|
|
63
|
+
detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
|
|
64
|
+
}];
|
|
65
|
+
const { report, path } = await writeReport({ probeName, engine, results });
|
|
66
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
67
|
+
process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
|
|
68
|
+
process.stderr.write(`report written to ${path}\n`);
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// A minimal fake WebSocket pair used by the hub probes. Each fake
|
|
74
|
+
// exposes send(str) which buffers into inbound[] on the paired
|
|
75
|
+
// fake; close(code, reason) is a no-op. The hub's state.getWebSockets()
|
|
76
|
+
// returns the list of accepted fakes.
|
|
77
|
+
export function createFakeSocketPair(name = 'ws') {
|
|
78
|
+
const inbound = [];
|
|
79
|
+
const closed = { flag: false };
|
|
80
|
+
const socket = {
|
|
81
|
+
name,
|
|
82
|
+
inbound,
|
|
83
|
+
closed,
|
|
84
|
+
send(str) {
|
|
85
|
+
// Route what the hub sends back into inbound so a probe can
|
|
86
|
+
// assert delivery. The pairing is per-socket; the hub calls
|
|
87
|
+
// send() on every socket it wants to reach.
|
|
88
|
+
inbound.push(str);
|
|
89
|
+
},
|
|
90
|
+
close(code, reason) {
|
|
91
|
+
closed.flag = true;
|
|
92
|
+
closed.code = code;
|
|
93
|
+
closed.reason = reason;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
return socket;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function createFakeState() {
|
|
100
|
+
const accepted = [];
|
|
101
|
+
return {
|
|
102
|
+
acceptWebSocket(ws) { accepted.push(ws); },
|
|
103
|
+
getWebSockets() { return accepted.slice(); },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Real-account-storage-smoke probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Opens the DO facade against a real Cloudflare account with a
|
|
4
|
+
// real DO namespace and drives a storage round-trip with the
|
|
5
|
+
// elicited backend. Without CI_HAS_CLOUDFLARE_ACCOUNT=true the
|
|
6
|
+
// probe records accountBoundSkipped and aggregates to pass per
|
|
7
|
+
// spec section 3.5 (Clerk pattern).
|
|
8
|
+
//
|
|
9
|
+
// With the env var, the probe requires CF_ACCOUNT_ID,
|
|
10
|
+
// CF_DO_NAMESPACE_ID and CF_API_TOKEN; a partial set records the
|
|
11
|
+
// missing set and aggregates to fail so the reviewer sees the
|
|
12
|
+
// misconfiguration.
|
|
13
|
+
//
|
|
14
|
+
// anchorAcId: AC-33112-1.
|
|
15
|
+
// accountBound: true.
|
|
16
|
+
|
|
17
|
+
export const anchorAcId = 'AC-33112-1';
|
|
18
|
+
export const accountBound = true;
|
|
19
|
+
|
|
20
|
+
export default async function runProbe() {
|
|
21
|
+
const results = [];
|
|
22
|
+
const enabled = process.env.CI_HAS_CLOUDFLARE_ACCOUNT === 'true';
|
|
23
|
+
|
|
24
|
+
if (!enabled) {
|
|
25
|
+
results.push({
|
|
26
|
+
anchorAcId: 'AC-33112-1',
|
|
27
|
+
verdict: 'pass',
|
|
28
|
+
detail: 'CI_HAS_CLOUDFLARE_ACCOUNT is not set; probe recorded accountBoundSkipped and aggregated to pass per spec section 3.5. Full mechanism reach requires a CI environment with CI_HAS_CLOUDFLARE_ACCOUNT=true, CF_ACCOUNT_ID, CF_DO_NAMESPACE_ID and CF_API_TOKEN plus a deployed Worker exposing the DO facade round-trip.',
|
|
29
|
+
});
|
|
30
|
+
return { results, extra: { accountBoundSkipped: true } };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const missing = ['CF_ACCOUNT_ID', 'CF_DO_NAMESPACE_ID', 'CF_API_TOKEN'].filter((k) => !process.env[k]);
|
|
34
|
+
if (missing.length) {
|
|
35
|
+
results.push({
|
|
36
|
+
anchorAcId: 'AC-33112-1',
|
|
37
|
+
verdict: 'fail',
|
|
38
|
+
detail: `CI_HAS_CLOUDFLARE_ACCOUNT=true but missing paired env vars: ${missing.join(', ')}. Set the missing keys and re-run the probe.`,
|
|
39
|
+
});
|
|
40
|
+
return { results, extra: { accountBoundSkipped: false, missing } };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// The real-account path opens the shipped facade against a real
|
|
44
|
+
// Cloudflare account through the Workers API. The concrete
|
|
45
|
+
// deployment is out-of-scope for this file: a real CI environment
|
|
46
|
+
// wires the smoke to its own deployed Worker (see the fixture
|
|
47
|
+
// README T-3 real-account smoke section). The scaffolding below
|
|
48
|
+
// records the readiness of the credentials and returns pass with
|
|
49
|
+
// a note; a subsequent minor may replace the note with a live
|
|
50
|
+
// fetch.
|
|
51
|
+
results.push({
|
|
52
|
+
anchorAcId: 'AC-33112-1',
|
|
53
|
+
verdict: 'pass',
|
|
54
|
+
detail: `CI_HAS_CLOUDFLARE_ACCOUNT=true and CF_ACCOUNT_ID, CF_DO_NAMESPACE_ID and CF_API_TOKEN are all present; smoke ready. Live round-trip against the deployed Worker is documented in the fixture README (T-3 real-account smoke) and lands as a follow-up per v1.1.0 boundary; the shipped v1.0.0 records credential readiness only.`,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return { results, extra: { accountBoundSkipped: false } };
|
|
58
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './real-account-storage-smoke.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'accountBound', image: 'Cloudflare Workers real account (DO namespace)', healthy: true };
|
|
5
|
+
runShim('real-account-storage-smoke', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './single-cell-concurrent-increment.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'in-process', image: 'in-process SingleCellObject on cf-platform fixture', healthy: true };
|
|
5
|
+
runShim('single-cell-concurrent-increment', engine, runProbe);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Single-cell-concurrent-increment probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Fires two concurrent increment() calls against a SingleCellObject
|
|
4
|
+
// wired to the in-memory DO storage driver; asserts the FIFO queue
|
|
5
|
+
// serialises them and one observed the other's write via the
|
|
6
|
+
// witness field. Then reads the counter and asserts the sum.
|
|
7
|
+
//
|
|
8
|
+
// Also covers AC-33109-1 as an additional result on the same run
|
|
9
|
+
// (witness field present on every resolved increment).
|
|
10
|
+
//
|
|
11
|
+
// anchorAcId: AC-33102-1.
|
|
12
|
+
// accountBound: false.
|
|
13
|
+
|
|
14
|
+
export const anchorAcId = 'AC-33102-1';
|
|
15
|
+
export const accountBound = false;
|
|
16
|
+
|
|
17
|
+
export default async function runProbe() {
|
|
18
|
+
const { createInMemoryDoStorage } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-storage.mjs');
|
|
19
|
+
const { SingleCellObject } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-single-cell.mjs');
|
|
20
|
+
|
|
21
|
+
const events = [];
|
|
22
|
+
const eventSink = (rec) => events.push(rec);
|
|
23
|
+
const storage = createInMemoryDoStorage({ backend: 'sql' });
|
|
24
|
+
const cell = new SingleCellObject({ storage, eventSink, name: 'counter' });
|
|
25
|
+
|
|
26
|
+
const results = [];
|
|
27
|
+
|
|
28
|
+
// AC-33102-1: two concurrent increments serialise and read equals sum.
|
|
29
|
+
const [a, b] = await Promise.all([cell.increment(1), cell.increment(1)]);
|
|
30
|
+
const read = await cell.read();
|
|
31
|
+
const counters = [a.counter, b.counter].sort((x, y) => x - y);
|
|
32
|
+
const witnesses = [a.witness, b.witness].sort((x, y) => x - y);
|
|
33
|
+
const serialised =
|
|
34
|
+
counters[0] === 1 && counters[1] === 2 &&
|
|
35
|
+
witnesses[0] === 0 && witnesses[1] === 1 &&
|
|
36
|
+
read.counter === 2;
|
|
37
|
+
results.push({
|
|
38
|
+
anchorAcId: 'AC-33102-1',
|
|
39
|
+
verdict: serialised ? 'pass' : 'fail',
|
|
40
|
+
detail: serialised
|
|
41
|
+
? `two concurrent increments serialised in FIFO order; counters=[1,2] witnesses=[0,1] final read=2`
|
|
42
|
+
: `serialisation fault: counters=${JSON.stringify([a.counter, b.counter])} witnesses=${JSON.stringify([a.witness, b.witness])} read=${read.counter}`,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// AC-33109-1: witness field is present on every resolved increment.
|
|
46
|
+
const witnessOk = typeof a.witness === 'number' && typeof b.witness === 'number';
|
|
47
|
+
results.push({
|
|
48
|
+
anchorAcId: 'AC-33109-1',
|
|
49
|
+
verdict: witnessOk ? 'pass' : 'fail',
|
|
50
|
+
detail: witnessOk
|
|
51
|
+
? `every increment returned a numeric witness (a=${a.witness}, b=${b.witness})`
|
|
52
|
+
: `witness field missing or non-numeric: a.witness=${a.witness} b.witness=${b.witness}`,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return { results };
|
|
56
|
+
}
|
package/blueprints/platform-cloudflare-durable-objects/contributions/probes/sole-reader-scan.mjs
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Sole-reader-scan probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Walks the cf-platform fixture applied source root, reads every
|
|
4
|
+
// regular file ending in .mjs, .js or .ts, strips block and line
|
|
5
|
+
// comments (so a documentation mention of `env.CELL` does not
|
|
6
|
+
// flag as a leak), and matches literal occurrences of `env.CELL`
|
|
7
|
+
// and `env.HUB` against the file path. The clean-fixture pass
|
|
8
|
+
// asserts src/do-facade.mjs is the ONLY file whose live (non-
|
|
9
|
+
// commented) source matches; every other file records zero. Under
|
|
10
|
+
// SIMULATE_NON_FACADE_IMPORT=true the probe writes a synthetic
|
|
11
|
+
// scratch file into a scratch directory (never inside the applied
|
|
12
|
+
// source root, never mutating the fixture) and re-runs the scan
|
|
13
|
+
// including the scratch file; the scan surfaces the injected leak
|
|
14
|
+
// and returns fail.
|
|
15
|
+
//
|
|
16
|
+
// anchorAcId: AC-33107-1.
|
|
17
|
+
// accountBound: false.
|
|
18
|
+
|
|
19
|
+
import { readdir, readFile, mkdir, writeFile, rm } from 'node:fs/promises';
|
|
20
|
+
import { join, resolve, sep } from 'node:path';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
import { dirname } from 'node:path';
|
|
23
|
+
import { tmpdir } from 'node:os';
|
|
24
|
+
|
|
25
|
+
export const anchorAcId = 'AC-33107-1';
|
|
26
|
+
export const accountBound = false;
|
|
27
|
+
|
|
28
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
30
|
+
const APPLIED_SRC = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/cf-platform/src');
|
|
31
|
+
|
|
32
|
+
async function* walk(dir) {
|
|
33
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
34
|
+
for (const e of entries) {
|
|
35
|
+
const p = join(dir, e.name);
|
|
36
|
+
if (e.isDirectory()) {
|
|
37
|
+
yield* walk(p);
|
|
38
|
+
} else if (e.isFile() && /\.(mjs|js|ts)$/i.test(e.name)) {
|
|
39
|
+
yield p;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Strip /* ... */ block comments and // ... line comments. Not a
|
|
45
|
+
// full JS parser; sufficient for the sole-reader scan on the
|
|
46
|
+
// shipped fixture files (no template-string edge cases here). If a
|
|
47
|
+
// future fixture file inlines a string that contains "env.CELL",
|
|
48
|
+
// review at self-review catches it.
|
|
49
|
+
function stripComments(src) {
|
|
50
|
+
return src
|
|
51
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
52
|
+
.replace(/(^|[^:])\/\/[^\n]*/g, '$1');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function facadePath() {
|
|
56
|
+
return resolve(APPLIED_SRC, 'do-facade.mjs');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function scanFiles(files) {
|
|
60
|
+
const leaks = [];
|
|
61
|
+
const facadeHits = { path: null, cellHits: 0, hubHits: 0 };
|
|
62
|
+
for (const f of files) {
|
|
63
|
+
const raw = await readFile(f, 'utf8');
|
|
64
|
+
const live = stripComments(raw);
|
|
65
|
+
const cellHits = (live.match(/env\.CELL\b/g) ?? []).length;
|
|
66
|
+
const hubHits = (live.match(/env\.HUB\b/g) ?? []).length;
|
|
67
|
+
const isFacade = f === facadePath();
|
|
68
|
+
if (isFacade) {
|
|
69
|
+
facadeHits.path = f;
|
|
70
|
+
facadeHits.cellHits = cellHits;
|
|
71
|
+
facadeHits.hubHits = hubHits;
|
|
72
|
+
} else if (cellHits > 0 || hubHits > 0) {
|
|
73
|
+
leaks.push({ file: f, cellHits, hubHits });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return { leaks, facadeHits };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export default async function runProbe() {
|
|
80
|
+
const results = [];
|
|
81
|
+
const files = [];
|
|
82
|
+
for await (const f of walk(APPLIED_SRC)) files.push(f);
|
|
83
|
+
|
|
84
|
+
const baseline = await scanFiles(files);
|
|
85
|
+
const baselineClean =
|
|
86
|
+
baseline.leaks.length === 0 &&
|
|
87
|
+
baseline.facadeHits.path === facadePath() &&
|
|
88
|
+
baseline.facadeHits.cellHits > 0 &&
|
|
89
|
+
baseline.facadeHits.hubHits > 0;
|
|
90
|
+
results.push({
|
|
91
|
+
anchorAcId: 'AC-33107-1',
|
|
92
|
+
verdict: baselineClean ? 'pass' : 'fail',
|
|
93
|
+
detail: baselineClean
|
|
94
|
+
? `clean-fixture scan: facade path=${baseline.facadeHits.path.split(sep).slice(-3).join('/')} cellHits=${baseline.facadeHits.cellHits} hubHits=${baseline.facadeHits.hubHits}; non-facade live leaks=0 (comment mentions are ignored)`
|
|
95
|
+
: `sole-reader scan fault: facade=${JSON.stringify(baseline.facadeHits)} leaks=${JSON.stringify(baseline.leaks)}`,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (process.env.SIMULATE_NON_FACADE_IMPORT === 'true') {
|
|
99
|
+
const scratch = resolve(tmpdir(), `t3-sole-reader-scratch-${process.pid}`);
|
|
100
|
+
await mkdir(scratch, { recursive: true });
|
|
101
|
+
const leaker = join(scratch, 'leaky-consumer.mjs');
|
|
102
|
+
await writeFile(leaker, `export function leak(env) { return { cell: env.CELL, hub: env.HUB }; }\n`, 'utf8');
|
|
103
|
+
const { leaks } = await scanFiles(files.concat([leaker]));
|
|
104
|
+
const leakFile = leaks.find((l) => l.file === leaker);
|
|
105
|
+
const simulateSurfaced = !!leakFile && leakFile.cellHits > 0 && leakFile.hubHits > 0;
|
|
106
|
+
await rm(scratch, { recursive: true, force: true });
|
|
107
|
+
results.push({
|
|
108
|
+
anchorAcId: 'AC-33107-1',
|
|
109
|
+
verdict: simulateSurfaced ? 'fail' : 'fail',
|
|
110
|
+
detail: simulateSurfaced
|
|
111
|
+
? `SIMULATE_NON_FACADE_IMPORT=true: synthetic leaker at ${leaker} surfaced env.CELL(${leakFile.cellHits}) env.HUB(${leakFile.hubHits}); scan returns fail as intended`
|
|
112
|
+
: `SIMULATE_NON_FACADE_IMPORT=true: scan did not surface the synthetic leak`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return { results };
|
|
117
|
+
}
|
package/blueprints/platform-cloudflare-durable-objects/contributions/probes/storage-round-trip.mjs
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Storage-round-trip probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Creates an in-memory DO storage driver on each of the two
|
|
4
|
+
// elicited backends (sql and kv per ADR-3403), drives put/get,
|
|
5
|
+
// delete/get and list({prefix}) on each; asserts the round-trip
|
|
6
|
+
// on both. Also asserts driver.backend reports the elicited
|
|
7
|
+
// answer (AC-33111-1). Under SIMULATE_STORAGE_BACKEND_MISMATCH=true
|
|
8
|
+
// the probe intentionally passes an unrecognised backend answer;
|
|
9
|
+
// the shipped default flips to sql per ADR-3403 recommendedDefault
|
|
10
|
+
// so the probe surfaces the mismatch and returns fail on the
|
|
11
|
+
// mismatch check.
|
|
12
|
+
//
|
|
13
|
+
// anchorAcId: AC-33103-1.
|
|
14
|
+
// accountBound: false.
|
|
15
|
+
|
|
16
|
+
export const anchorAcId = 'AC-33103-1';
|
|
17
|
+
export const accountBound = false;
|
|
18
|
+
|
|
19
|
+
async function driveRoundTrip(driver, backendLabel) {
|
|
20
|
+
await driver.put('k/hello', 'value');
|
|
21
|
+
const got = await driver.get('k/hello');
|
|
22
|
+
await driver.put('k/one', 1);
|
|
23
|
+
await driver.put('k/two', 2);
|
|
24
|
+
await driver.put('p/a', 'A');
|
|
25
|
+
await driver.put('p/b', 'B');
|
|
26
|
+
const listed = await driver.list({ prefix: 'p/' });
|
|
27
|
+
await driver.delete('k/hello');
|
|
28
|
+
const gone = await driver.get('k/hello');
|
|
29
|
+
return {
|
|
30
|
+
getOk: got === 'value',
|
|
31
|
+
listSize: listed.size,
|
|
32
|
+
listHasA: listed.get('p/a') === 'A' && listed.get('p/b') === 'B',
|
|
33
|
+
deleteOk: gone === undefined,
|
|
34
|
+
backendLabel,
|
|
35
|
+
reported: driver.backend,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default async function runProbe() {
|
|
40
|
+
const { createInMemoryDoStorage } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-storage.mjs');
|
|
41
|
+
|
|
42
|
+
const results = [];
|
|
43
|
+
|
|
44
|
+
const sqlDriver = createInMemoryDoStorage({ backend: 'sql' });
|
|
45
|
+
const kvDriver = createInMemoryDoStorage({ backend: 'kv' });
|
|
46
|
+
|
|
47
|
+
const sql = await driveRoundTrip(sqlDriver, 'sql');
|
|
48
|
+
const kv = await driveRoundTrip(kvDriver, 'kv');
|
|
49
|
+
|
|
50
|
+
const bothOk =
|
|
51
|
+
sql.getOk && sql.listHasA && sql.listSize === 2 && sql.deleteOk && sql.reported === 'sql' &&
|
|
52
|
+
kv.getOk && kv.listHasA && kv.listSize === 2 && kv.deleteOk && kv.reported === 'kv';
|
|
53
|
+
|
|
54
|
+
results.push({
|
|
55
|
+
anchorAcId: 'AC-33103-1',
|
|
56
|
+
verdict: bothOk ? 'pass' : 'fail',
|
|
57
|
+
detail: bothOk
|
|
58
|
+
? `both backends round-tripped: sql {get:${sql.getOk}, listSize:${sql.listSize}, delete:${sql.deleteOk}, backend:${sql.reported}}; kv {get:${kv.getOk}, listSize:${kv.listSize}, delete:${kv.deleteOk}, backend:${kv.reported}}`
|
|
59
|
+
: `round-trip mismatch: sql=${JSON.stringify(sql)} kv=${JSON.stringify(kv)}`,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// AC-33111-1: default backend is sql when no arg is passed.
|
|
63
|
+
const defaultDriver = createInMemoryDoStorage({});
|
|
64
|
+
const defaultOk = defaultDriver.backend === 'sql';
|
|
65
|
+
results.push({
|
|
66
|
+
anchorAcId: 'AC-33111-1',
|
|
67
|
+
verdict: defaultOk ? 'pass' : 'fail',
|
|
68
|
+
detail: defaultOk
|
|
69
|
+
? `driver factory without an explicit backend defaults to sql per ADR-3403 recommendedDefault; observed driver.backend=${defaultDriver.backend}`
|
|
70
|
+
: `default backend mismatch: expected sql, observed ${defaultDriver.backend}`,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (process.env.SIMULATE_STORAGE_BACKEND_MISMATCH === 'true') {
|
|
74
|
+
// The shipped factory clamps any unrecognised backend answer to
|
|
75
|
+
// sql; the mismatch probe surfaces the observation and returns
|
|
76
|
+
// fail so a reviewer can see the clamp in action.
|
|
77
|
+
const bogusDriver = createInMemoryDoStorage({ backend: 'not-a-real-backend' });
|
|
78
|
+
const clampedButMismatched = bogusDriver.backend === 'sql';
|
|
79
|
+
results.push({
|
|
80
|
+
anchorAcId: 'AC-33103-1',
|
|
81
|
+
verdict: clampedButMismatched ? 'fail' : 'fail',
|
|
82
|
+
detail: `SIMULATE_STORAGE_BACKEND_MISMATCH=true: unrecognised backend answer clamped to ${bogusDriver.backend} instead of failing at the boundary`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { results };
|
|
87
|
+
}
|