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,112 @@
|
|
|
1
|
+
// Websocket-hub-broadcast probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Wires a HubObject to a fake state, accepts two fake sockets
|
|
4
|
+
// (createFakeSocketPair), drives a broadcast from client A and
|
|
5
|
+
// asserts B receives within the elicited window (default 500ms).
|
|
6
|
+
// Then drives hibernate-and-wake round-trip: hibernate, wake once
|
|
7
|
+
// (doWakeUp emitted, lastBroadcast returned), wake again (no
|
|
8
|
+
// second doWakeUp). Finally scans every emitted record on the sink
|
|
9
|
+
// against the allowed key set {event, key, size, ttl, timestamp,
|
|
10
|
+
// objectName, scheduledTime} and asserts zero forbidden-key hits
|
|
11
|
+
// (AC-33106-1); under SIMULATE_PII_LEAK=true a wrapped sink forwards
|
|
12
|
+
// a synthetic body-bearing record and the probe surfaces it,
|
|
13
|
+
// returning fail on the secrecy result.
|
|
14
|
+
//
|
|
15
|
+
// Under SIMULATE_HUB_HANG=true the broadcast handler is wrapped
|
|
16
|
+
// with an artificial delay past the elicited window; the probe
|
|
17
|
+
// surfaces the hang and returns fail on the broadcast-within-
|
|
18
|
+
// window check.
|
|
19
|
+
//
|
|
20
|
+
// anchorAcId: AC-33105-1 (primary; AC-33110-1 and AC-33106-1
|
|
21
|
+
// covered as additional results).
|
|
22
|
+
// accountBound: false.
|
|
23
|
+
|
|
24
|
+
export const anchorAcId = 'AC-33105-1';
|
|
25
|
+
export const accountBound = false;
|
|
26
|
+
|
|
27
|
+
const ALLOWED_KEYS = new Set(['event', 'key', 'size', 'ttl', 'timestamp', 'objectName', 'scheduledTime']);
|
|
28
|
+
const FORBIDDEN_KEYS = ['body', 'ssn', 'userId', 'headers', 'cookies', 'request', 'payload'];
|
|
29
|
+
|
|
30
|
+
export default async function runProbe() {
|
|
31
|
+
const { createInMemoryDoStorage } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-storage.mjs');
|
|
32
|
+
const { HubObject } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/do-hub.mjs');
|
|
33
|
+
const { createFakeState, createFakeSocketPair } = await import('./probe-utils.mjs');
|
|
34
|
+
|
|
35
|
+
const events = [];
|
|
36
|
+
const cleanSink = (rec) => events.push(rec);
|
|
37
|
+
const leakySink = (rec) => events.push({
|
|
38
|
+
...rec,
|
|
39
|
+
body: 'Hello, world (leaked test body)',
|
|
40
|
+
ssn: '123-45-6789',
|
|
41
|
+
userId: 'user_leaked_test_uid',
|
|
42
|
+
});
|
|
43
|
+
const eventSink = process.env.SIMULATE_PII_LEAK === 'true' ? leakySink : cleanSink;
|
|
44
|
+
const storage = createInMemoryDoStorage({ backend: 'sql' });
|
|
45
|
+
const state = createFakeState();
|
|
46
|
+
const hub = new HubObject({ state, storage, eventSink, name: 'lobby', hibernateAfterIdleMs: 500 });
|
|
47
|
+
|
|
48
|
+
const sockA = createFakeSocketPair('A');
|
|
49
|
+
const sockB = createFakeSocketPair('B');
|
|
50
|
+
await hub.accept(sockA);
|
|
51
|
+
await hub.accept(sockB);
|
|
52
|
+
|
|
53
|
+
const results = [];
|
|
54
|
+
|
|
55
|
+
// AC-33105-1: broadcast from A reaches both A and B within 500ms.
|
|
56
|
+
const started = Date.now();
|
|
57
|
+
const payload = 'ping';
|
|
58
|
+
if (process.env.SIMULATE_HUB_HANG === 'true') {
|
|
59
|
+
await new Promise((r) => setTimeout(r, 750));
|
|
60
|
+
}
|
|
61
|
+
await hub.webSocketMessage(sockA, JSON.stringify({ type: 'broadcast', payload }));
|
|
62
|
+
const elapsed = Date.now() - started;
|
|
63
|
+
const gotA = sockA.inbound.find((s) => s.includes('"payload":"ping"'));
|
|
64
|
+
const gotB = sockB.inbound.find((s) => s.includes('"payload":"ping"'));
|
|
65
|
+
const persisted = await storage.get('lastBroadcast');
|
|
66
|
+
const broadcastOk = !!gotA && !!gotB && elapsed <= 500 && !!persisted && persisted.includes('"payload":"ping"');
|
|
67
|
+
results.push({
|
|
68
|
+
anchorAcId: 'AC-33105-1',
|
|
69
|
+
verdict: broadcastOk ? 'pass' : 'fail',
|
|
70
|
+
detail: broadcastOk
|
|
71
|
+
? `broadcast fan-out: A received ${gotA} B received ${gotB}; elapsed ${elapsed}ms within 500ms window; storage.lastBroadcast persisted`
|
|
72
|
+
: `broadcast fault: gotA=${!!gotA} gotB=${!!gotB} elapsed=${elapsed}ms persisted=${!!persisted}`,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// AC-33110-1: hibernate-and-wake round-trip preserves storage and doWakeUp fires exactly once.
|
|
76
|
+
const preWakeCount = events.length;
|
|
77
|
+
await hub.hibernate();
|
|
78
|
+
const wake1 = await hub.wake();
|
|
79
|
+
const wake2 = await hub.wake();
|
|
80
|
+
const wakeEvents = events.slice(preWakeCount).filter((e) => e.event === 'doWakeUp');
|
|
81
|
+
const hibernateOk =
|
|
82
|
+
wake1.lastBroadcast === persisted &&
|
|
83
|
+
wake2.alreadyAwake === true &&
|
|
84
|
+
wake2.lastBroadcast === persisted &&
|
|
85
|
+
wakeEvents.length === 1;
|
|
86
|
+
results.push({
|
|
87
|
+
anchorAcId: 'AC-33110-1',
|
|
88
|
+
verdict: hibernateOk ? 'pass' : 'fail',
|
|
89
|
+
detail: hibernateOk
|
|
90
|
+
? `hibernate-and-wake round-trip: doWakeUp fired once; wake1.lastBroadcast preserved; wake2.alreadyAwake=true with same lastBroadcast`
|
|
91
|
+
: `hibernate-wake fault: wakeEventCount=${wakeEvents.length} wake1=${JSON.stringify(wake1)} wake2=${JSON.stringify(wake2)}`,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// AC-33106-1: every event carries only allowed keys; no forbidden keys.
|
|
95
|
+
const forbiddenHits = [];
|
|
96
|
+
const extraKeyHits = [];
|
|
97
|
+
for (const rec of events) {
|
|
98
|
+
const extras = Object.keys(rec).filter((k) => !ALLOWED_KEYS.has(k));
|
|
99
|
+
if (extras.length) extraKeyHits.push({ event: rec.event, extras });
|
|
100
|
+
for (const k of FORBIDDEN_KEYS) if (k in rec) forbiddenHits.push({ event: rec.event, forbiddenKey: k });
|
|
101
|
+
}
|
|
102
|
+
const secrecyOk = forbiddenHits.length === 0 && extraKeyHits.length === 0;
|
|
103
|
+
results.push({
|
|
104
|
+
anchorAcId: 'AC-33106-1',
|
|
105
|
+
verdict: secrecyOk ? 'pass' : 'fail',
|
|
106
|
+
detail: secrecyOk
|
|
107
|
+
? `event-secrecy scan across ${events.length} records: allowed-key set {${[...ALLOWED_KEYS].join(', ')}}; forbidden-key hits 0; extra-key hits 0`
|
|
108
|
+
: `event-secrecy fault: forbiddenHits=${JSON.stringify(forbiddenHits.slice(0, 5))} extraKeyHits=${JSON.stringify(extraKeyHits.slice(0, 5))}`,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return { results };
|
|
112
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// Wrangler-seam probe for platform-cloudflare-durable-objects v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Spawns `wrangler dev --local` on the cf-platform fixture and
|
|
4
|
+
// exercises the two shipped DO shapes through workerd:
|
|
5
|
+
//
|
|
6
|
+
// (a) two concurrent `POST /cell/<id>/increment` requests routed
|
|
7
|
+
// through `src/index.mjs` -> `createDoFacade({env}).cellFetch`
|
|
8
|
+
// -> `env.CELL.idFromName(id).fetch(...)` -> the shipped
|
|
9
|
+
// SingleCellObject class. Asserts the two responses observe
|
|
10
|
+
// per-instance serialisation: counters equal [1, 2] in some
|
|
11
|
+
// order, witnesses equal [0, 1] in some order (each request
|
|
12
|
+
// observed the prior write). Under the shipped code path the
|
|
13
|
+
// SingleCellObject `_serialise` promise queue plus workerd's
|
|
14
|
+
// per-instance dispatch both provide the guarantee; removing
|
|
15
|
+
// the queue surfaces two responses of {counter:1, witness:0}
|
|
16
|
+
// on the mutation-run.
|
|
17
|
+
// (b) one WebSocket upgrade against `/hub/<id>/connect` reaching
|
|
18
|
+
// `env.HUB`; asserts a single broadcast frame arrives on
|
|
19
|
+
// connect (the shipped HubObject fetch handler accepts the
|
|
20
|
+
// server half via `state.acceptWebSocket` and sends one
|
|
21
|
+
// broadcast frame immediately, so the probe does not need a
|
|
22
|
+
// second client to trigger fan-out).
|
|
23
|
+
//
|
|
24
|
+
// The probe also carries an additional AC-33108-1 result that
|
|
25
|
+
// greps the fixture wrangler.toml for the two `[[durable_objects.bindings]]`
|
|
26
|
+
// binding pairs (name/class_name) and the `[[migrations]]` block
|
|
27
|
+
// (tag `"v1"` plus new_classes for both classes). That result is
|
|
28
|
+
// deterministic and does not require wrangler.
|
|
29
|
+
//
|
|
30
|
+
// Warn semantics per section 3.1 pass-with-skip: if the wrangler
|
|
31
|
+
// devDependency is missing under `packages/rcf-lite/test/fixtures/cf-platform/node_modules/.bin`,
|
|
32
|
+
// or if the CLI does not bind within the cap, the probe returns
|
|
33
|
+
// aggregateVerdict warn (never fail); the wrangler.toml grep result
|
|
34
|
+
// still runs and reports pass. A handler thrown at the workerd
|
|
35
|
+
// boundary is a genuine `fail` per the gate reviewer's directive.
|
|
36
|
+
//
|
|
37
|
+
// anchorAcId: AC-33113-1 (wrangler-seam runtime coverage);
|
|
38
|
+
// AC-33108-1 covered as an additional result.
|
|
39
|
+
// accountBound: false.
|
|
40
|
+
|
|
41
|
+
import { spawn } from 'node:child_process';
|
|
42
|
+
import { readFile } from 'node:fs/promises';
|
|
43
|
+
import { existsSync } from 'node:fs';
|
|
44
|
+
import { dirname, resolve } from 'node:path';
|
|
45
|
+
import { fileURLToPath } from 'node:url';
|
|
46
|
+
|
|
47
|
+
export const anchorAcId = 'AC-33113-1';
|
|
48
|
+
export const accountBound = false;
|
|
49
|
+
|
|
50
|
+
const BIND_CAP_MS = 45000;
|
|
51
|
+
const KILL_GRACE_MS = 2000;
|
|
52
|
+
const WS_CAP_MS = 5000;
|
|
53
|
+
|
|
54
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
55
|
+
const FIXTURE_DIR = resolve(HERE, '..', '..', '..', '..', 'packages', 'rcf-lite', 'test', 'fixtures', 'cf-platform');
|
|
56
|
+
|
|
57
|
+
function findWranglerBin() {
|
|
58
|
+
const candidate = resolve(FIXTURE_DIR, 'node_modules', '.bin', 'wrangler');
|
|
59
|
+
return existsSync(candidate) ? candidate : null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function killAndDrain(proc) {
|
|
63
|
+
if (!proc || proc.killed) return;
|
|
64
|
+
try { proc.kill('SIGTERM'); } catch (_err) { /* best effort */ }
|
|
65
|
+
await new Promise((r) => setTimeout(r, KILL_GRACE_MS));
|
|
66
|
+
try { if (!proc.killed) proc.kill('SIGKILL'); } catch (_err) { /* best effort */ }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function greppedWranglerToml() {
|
|
70
|
+
const toml = await readFile(resolve(FIXTURE_DIR, 'wrangler.toml'), 'utf8');
|
|
71
|
+
const cellNameHit = /name = "CELL"/.test(toml);
|
|
72
|
+
const cellClassHit = /class_name = "SingleCellObject"/.test(toml);
|
|
73
|
+
const hubNameHit = /name = "HUB"/.test(toml);
|
|
74
|
+
const hubClassHit = /class_name = "HubObject"/.test(toml);
|
|
75
|
+
const tagHit = /tag = "v1"/.test(toml);
|
|
76
|
+
const newClassesHit = /new_classes = \["SingleCellObject", "HubObject"\]/.test(toml);
|
|
77
|
+
return {
|
|
78
|
+
ok: cellNameHit && cellClassHit && hubNameHit && hubClassHit && tagHit && newClassesHit,
|
|
79
|
+
hits: { cellNameHit, cellClassHit, hubNameHit, hubClassHit, tagHit, newClassesHit },
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function driveConcurrentIncrements(boundUrl) {
|
|
84
|
+
const target = `${boundUrl}/cell/wrangler-seam-cell-${Date.now()}/increment`;
|
|
85
|
+
const [a, b] = await Promise.all([
|
|
86
|
+
fetch(target, { method: 'POST' }),
|
|
87
|
+
fetch(target, { method: 'POST' }),
|
|
88
|
+
]);
|
|
89
|
+
if (!a.ok || !b.ok) {
|
|
90
|
+
return { ok: false, reason: `HTTP status a=${a.status} b=${b.status}`, target };
|
|
91
|
+
}
|
|
92
|
+
const [ja, jb] = await Promise.all([a.json(), b.json()]);
|
|
93
|
+
const counters = [ja.counter, jb.counter].sort((x, y) => x - y);
|
|
94
|
+
const witnesses = [ja.witness, jb.witness].sort((x, y) => x - y);
|
|
95
|
+
const serialised =
|
|
96
|
+
counters[0] === 1 && counters[1] === 2 &&
|
|
97
|
+
witnesses[0] === 0 && witnesses[1] === 1;
|
|
98
|
+
return {
|
|
99
|
+
ok: serialised,
|
|
100
|
+
counters,
|
|
101
|
+
witnesses,
|
|
102
|
+
responses: [ja, jb],
|
|
103
|
+
target,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function drainOneWebSocketFrame(boundUrl) {
|
|
108
|
+
const wsUrl = boundUrl.replace(/^http/, 'ws') + `/hub/wrangler-seam-hub-${Date.now()}/connect`;
|
|
109
|
+
return new Promise((resolveResult) => {
|
|
110
|
+
let settled = false;
|
|
111
|
+
const timer = setTimeout(() => {
|
|
112
|
+
if (settled) return;
|
|
113
|
+
settled = true;
|
|
114
|
+
try { ws.close(); } catch (_err) { /* best effort */ }
|
|
115
|
+
resolveResult({ ok: false, reason: `no frame received within ${WS_CAP_MS}ms`, wsUrl });
|
|
116
|
+
}, WS_CAP_MS);
|
|
117
|
+
let ws;
|
|
118
|
+
try {
|
|
119
|
+
ws = new WebSocket(wsUrl);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
settled = true;
|
|
123
|
+
return resolveResult({ ok: false, reason: `WebSocket construct threw: ${err && err.message ? err.message : String(err)}`, wsUrl });
|
|
124
|
+
}
|
|
125
|
+
ws.addEventListener('message', (ev) => {
|
|
126
|
+
if (settled) return;
|
|
127
|
+
settled = true;
|
|
128
|
+
clearTimeout(timer);
|
|
129
|
+
const payload = typeof ev.data === 'string' ? ev.data : String(ev.data);
|
|
130
|
+
try { ws.close(); } catch (_err) { /* best effort */ }
|
|
131
|
+
resolveResult({ ok: payload.includes('"payload":"hello-from-hub"'), payload, wsUrl });
|
|
132
|
+
});
|
|
133
|
+
ws.addEventListener('error', (err) => {
|
|
134
|
+
if (settled) return;
|
|
135
|
+
settled = true;
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
resolveResult({ ok: false, reason: `WebSocket error: ${err && err.message ? err.message : 'no message'}`, wsUrl });
|
|
138
|
+
});
|
|
139
|
+
ws.addEventListener('close', (ev) => {
|
|
140
|
+
if (settled) return;
|
|
141
|
+
settled = true;
|
|
142
|
+
clearTimeout(timer);
|
|
143
|
+
resolveResult({ ok: false, reason: `WebSocket closed before message: code=${ev.code} reason=${ev.reason}`, wsUrl });
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export default async function runProbe() {
|
|
149
|
+
const results = [];
|
|
150
|
+
|
|
151
|
+
// AC-33108-1 (additional result): wrangler.toml literal-strings
|
|
152
|
+
// grep. Deterministic; runs first so a wrangler-missing warn
|
|
153
|
+
// does not hide it.
|
|
154
|
+
const toml = await greppedWranglerToml();
|
|
155
|
+
results.push({
|
|
156
|
+
anchorAcId: 'AC-33108-1',
|
|
157
|
+
verdict: toml.ok ? 'pass' : 'fail',
|
|
158
|
+
detail: toml.ok
|
|
159
|
+
? `wrangler.toml carries name="CELL" + class_name="SingleCellObject", name="HUB" + class_name="HubObject", and [[migrations]] tag "v1" with new_classes ["SingleCellObject","HubObject"]`
|
|
160
|
+
: `wrangler.toml grep miss: ${JSON.stringify(toml.hits)}`,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const bin = findWranglerBin();
|
|
164
|
+
if (!bin) {
|
|
165
|
+
results.push({
|
|
166
|
+
anchorAcId: 'AC-33113-1',
|
|
167
|
+
verdict: 'warn',
|
|
168
|
+
detail: `wrangler devDependency not installed under ${FIXTURE_DIR}/node_modules/.bin/wrangler; run pnpm install --ignore-workspace in the fixture directory to bring the CLI onto the tree. Mechanism-reach gap noted; the in-process probes carry the runtime evidence for the shipped DO classes.`,
|
|
169
|
+
});
|
|
170
|
+
return { results, extra: { wranglerBinPresent: false } };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const proc = spawn(bin, ['dev', '--local', '--port', '0'], {
|
|
174
|
+
cwd: FIXTURE_DIR,
|
|
175
|
+
env: process.env,
|
|
176
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
let boundUrl = null;
|
|
180
|
+
let stderrTail = '';
|
|
181
|
+
let stdoutTail = '';
|
|
182
|
+
proc.stdout.on('data', (buf) => {
|
|
183
|
+
const s = buf.toString();
|
|
184
|
+
stdoutTail = (stdoutTail + s).slice(-2000);
|
|
185
|
+
const match = s.match(/http:\/\/(?:127\.0\.0\.1|localhost):(\d+)/i);
|
|
186
|
+
if (match && !boundUrl) boundUrl = `http://127.0.0.1:${match[1]}`;
|
|
187
|
+
});
|
|
188
|
+
proc.stderr.on('data', (buf) => {
|
|
189
|
+
stderrTail = (stderrTail + buf.toString()).slice(-2000);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const bindStart = Date.now();
|
|
193
|
+
while (!boundUrl && Date.now() - bindStart < BIND_CAP_MS) {
|
|
194
|
+
if (proc.exitCode !== null) break;
|
|
195
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!boundUrl) {
|
|
199
|
+
await killAndDrain(proc);
|
|
200
|
+
results.push({
|
|
201
|
+
anchorAcId: 'AC-33113-1',
|
|
202
|
+
verdict: 'warn',
|
|
203
|
+
detail: `wrangler dev did not bind within ${BIND_CAP_MS}ms cap; treated as a CLI regression per spec section 3.1 pass-with-skip. stderr tail: ${stderrTail.slice(-500)} stdout tail: ${stdoutTail.slice(-500)}`,
|
|
204
|
+
});
|
|
205
|
+
return { results, extra: { boundUrl: null, wranglerBinPresent: true } };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Small settle delay so DO namespaces are wired before requests fire.
|
|
209
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
210
|
+
|
|
211
|
+
let seamResult = null;
|
|
212
|
+
let handlerThrew = false;
|
|
213
|
+
try {
|
|
214
|
+
seamResult = await driveConcurrentIncrements(boundUrl);
|
|
215
|
+
} catch (err) {
|
|
216
|
+
handlerThrew = true;
|
|
217
|
+
seamResult = { ok: false, reason: `probe threw at increment: ${err && err.message ? err.message : String(err)}` };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let wsResult = null;
|
|
221
|
+
try {
|
|
222
|
+
wsResult = await drainOneWebSocketFrame(boundUrl);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
handlerThrew = true;
|
|
225
|
+
wsResult = { ok: false, reason: `probe threw at ws: ${err && err.message ? err.message : String(err)}` };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
await killAndDrain(proc);
|
|
229
|
+
|
|
230
|
+
// Serialisation result: fail if the handler surfaced a thrown
|
|
231
|
+
// error at the workerd boundary; else pass/fail based on the
|
|
232
|
+
// observed serialisation shape.
|
|
233
|
+
if (handlerThrew) {
|
|
234
|
+
results.push({
|
|
235
|
+
anchorAcId: 'AC-33113-1',
|
|
236
|
+
verdict: 'fail',
|
|
237
|
+
detail: `handler threw at the workerd boundary during the wrangler-seam drive; increment=${seamResult?.reason ?? 'n/a'}; websocket=${wsResult?.reason ?? 'n/a'}`,
|
|
238
|
+
});
|
|
239
|
+
} else {
|
|
240
|
+
results.push({
|
|
241
|
+
anchorAcId: 'AC-33113-1',
|
|
242
|
+
verdict: seamResult.ok ? 'pass' : 'fail',
|
|
243
|
+
detail: seamResult.ok
|
|
244
|
+
? `two concurrent POST ${seamResult.target} responded with counters=${JSON.stringify(seamResult.counters)} witnesses=${JSON.stringify(seamResult.witnesses)}; serialisation observed under workerd (each request read the other's write)`
|
|
245
|
+
: `serialisation fault under workerd: ${seamResult.reason ?? `counters=${JSON.stringify(seamResult.counters)} witnesses=${JSON.stringify(seamResult.witnesses)} responses=${JSON.stringify(seamResult.responses ?? null)}`}`,
|
|
246
|
+
});
|
|
247
|
+
results.push({
|
|
248
|
+
anchorAcId: 'AC-33105-1',
|
|
249
|
+
verdict: wsResult.ok ? 'pass' : 'fail',
|
|
250
|
+
detail: wsResult.ok
|
|
251
|
+
? `WebSocket upgrade against ${wsResult.wsUrl} received one broadcast frame with payload=${wsResult.payload}`
|
|
252
|
+
: `websocket fault: ${wsResult.reason} (url=${wsResult.wsUrl})`,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return { results, extra: { boundUrl, wranglerBinPresent: true } };
|
|
257
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The DO namespace facade is the sole reader of env.CELL and env.HUB and opens on boot with namespaceReady",
|
|
5
|
+
"description": "The applying project reaches Cloudflare Durable Objects through a single facade module in the project source tree that is the ONLY module holding a reference to the DO namespace bindings (env.CELL for the single-cell shape and env.HUB for the hibernatable-WebSocket hub shape per https://developers.cloudflare.com/durable-objects/). On process boot the facade wires the injected event sink and emits a namespaceReady lifecycle event with a metadata-only payload. Every consumer of DO from the applied project code calls the facade's typed handles; no other module dereferences env.CELL or env.HUB.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The single-cell shape exposes typed domain verbs and serialises concurrent invocations per instance",
|
|
5
|
+
"description": "A named single-cell object exposes typed domain verbs (increment, read, reset). Cloudflare's documented Durable Objects consistency model serialises invocations against the same instance per https://developers.cloudflare.com/durable-objects/; the shipped SingleCellObject class realises that contract so a concurrent-increment probe observes the counter sum and one increment observed the other via a written witness.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-003",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The storage API provides typed put/get/delete on the object with an elicited backend (SQL or KV)",
|
|
5
|
+
"description": "The object's state.storage surface exposes typed put(key, value), get(key), delete(key) and list({prefix}) verbs per https://developers.cloudflare.com/durable-objects/. Storage backend is elicited (sql or kv per ADR-3403); the shipped class code is backend-agnostic and threads through the elicited answer. A storage round-trip probe drives both backends via a fixture switch.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-004",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The alarm surface fires alarm() exactly once per scheduled time and doAlarmFired carries object name and scheduled time",
|
|
5
|
+
"description": "A named object supports storage.setAlarm(scheduledTime) and an alarm() handler per https://developers.cloudflare.com/durable-objects/. Cloudflare's runtime guarantees alarm delivery once per scheduled time; the shipped class realises the handler and the injected event sink records a doAlarmFired event with {objectName, scheduledTime} metadata fields alongside the metadata-only lifecycle payload.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-005",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The hibernatable WebSocket hub accepts clients via state.acceptWebSocket and the wake handler runs from cold reading the same storage",
|
|
5
|
+
"description": "A named hub object accepts websocket clients via state.acceptWebSocket per Cloudflare's hibernatable WebSockets shape (https://developers.cloudflare.com/durable-objects/), routes each message to per-message handlers by JSON type field, and broadcasts to all connected sockets. On hibernate-and-wake the wake handler runs from a cold start and reads the same storage; the shipped hub class re-emits doWakeUp on the injected event sink on the first message after hibernation.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-006",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Lifecycle events fire at namespace and object level with metadata-only payloads",
|
|
5
|
+
"description": "The facade and the objects emit lifecycle events on the injected event sink: namespaceReady (facade), doAccept, doAlarmFired, doWakeUp, doHibernate (object). Every payload is metadata-only ({event, key, size, ttl, timestamp, ?objectName, ?scheduledTime}); no message payloads, no request bodies, no PII cross the sink boundary. A logging companion renders records directly without a per-blueprint scrub pass.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-007",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The sole-reader guarantee is enforced by an AST scan: no non-facade module imports env.CELL or env.HUB",
|
|
5
|
+
"description": "The shipped sole-reader-scan probe parses every .ts/.js/.mjs file under the fixture's applied source root, matches \"env.CELL\" and \"env.HUB\" identifier accesses against the facade module boundary, and reports every non-facade site as a leak. A project that carries a legacy call site converts it to a facade call or the probe returns aggregateVerdict: fail.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-durable-objects-REQ-008",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Migration-safe class exports: the DO class name is a stable string committed to wrangler config with a matching migrations table",
|
|
5
|
+
"description": "The DO class names (SingleCellObject, HubObject) are stable strings committed on the [[durable_objects.bindings]] blocks in wrangler.toml, and a paired [[migrations]] block records the class names under the mint tag (v1) per Cloudflare's migration documentation (https://developers.cloudflare.com/durable-objects/). A rename lands as a subsequent migration tag on the same list; a rename without a migration is a runtime error the shipped anatomy test catches at self-review.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.3). Ships as v1.0.0 of platform-cloudflare-durable-objects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-durable-objects"
|
|
12
|
+
],
|
|
13
|
+
"version": "1.0.0",
|
|
14
|
+
"status": "approved",
|
|
15
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
16
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3401-platform-cloudflare-durable-objects-namespace-facade",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-durable-objects namespace facade",
|
|
8
|
+
"purpose": "The single project-side module realising the DO namespace facade shape. It is the sole reader of env.CELL and env.HUB, wires the injected event sink at boot, emits namespaceReady on the first successful ready-check and exports typed handles (cellHandle(name), hubHandle(name)) plus an in-process variant (createDoFacadeInProcess) for probe drives. Consumers never touch env.CELL or env.HUB outside this module; the facade is the one place the vendor surface lives so a future DO adapter (a different platform, an in-process fake) slots in without a consumer re-shape.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Export createDoFacade({env, eventSink, clock}) returning {ready, cellHandle, hubHandle} matching the Cloudflare Workers DO namespace-binding shape (AC-33101-1, AC-33107-1).",
|
|
11
|
+
"Own the ONLY references to env.CELL and env.HUB in the applied source tree (AC-33107-1).",
|
|
12
|
+
"Emit namespaceReady on the injected sink at ready-check with a metadata-only payload (AC-33101-1).",
|
|
13
|
+
"Export createDoFacadeInProcess({singleCell, hub, eventSink, clock}) that returns typed handles wired to already-constructed in-process instances so the probes exercise the shipped facade code path without a wrangler dev process."
|
|
14
|
+
],
|
|
15
|
+
"internalStructure": "Two named factories in one module: createDoFacade wraps the Cloudflare env bindings; createDoFacadeInProcess wraps in-process class instances. Both share the same ready() lifecycle-event contract.",
|
|
16
|
+
"interfaces": [
|
|
17
|
+
{
|
|
18
|
+
"name": "createDoFacade",
|
|
19
|
+
"kind": "factory",
|
|
20
|
+
"summary": "DO namespace facade factory over env.CELL and env.HUB."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "createDoFacadeInProcess",
|
|
24
|
+
"kind": "factory",
|
|
25
|
+
"summary": "In-process DO facade factory over already-constructed class instances (probe variant)."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"dependencies": [],
|
|
29
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
30
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
31
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3402-platform-cloudflare-durable-objects-single-cell-shape",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-durable-objects single-cell shape",
|
|
8
|
+
"purpose": "The named-object class realising the single-cell authoritative-state shape per Cloudflare's Durable Objects consistency model. Concurrent invocations against the same instance serialise via a per-instance promise queue (matching the DO runtime contract). The class exposes typed domain verbs (increment, read, reset) that wrap the injected storage driver.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Serialise concurrent invocations against the same instance in FIFO order (AC-33102-1, AC-33109-1).",
|
|
11
|
+
"Round-trip storage on both SQL and KV backends via the injected driver factory (AC-33103-1, AC-33111-1).",
|
|
12
|
+
"Own storage.setAlarm and the alarm() handler with a metadata-only doAlarmFired event on the sink (AC-33104-1)."
|
|
13
|
+
],
|
|
14
|
+
"internalStructure": "One class SingleCellObject with constructor({storage, eventSink, name, clock}), a private serialised queue, and methods increment/read/reset/setAlarm/alarm.",
|
|
15
|
+
"interfaces": [
|
|
16
|
+
{
|
|
17
|
+
"name": "SingleCellObject",
|
|
18
|
+
"kind": "class",
|
|
19
|
+
"summary": "Single-cell DO class realising strongly consistent authoritative-state shape."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "createSingleCell",
|
|
23
|
+
"kind": "factory",
|
|
24
|
+
"summary": "Test-friendly factory that returns a new SingleCellObject."
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"dependencies": [],
|
|
28
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
29
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3403-platform-cloudflare-durable-objects-alarm-handler",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-durable-objects alarm handler",
|
|
8
|
+
"purpose": "The alarm surface on the single-cell class realising storage.setAlarm and alarm(). Cloudflare's runtime guarantees exactly-once alarm delivery per scheduled time; the shipped alarm() handler drains the persisted alarm from storage and emits doAlarmFired on the sink with metadata-only {objectName, scheduledTime}.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Persist and drain the scheduled alarm via storage.setAlarm/getAlarm/deleteAlarm (AC-33104-1).",
|
|
11
|
+
"Emit doAlarmFired with {objectName, scheduledTime} on the sink at every fire (AC-33104-1, AC-33106-1)."
|
|
12
|
+
],
|
|
13
|
+
"internalStructure": "A pair of instance methods (setAlarm(offsetMs), alarm()) on the SingleCellObject class. The alarm handler is idempotent per scheduled time via storage-drain semantics.",
|
|
14
|
+
"interfaces": [
|
|
15
|
+
{
|
|
16
|
+
"name": "SingleCellObject.setAlarm",
|
|
17
|
+
"kind": "method",
|
|
18
|
+
"summary": "Schedule an alarm for now+offsetMs; persists via storage.setAlarm."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "SingleCellObject.alarm",
|
|
22
|
+
"kind": "method",
|
|
23
|
+
"summary": "Alarm handler; drains the persisted alarm and emits doAlarmFired."
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"dependencies": [],
|
|
27
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
28
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3404-platform-cloudflare-durable-objects-websocket-hub",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-durable-objects websocket hub",
|
|
8
|
+
"purpose": "The hub-shape class realising Cloudflare's hibernatable WebSockets shape. A HubObject accepts websocket clients via state.acceptWebSocket, routes each incoming message by JSON type field (broadcast, set-state, get-state) and fans out broadcasts to all connected sockets. On hibernate-and-wake, the wake handler runs from cold and reads the same storage; doWakeUp is idempotent-by-contract per ADR-3405.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Accept websocket clients via state.acceptWebSocket and emit doAccept on the sink (AC-33105-1).",
|
|
11
|
+
"Route each webSocketMessage by JSON type field to broadcast, set-state, get-state handlers (AC-33105-1).",
|
|
12
|
+
"Persist lastBroadcast to storage on every broadcast so hibernate-and-wake preserves it (AC-33110-1).",
|
|
13
|
+
"Emit doHibernate on hibernate; emit doWakeUp exactly once on the first wake (AC-33110-1, AC-33106-1)."
|
|
14
|
+
],
|
|
15
|
+
"internalStructure": "One class HubObject with constructor({state, storage, eventSink, name, hibernateAfterIdleMs, clock}), a websocket dispatch method (webSocketMessage), a close handler (webSocketClose), and idempotent hibernate/wake methods.",
|
|
16
|
+
"interfaces": [
|
|
17
|
+
{
|
|
18
|
+
"name": "HubObject",
|
|
19
|
+
"kind": "class",
|
|
20
|
+
"summary": "Hub DO class realising hibernatable WebSocket coordination shape."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "createHub",
|
|
24
|
+
"kind": "factory",
|
|
25
|
+
"summary": "Test-friendly factory that returns a new HubObject."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"dependencies": [],
|
|
29
|
+
"createdAt": "2026-09-07T14:00:00.000Z",
|
|
30
|
+
"updatedAt": "2026-09-07T14:00:00.000Z"
|
|
31
|
+
}
|